{"version":3,"file":"static/js/7f16a1dded6bdc6ebacb.bundle.js","mappings":"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","sources":["webpack://bju-press/./src/modules/pdp-kit-contents/pdp-kit-contents.tsx?6efe","webpack://bju-press/./src/utilities/class-name-helper.ts?dd10","webpack://bju-press/./src/utilities/data-attribute-parser.ts?7345","webpack://bju-press/./src/utilities/global-constants.ts?5882","webpack://bju-press/./lib/pdp-kit-contents/module-registration.js?147f","webpack://bju-press/external var \"React\"?0d3b","webpack://bju-press/external var \"ReactDOM\"?853b"],"sourcesContent":["//==============================================================================\r\n// PDP Kit Contents\r\n//\r\n// Displays a list of items included in a kit.\r\n//==============================================================================\r\nimport * as React from 'react';\r\nimport { observable } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport classnames from 'classnames';\r\n\r\nimport { getCatalogId } from '@msdyn365-commerce/core';\r\n\r\nimport { clsHelper } from '../../utilities/class-name-helper';\r\nimport { attrNames } from '../../utilities/global-constants';\r\nimport { convertProductAttributes, AttributesWithMetadata } from '../../utilities/data-attribute-parser';\r\n\r\nimport { ProductSearchResult, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\nimport { searchByCriteriaAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\n\r\nimport { IPdpKitContentsData } from './pdp-kit-contents.data';\r\nimport { IPdpKitContentsProps } from './pdp-kit-contents.props.autogenerated';\r\n\r\n//==============================================================================\r\n// INTERFACES\r\n//==============================================================================\r\nexport interface ContentsMap {\r\n kit: string;\r\n itemId: string;\r\n items: ItemMap[];\r\n}\r\n\r\nexport interface ItemMap {\r\n itemId: string;\r\n productName?: string;\r\n productPath?: string;\r\n}\r\n\r\n//==============================================================================\r\n// CLASS NAME UTILITY\r\n//==============================================================================\r\nconst BASE_CLASS = 'pdp-kit-contents';\r\nconst cls = (fragment?: string) => clsHelper(BASE_CLASS, fragment);\r\n\r\n//==============================================================================\r\n// CLASS DEFINITION\r\n//==============================================================================\r\n/**\r\n * PdpKitContents component\r\n * @extends {React.Component>}\r\n */\r\n//==============================================================================\r\n@observer\r\nclass PdpKitContents extends React.Component> {\r\n //==========================================================================\r\n // VARIABLES\r\n //==========================================================================\r\n @observable private productList: ContentsMap[] = [];\r\n\r\n //==========================================================================\r\n // PUBLIC METHODS\r\n //==========================================================================\r\n //------------------------------------------------------\r\n // Invoked immediately after component is mounted\r\n //------------------------------------------------------\r\n public componentDidMount(): void {\r\n this._getProductList(attrNames.kitContents);\r\n }\r\n\r\n //------------------------------------------------------\r\n // Render function\r\n //------------------------------------------------------\r\n public render(): JSX.Element | null {\r\n const { config } = this.props;\r\n\r\n // If product list cannot be obtained, do not render module\r\n if (!this.productList) {\r\n return null;\r\n }\r\n\r\n return (\r\n
\r\n {this.productList.map((kit, index) => {\r\n return (\r\n
\r\n\r\n {/* Kit name */}\r\n
\r\n {kit.kit}\r\n
\r\n\r\n {/* Kit contents table */}\r\n
\r\n {/* Table header row */}\r\n
\r\n {/* Item ID */}\r\n
\r\n {config.labelItemId}\r\n
\r\n {/* Product name */}\r\n
\r\n {config.labelItemName}\r\n
\r\n
\r\n\r\n {/* Table rows */}\r\n {kit.items?.map((item, itemIndex) => {\r\n return (\r\n
\r\n {/* Item ID */}\r\n
\r\n {item.itemId}\r\n
\r\n {/* Product name */}\r\n \r\n
\r\n );\r\n })}\r\n
\r\n
\r\n );\r\n })}\r\n
\r\n );\r\n }\r\n\r\n //==========================================================================\r\n // PRIVATE METHODS\r\n //==========================================================================\r\n //------------------------------------------------------\r\n // Parse kit contents data into a friendlier format\r\n //\r\n // Ex input data: 'American Republic DVD with Books\r\n // (4th ed.)|450635:515841,298380,\r\n // 298364,434506,433656,418327|English 8\r\n // DVD with Books|523092:523093,…'\r\n //------------------------------------------------------\r\n private readonly _parseContentsData = (contentsData: string): ContentsMap[] => {\r\n const splitData = contentsData.split('|');\r\n const parsedData = [];\r\n\r\n for (let i = 0; i < splitData.length; i+=2) {\r\n const separatedItemData = splitData[i+1].split(':');\r\n\r\n parsedData.push({\r\n kit: splitData[i],\r\n itemId: separatedItemData[0],\r\n items: this._parseItemsData(separatedItemData[separatedItemData.length - 1]) || []\r\n });\r\n }\r\n\r\n return parsedData;\r\n };\r\n\r\n //------------------------------------------------------\r\n // Parse kit items data into a friendlier format\r\n //\r\n // Ex input data: '515841,298380,298364'\r\n //------------------------------------------------------\r\n private readonly _parseItemsData = (itemsData: string): ItemMap[] => {\r\n return itemsData.split(',').map(property => {\r\n return {\r\n itemId: property\r\n };\r\n });\r\n };\r\n\r\n //------------------------------------------------------\r\n // Get converted product attributes\r\n //------------------------------------------------------\r\n private readonly _getConvertedAttributes = (): AttributesWithMetadata | undefined => {\r\n const { data } = this.props;\r\n const productAttributes = data.productSpecificationData?.result;\r\n return productAttributes && convertProductAttributes(productAttributes);\r\n };\r\n\r\n //------------------------------------------------------\r\n // Get product list with parsed properties\r\n //------------------------------------------------------\r\n private readonly _getProductList = async (attribute: string): Promise => {\r\n const convertedAttributes = this._getConvertedAttributes();\r\n const kitAttribute = convertedAttributes && convertedAttributes[attribute] as string;\r\n const parsedAttributes = kitAttribute && this._parseContentsData(kitAttribute);\r\n\r\n const kitPromises = parsedAttributes && parsedAttributes.map(async kit => {\r\n const productItemIds = kit.items.map(item => item.itemId);\r\n const productList = productItemIds && await this._getProducts(productItemIds);\r\n\r\n const productResult = productList && productList.map((item: ProductSearchResult) => {\r\n const itemId = item.ItemId!;\r\n const productName = item.Name;\r\n const productPath = this._getProductPath(item);\r\n return {itemId, productName, productPath};\r\n });\r\n\r\n return {...kit, items: productResult};\r\n });\r\n\r\n // Wait for all requests to complete\r\n const kitResult = kitPromises && await Promise.all(kitPromises);\r\n\r\n this.productList = kitResult || [];\r\n };\r\n\r\n //------------------------------------------------------\r\n // Get products from item IDs\r\n //------------------------------------------------------\r\n private readonly _getProducts = async (itemIds: string[]): Promise => {\r\n const { context } = this.props;\r\n\r\n const itemList = itemIds?.map(itemId => ({ ItemId: itemId }));\r\n\r\n // Build a ProductSearchCriteria object\r\n const criteria: ProductSearchCriteria = {\r\n ItemIds: itemList,\r\n Context: {\r\n ChannelId: context.request.apiSettings.channelId,\r\n CatalogId: getCatalogId(context.request)\r\n }\r\n };\r\n\r\n try {\r\n // Fetch search results\r\n const searchResults = await searchByCriteriaAsync({ callerContext: context.actionContext }, criteria);\r\n return searchResults;\r\n } catch (error) {\r\n if (context.telemetry) {\r\n context.telemetry.exception(error as Error);\r\n context.telemetry.debug('Unable to find products');\r\n }\r\n }\r\n\r\n return [];\r\n };\r\n\r\n //------------------------------------------------------\r\n // Format product URL path from product rec ID\r\n //------------------------------------------------------\r\n private readonly _getProductPath = (product: ProductSearchResult): string | undefined => {\r\n return `/${String(product.RecordId)}.p`;\r\n };\r\n}\r\n\r\nexport default PdpKitContents;\r\n","//==============================================================================\r\n// Class Name Helper\r\n//\r\n// Tool to standardize CSS class naming in module components and elements\r\n//==============================================================================\r\n\r\nexport function clsHelper(baseClass: string, fragment?: string, separator: string = '__'): string | undefined {\r\n return fragment ? `${baseClass}${separator}${fragment}` : undefined;\r\n}\r\n","//==============================================================================\r\n// D365 OData Attribute Parser\r\n//\r\n// In creating this, it became clear that \"attributes\" is a general term.\r\n//\r\n// Product attributes are a first-class entity. They have their own dedicated\r\n// fields and schema.\r\n//\r\n// The more generic term \"attributes\" is used as a generic extension system.\r\n// Almost every entity (including Product Attributes) has an ExtensionProperties\r\n// field for jamming extra information into. In some cases, D365 handles these\r\n// natively, such as sales order line and header attributes, or customer\r\n// attributes. Attributes using ExtensionProperties use the\r\n// CommerceProperty and CommercePropertyValue types.\r\n//\r\n// A major note about ExtensionProperty-based attributes: they have fields\r\n// for many different data types, but there's no indicator as to which\r\n// of the fields is actually used. The consumer of the data is expected to\r\n// know the data type ahead of time. In the case of D365-native attribute users\r\n// such as customers and sales orders, only the string type appears to work.\r\n//\r\n// This module includes parsers for generic ExtensionProperties-based attributes\r\n// and Product Attributes. Though different Product Attribute retail server\r\n// calls use the same AttributeValue entity to transmit the data, they appear\r\n// to return different fields from that entity. Because of this, two different\r\n// parser calls are included here. They currently share the same implementation,\r\n// but by including different call signatures we have the ability to diverge\r\n// the implementations if the need arises.\r\n//\r\n// A note about Product Attributes: These contain both a friendly name,\r\n// displayed to users in back office, and an internal name. The internal name\r\n// can be the same as the friendly name, but by convention we've been pushing\r\n// for a PascalCase scheme. At present, the searchByCriteria call returns only\r\n// the unfriendly name, and the GetAttributeValues call returns only the\r\n// friendly name. We don't have a known method of correlating the two. That may\r\n// be an argument for keeping the friendly and unfriendly names identical.\r\n//==============================================================================\r\nimport {\r\n CommerceProperty, // Generic attributes stored in ExtensionProperties\r\n CommercePropertyValue, // Generic attributes stored in AttributeValue\r\n AttributeValue, AttributeDataType, // Product attributes or Product Search Result attributes\r\n CustomerAttribute, // Customer attributes\r\n IDictionary,\r\n} from '@msdyn365-commerce/retail-proxy';\r\n\r\n//==============================================================================\r\n// INTERFACES AND CONSTANTS\r\n//==============================================================================\r\nexport type CommerceValueTypes = string | number | boolean | Date;\r\n\r\n// This is me giving up on proper typing. If doing this in TypeScript is possible, I don't know how.\r\n// For the key \"meta\", the type should be a hash of strings.\r\n// For all other keys, the type is a CommerceValueType.\r\nexport type AttributesWithMetadata = {\r\n [key: string]: CommerceValueTypes | IDictionary\r\n};\r\n\r\n// Type to support both internal and friendly name for attributes\r\nexport type AttributesLocalized = {\r\n [key: string]: {\r\n friendlyName?: string,\r\n value?: CommerceValueTypes | IDictionary\r\n }\r\n};\r\n\r\n// Return type for getTypeInfo()\r\ntype TypeData = {\r\n source: keyof AttributeValue,\r\n type: string,\r\n\r\n customerSource?: keyof CommercePropertyValue,\r\n};\r\n\r\n//==============================================================================\r\n// FUNCTIONS\r\n//==============================================================================\r\n\r\n//----------------------------------------------------------\r\n// This version handles ExtensionProperties conversion.\r\n//\r\n// While these have a bunch of potential fields, the value\r\n// is always stored within StringValue.\r\n// There isn't a data type field, so if the content wasn't\r\n// in StringValue we wouldn't know where to find it.\r\n//----------------------------------------------------------\r\nexport function convertExtensionProperties(attributeList: CommerceProperty[]): IDictionary {\r\n const output = {};\r\n\r\n attributeList.forEach(entry => {\r\n if (entry.Key) {\r\n output[entry.Key] = entry.Value?.StringValue; // Ecommerce seems to always use strings.\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the Name is always the friendly\r\n// name.\r\n// KeyName and ExtensionProperties aren't defined.\r\n//\r\n// These results seem to be missing CurrencyValue,\r\n// FloatValue, DateTimeOffsetValue\r\n// I don't know if those data types aren't allowed here.\r\n//\r\n// Return value: Hash of key: property values with variable\r\n// types. There is also a \"meta\" key containing a hash of\r\n// all the attribute keys and their corresponding types.\r\n//\r\n// Example:\r\n// {\r\n// flavor: 'bland',\r\n// calories: 5300,\r\n// meta: {\r\n// flavor: 'string',\r\n// calories: 'number'\r\n// }\r\n// }\r\n//----------------------------------------------------------\r\nexport function convertProductAttributes(attributeList: AttributeValue[]): AttributesWithMetadata {\r\n const output = {\r\n meta: {}\r\n };\r\n\r\n attributeList.forEach(attribute => {\r\n // These should always be present, but TypeScript insists they can be undefined.\r\n if (attribute.Name && attribute.DataTypeValue) {\r\n const typeData = getTypeInfo(attribute.DataTypeValue);\r\n output[attribute.Name] = attribute[typeData.source]; // Ecommerce seems to require strings\r\n output.meta[attribute.Name] = typeData.type;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the Name is the friendly\r\n// name while KeyName is the internal name.\r\n//\r\n// This makes use of combined attributes containing both\r\n// internal and friendly name to support localization.\r\n//\r\n// Return value: Hash of internal name keys containing an object with both the\r\n// friendly name and attribute value There is also a \"meta\" key containing a\r\n// hash of all the attribute keys and their corresponding types.\r\n//\r\n// Example:\r\n// {\r\n// flavor: {\r\n// friendlyName: Flavor,\r\n// value: 'bland'\r\n// },\r\n// calories: {\r\n// friendlyName: Calories,\r\n// value: 5300\r\n// },\r\n// meta: {\r\n// flavor: 'string',\r\n// calories: 'number'\r\n// }\r\n// }\r\n//----------------------------------------------------------\r\nexport function convertProductAttributesLocalized(attributeList: AttributeValue[]): AttributesLocalized {\r\n const output = {\r\n meta: {}\r\n };\r\n\r\n attributeList.forEach(attribute => {\r\n if (attribute.KeyName && attribute.DataTypeValue) {\r\n const typeData = getTypeInfo(attribute.DataTypeValue);\r\n output[attribute.KeyName] = {\r\n friendlyName: attribute.Name,\r\n value: attribute[typeData.source]\r\n };\r\n output.meta[attribute.KeyName] = typeData.type;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the\r\n// Name/KeyName/ExtensionProperties is always the unfriendly\r\n// name.\r\n//\r\n// These results are only missing the Swatches field.\r\n//\r\n// Though the returned value is a bit different, at present\r\n// the implementation for convertProductAttributes works for\r\n// search results.\r\n// If they diverge in the future, extend this function.\r\n//----------------------------------------------------------\r\nexport function convertSearchAttributes(attributeList: AttributeValue[]): AttributesWithMetadata {\r\n return convertProductAttributes(attributeList);\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the Name is always the friendly\r\n// name. Value is always Text, and DataTypeValue is not\r\n// present here.\r\n//----------------------------------------------------------\r\nexport function convertCartAttributes(attributeList: AttributeValue[]): AttributesWithMetadata {\r\n const output = {};\r\n\r\n attributeList.forEach(attribute => {\r\n if (attribute.Name) {\r\n output[attribute.Name] = attribute.TextValue;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n//----------------------------------------------------------\r\nexport function convertCustomerAttributes(attributeList: CustomerAttribute[] | undefined): AttributesWithMetadata {\r\n const output = {\r\n meta: {}\r\n };\r\n\r\n attributeList?.forEach(attribute => {\r\n // These should always be present, but TypeScript insists they can be undefined.\r\n if (attribute.Name && attribute.DataTypeValue) {\r\n const typeData = getTypeInfo(attribute.DataTypeValue);\r\n output[attribute.Name] = attribute.AttributeValue && typeData.customerSource && attribute.AttributeValue[typeData.customerSource];\r\n output.meta[attribute.Name] = typeData.type;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// Finds the source field and type for an attribute\r\n//\r\n// This should probably be extended to better support\r\n// currency, which seems to be two fields glued together.\r\n//----------------------------------------------------------\r\nfunction getTypeInfo(type: AttributeDataType): TypeData {\r\n\r\n // Awkward, but this helps TypeScript enforce strict type checking\r\n type TypeMapType = {\r\n [key in AttributeDataType]: TypeData\r\n };\r\n\r\n const typeMap: TypeMapType = {\r\n [AttributeDataType.None]: {source: 'TextValue', type: 'string'}, // We need to choose something\r\n [AttributeDataType.Currency]: {source: 'CurrencyValue', type: 'number'}, // Should also include CurrencyCode, which is a string?\r\n [AttributeDataType.DateTime]: {source: 'DateTimeOffsetValue', type: 'Date'},\r\n [AttributeDataType.Decimal]: {source: 'FloatValue', type: 'number'},\r\n [AttributeDataType.Integer]: {source: 'IntegerValue', type: 'number', customerSource: 'IntegerValue'},\r\n [AttributeDataType.Text]: {source: 'TextValue', type: 'string', customerSource: 'StringValue'},\r\n [AttributeDataType.TrueFalse]: {source: 'BooleanValue', type: 'boolean', customerSource: 'BooleanValue'},\r\n [AttributeDataType.Video]: {source: 'TextValue', type: 'string'},\r\n [AttributeDataType.Image]: {source: 'TextValue', type: 'string'}\r\n };\r\n\r\n return typeMap[type];\r\n}\r\n","//==============================================================================\r\n// Global Constants\r\n//\r\n// Consolidated list of constants reused across different modules and extensions\r\n//==============================================================================\r\n\r\n//----------------------------------------------------------\r\n// Attribute names list\r\n//----------------------------------------------------------\r\nexport const attrNames = {\r\n productType: 'Item Type',\r\n lineAttributes: 'LineAttributes',\r\n blacklistedShippingAreas: 'Embargoed shipping locations',\r\n kitConfigurator: 'KitConfigurator',\r\n kitContents: 'eCommBurstoutKitContents',\r\n kitFormats: 'eCommBurstoutKitFormats',\r\n kitElectives: 'eCommBurstoutKitElectives',\r\n kitSubstitutions: 'eCommBurstoutKitSubstitutions',\r\n kitLineSubstitutions: 'eCommBurstoutKitLineDetails',\r\n kitLineParentAssociation: 'eCommBurstoutKitOrderLineParentAssociation',\r\n kitLineChildAssociation: 'eCommBurstoutKitOrderLineChildAssociation',\r\n instructors: 'eCommInstructors',\r\n consultantCartAttribute: 'eCommConsultantId',\r\n isInstallmentEligible: 'eCommItemIsPPEligible',\r\n cashForCollege: 'eCommCash4College',\r\n dropShip: 'eCommDropShip',\r\n scoringType: 'TestScoring',\r\n studentId: 'eCommPTEStudentId',\r\n schoolIdPP: 'eCommPPSchoolId',\r\n testCoordinator: 'PTETestCoordinator',\r\n testEnrollment: 'PTESchoolEnrollment',\r\n testType: 'Test Type',\r\n testFormat: 'Test Format',\r\n testDate: 'eCommPTETestDate',\r\n testDateId: 'eCommPTETestDateId',\r\n testAdmin: 'eCommPTEAdminCustAccount',\r\n testProctorEmail: 'PTEProctorEmail',\r\n testProctorName: 'PTEProctorName',\r\n testProctorPhone: 'PTEProctorPhone',\r\n testProctorTimeZone: 'PTEProctorTimeZone',\r\n userAgreement: 'eCommUserAgreement',\r\n umbrellaGroup: 'UmbrellaGroupID',\r\n gradeLvl: 'Grade level',\r\n isNotTest: 'Other',\r\n onlineTest: 'Online test',\r\n purchaseItemType: 'TestBklt',\r\n notBuyable: 'Not Buyable',\r\n billingCountry: 'eCommBillingCountryCode',\r\n billingZipCode: 'eCommBillingZipPostalCode',\r\n paymentScheduleName: 'PaymentScheduleName',\r\n isDBOrder: 'IsDBOrder',\r\n troveAdminFirstName: \"TroveAdminFirstName\",\r\n troveAdminLastName: \"TroveAdminLastName\",\r\n troveAdminEmail: \"TroveAdminEmail\",\r\n troveAdminTelephone: \"TroveAdminTelephone\",\r\n troveAnnualLicense: \"TroveAnnualLicense\",\r\n troveProduct: \"Trove\",\r\n troveParticipant: \"TroveParticipant\",\r\n poNumber: \"CSPONumber\"\r\n};\r\n\r\n//----------------------------------------------------------\r\n// Global label resources\r\n//----------------------------------------------------------\r\nexport const labelResources = {\r\n sku: 'SKU'\r\n};\r\n","const binding = { modules: {}, dataActions: {} };\n\n const registerActionId = (actionPath) => {\n if (binding.dataActions[actionPath] &&\n binding.dataActions[actionPath].default &&\n binding.dataActions[actionPath].default.prototype &&\n binding.dataActions[actionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[actionPath].default.prototype.id] = binding.dataActions[actionPath];\n } else {\n Object.keys(binding.dataActions[actionPath] || {}).forEach(exportName => {\n if (binding.dataActions[actionPath][exportName] &&\n binding.dataActions[actionPath][exportName].prototype &&\n binding.dataActions[actionPath][exportName].prototype.Action) {\n binding.dataActions[binding.dataActions[actionPath][exportName].prototype.id] = binding.dataActions[actionPath][exportName];\n }\n })\n }\n };\n\n const registerSanitizedActionPath = (sanitizedActionPath, dataAction) => {\n if (process.env.NODE_ENV === 'development') {\n if (!dataAction.default) {\n throw new Error('Data action path does not have a default export');\n }\n if (!(dataAction.default.prototype.id && binding.dataActions[dataAction.default.prototype.id]) || !binding.dataActions[sanitizedActionPath]) {\n binding.dataActions[sanitizedActionPath] = dataAction;\n }\n } else {\n binding.dataActions[sanitizedActionPath] = dataAction;\n if (!binding.dataActions[sanitizedActionPath].default) {\n throw new Error('Data action path ' + sanitizedActionPath + ' does not have a default export');\n }\n binding.dataActions[sanitizedActionPath].default.prototype.RegistrationId = sanitizedActionPath;\n if (binding.dataActions[sanitizedActionPath].default.prototype.id) {\n binding.dataActions[binding.dataActions[sanitizedActionPath].default.prototype.id] = sanitizedActionPath;\n }\n }\n };\n \n\n (binding.modules['pdp-kit-contents'] = {\n c: () => require('partner/modules/pdp-kit-contents/pdp-kit-contents.tsx'),\n $type: 'contentModule',\n da: [{name:'productSpecificationData', path:'@msdyn365-commerce-modules/retail-actions/dist/lib/get-attributes-for-selected-variant', runOn: 0}],\n \n iNM: false,\n ns: '__local__',\n n: 'pdp-kit-contents',\n p: '__local__',\n \n pdp: '',\n \n \n md: 'src/modules/pdp-kit-contents'\n });\n \n\n {\n const sanitizedActionPath = '@msdyn365-commerce-modules/retail-actions/dist/lib/get-attributes-for-selected-variant';\n let dataAction = require('@msdyn365-commerce-modules/retail-actions/dist/lib/get-attributes-for-selected-variant');\n registerSanitizedActionPath(sanitizedActionPath, dataAction);\n }\n \n\n \n window.__bindings__ = window.__bindings__ || {};\n window.__bindings__.modules = {\n ...window.__bindings__.modules || {},\n ...binding.modules\n };\n \n window.__bindings__.dataActions = {\n ...window.__bindings__.dataActions || {},\n ...binding.dataActions\n };","module.exports = React;","module.exports = ReactDOM;"],"names":["BASE_CLASS","cls","fragment","clsHelper","PdpKitContents","React","constructor","productList","_parseContentsData","contentsData","splitData","split","parsedData","i","length","separatedItemData","push","kit","itemId","items","this","_parseItemsData","itemsData","map","property","_getConvertedAttributes","_data$productSpecific","data","props","productAttributes","productSpecificationData","result","convertProductAttributes","_getProductList","async","convertedAttributes","kitAttribute","attribute","parsedAttributes","kitPromises","productItemIds","item","_getProducts","productResult","ItemId","productName","Name","productPath","_getProductPath","_objectSpread","kitResult","Promise","all","context","criteria","ItemIds","itemIds","Context","ChannelId","request","apiSettings","channelId","CatalogId","getCatalogId","searchByCriteriaAsync","callerContext","actionContext","error","telemetry","exception","debug","product","String","RecordId","componentDidMount","attrNames","kitContents","render","config","className","classnames","index","_kit$items","key","labelItemId","labelItemName","itemIndex","href","__decorate","observable","observer","baseClass","separator","arguments","undefined","attributeList","output","meta","forEach","DataTypeValue","typeData","getTypeInfo","source","type","convertCartAttributes","TextValue","convertCustomerAttributes","AttributeValue","customerSource","AttributeDataType","None","Currency","DateTime","Decimal","Integer","Text","TrueFalse","Video","Image","productType","lineAttributes","blacklistedShippingAreas","kitConfigurator","kitFormats","kitElectives","kitSubstitutions","kitLineSubstitutions","kitLineParentAssociation","kitLineChildAssociation","instructors","consultantCartAttribute","isInstallmentEligible","cashForCollege","dropShip","scoringType","studentId","schoolIdPP","testCoordinator","testEnrollment","testType","testFormat","testDate","testDateId","testAdmin","testProctorEmail","testProctorName","testProctorPhone","testProctorTimeZone","userAgreement","umbrellaGroup","gradeLvl","isNotTest","onlineTest","purchaseItemType","notBuyable","billingCountry","billingZipCode","paymentScheduleName","isDBOrder","troveAdminFirstName","troveAdminLastName","troveAdminEmail","troveAdminTelephone","troveAnnualLicense","troveProduct","troveParticipant","poNumber","labelResources","sku","binding","modules","dataActions","c","require","$type","da","name","path","runOn","iNM","ns","n","p","pdp","md","registerSanitizedActionPath","sanitizedActionPath","dataAction","default","Error","prototype","RegistrationId","id","window","__bindings__","module","exports","ReactDOM"],"sourceRoot":""}