diff --git a/src/api/catalog-search/__snapshots__/util.test.ts.snap b/src/api/catalog-search/__snapshots__/util.test.ts.snap index db85b098..50d67c6b 100644 --- a/src/api/catalog-search/__snapshots__/util.test.ts.snap +++ b/src/api/catalog-search/__snapshots__/util.test.ts.snap @@ -251,9 +251,6 @@ Array [ Object { "name": "cdk-time-bomb", }, - Object { - "name": "cdk-time-bomb", - }, Object { "name": "cdk-tweet-queue", }, @@ -266,9 +263,6 @@ Array [ Object { "name": "cdk8s-aws-alb-ingress-controller", }, - Object { - "name": "cdk8s-aws-alb-ingress-controller", - }, Object { "name": "cdk8s-op", }, @@ -639,10 +633,6 @@ Array [ "date": "Tue, 21 Jul 2020 14:12:38 GMT", "name": "cdk-time-bomb", }, - Object { - "date": "Thu, 14 May 2020 15:21:58 GMT", - "name": "cdk-time-bomb", - }, Object { "date": "Wed, 15 Sep 2021 00:19:48 GMT", "name": "cdk-tweet-queue", @@ -659,10 +649,6 @@ Array [ "date": "Mon, 23 Nov 2020 09:47:27 GMT", "name": "cdk8s-aws-alb-ingress-controller", }, - Object { - "date": "Mon, 23 Nov 2020 08:29:12 GMT", - "name": "cdk8s-aws-alb-ingress-controller", - }, Object { "date": "Wed, 18 Nov 2020 05:29:35 GMT", "name": "cdk8s-op", @@ -772,10 +758,6 @@ Array [ "date": "Fri, 17 Apr 2020 18:59:40 GMT", "name": "cdk-sqs-monitored", }, - Object { - "date": "Thu, 14 May 2020 15:21:58 GMT", - "name": "cdk-time-bomb", - }, Object { "date": "Thu, 04 Jun 2020 19:50:33 GMT", "name": "aws-lambda-golang", @@ -856,10 +838,6 @@ Array [ "date": "Wed, 18 Nov 2020 05:29:35 GMT", "name": "cdk8s-op", }, - Object { - "date": "Mon, 23 Nov 2020 08:29:12 GMT", - "name": "cdk8s-aws-alb-ingress-controller", - }, Object { "date": "Mon, 23 Nov 2020 09:47:27 GMT", "name": "cdk8s-aws-alb-ingress-controller", diff --git a/src/api/catalog-search/catalog-search.test.ts b/src/api/catalog-search/catalog-search.test.ts index 87fb11a7..5e3d2f07 100644 --- a/src/api/catalog-search/catalog-search.test.ts +++ b/src/api/catalog-search/catalog-search.test.ts @@ -1,12 +1,10 @@ import catalogFixture from "../../__fixtures__/catalog.json"; import statsFixture from "../../__fixtures__/stats.json"; -import { CDKType } from "../../constants/constructs"; import { Language } from "../../constants/languages"; import { CatalogPackage } from "../package/packages"; import { PackageStats } from "../stats"; import { CatalogSearchAPI } from "./catalog-search"; import { CatalogSearchSort } from "./constants"; -import * as util from "./util"; describe("CatalogSearchAPI", () => { const instance = new CatalogSearchAPI( @@ -27,13 +25,10 @@ describe("CatalogSearchAPI", () => { } it("exposes a property which returns detected cdk frameworks", () => { - const cdkFrameWorkCount = catalogFixture.packages.reduce((sum, i) => { - if (i.metadata.constructFramework?.name) { - return sum + 1; - } - - return sum; - }, 0); + const cdkFrameWorkCount = [...instance.search().values()].reduce( + (sum, { constructFrameworks }) => sum + constructFrameworks.size, + 0 + ); const detectedCount = Object.values(instance.constructFrameworks).reduce( (sum, i) => sum + i.pkgCount, @@ -103,27 +98,6 @@ describe("CatalogSearchAPI", () => { expect([...dynamodbResults.values()]).toEqual([extendedP1, extendedP2]); }); - it("Ignores cdkMajor filter if no cdkType is passed", () => { - const cdkMajorFilterSpy = jest.spyOn(util.FILTER_FUNCTIONS, "cdkMajor"); - - instance.search({ - filters: { - cdkType: CDKType.awscdk, - cdkMajor: 2, - }, - }); - - expect(cdkMajorFilterSpy).toHaveBeenCalledWith(2); - - instance.search({ - filters: { - cdkMajor: 3, - }, - }); - - expect(cdkMajorFilterSpy).toHaveBeenCalledWith(undefined); - }); - it("Returns results ordered by Sort", () => { const publishDateAsc = [ ...instance.search({ sort: CatalogSearchSort.PublishDateAsc }).values(), diff --git a/src/api/catalog-search/catalog-search.ts b/src/api/catalog-search/catalog-search.ts index afa95d8f..47beb876 100644 --- a/src/api/catalog-search/catalog-search.ts +++ b/src/api/catalog-search/catalog-search.ts @@ -4,7 +4,12 @@ import { Language } from "../../constants/languages"; import { CatalogPackage } from "../package/packages"; import { PackageStats } from "../stats"; import { CatalogSearchSort } from "./constants"; -import { FILTER_FUNCTIONS, renderAllKeywords, SORT_FUNCTIONS } from "./util"; +import { + FILTER_FUNCTIONS, + mapConstructFrameworks, + renderAllKeywords, + SORT_FUNCTIONS, +} from "./util"; const INDEX_FIELDS = { AUTHOR_EMAIL: { @@ -40,6 +45,7 @@ const INDEX_FIELDS = { export interface ExtendedCatalogPackage extends CatalogPackage { authorEmail?: string; authorName?: string; + constructFrameworks: Map; downloads: number; id: string; packageName?: string; @@ -139,6 +145,7 @@ export class CatalogSearchAPI { ...pkg, authorName, authorEmail, + constructFrameworks: mapConstructFrameworks(pkg.metadata), keywords, downloads, id, @@ -152,7 +159,7 @@ export class CatalogSearchAPI { this.map = this.sort(catalogMap, CatalogSearchSort.PublishDateDesc); - this.constructFrameworks = this.detectConstructFrameworks(); + this.constructFrameworks = this.detectAllConstructFrameworks(); this.keywords = this.detectKeywords(); this.index = lunr(function () { @@ -232,7 +239,10 @@ export class CatalogSearchAPI { /** * Performs a Search against the catalog and returns an array of all packages matching the query. */ - public findByName(query: string): ExtendedCatalogPackage[] { + public findByName( + query: string, + opts?: { dedup?: boolean } + ): ExtendedCatalogPackage[] { const results = [...this.map.values()].filter((pkg) => pkg.name === query); const matches = new Array(); for (const pkg of results.values()) { @@ -240,6 +250,17 @@ export class CatalogSearchAPI { matches.push(pkg); } } + + if (opts?.dedup) { + const map = new Map(); + + matches.forEach((pkg) => { + map.set(pkg.name, pkg); + }); + + return [...this.dedup(map).values()]; + } + return matches; } @@ -255,8 +276,7 @@ export class CatalogSearchAPI { const filterFunctions = [ FILTER_FUNCTIONS.cdkType(cdkType), - // Ignore major version filter if no CDK Type is defined - FILTER_FUNCTIONS.cdkMajor(cdkType ? cdkMajor : undefined), + FILTER_FUNCTIONS.cdkMajor({ cdkType, cdkMajor }), FILTER_FUNCTIONS.keywords(keywords), FILTER_FUNCTIONS.languages(languages), FILTER_FUNCTIONS.tags(tags), @@ -342,26 +362,25 @@ export class CatalogSearchAPI { * They are indexed by the name of the construct framework and record the count * of packages for that framework as well as a list of major versions. */ - private detectConstructFrameworks() { + private detectAllConstructFrameworks() { const results: CatalogConstructFrameworks = [...this.map.values()].reduce( (frameworks: CatalogConstructFrameworks, pkg: ExtendedCatalogPackage) => { - const { metadata } = pkg; + const { constructFrameworks } = pkg; - const frameworkName = metadata?.constructFramework?.name; - const majorVersion = metadata?.constructFramework?.majorVersion; + [...constructFrameworks.entries()]?.forEach(([name, majorVersion]) => { + if (majorVersion !== undefined) { + const entry = frameworks[name]; - if (frameworkName) { - const entry = frameworks[frameworkName]; + if ( + majorVersion !== null && + !entry.majorVersions.includes(majorVersion) + ) { + entry.majorVersions.push(majorVersion); + } - if ( - majorVersion !== undefined && - !entry.majorVersions.includes(majorVersion) - ) { - entry.majorVersions.push(majorVersion); + entry.pkgCount += 1; } - - entry.pkgCount += 1; - } + }); return frameworks; }, diff --git a/src/api/catalog-search/util.test.ts b/src/api/catalog-search/util.test.ts index b39aaf27..d3136c45 100644 --- a/src/api/catalog-search/util.test.ts +++ b/src/api/catalog-search/util.test.ts @@ -1,13 +1,26 @@ import catalogFixture from "../../__fixtures__/catalog.json"; import { CDKType } from "../../constants/constructs"; import { Language } from "../../constants/languages"; -import { ExtendedCatalogPackage } from "./catalog-search"; +import { CatalogPackage } from "../package/packages"; +import { CatalogSearchAPI } from "./catalog-search"; import { CatalogSearchSort } from "./constants"; -import { SORT_FUNCTIONS, FILTER_FUNCTIONS, renderAllKeywords } from "./util"; - -const packages = catalogFixture.packages as any as ExtendedCatalogPackage[]; +import { + SORT_FUNCTIONS, + FILTER_FUNCTIONS, + renderAllKeywords, + mapConstructFrameworks, +} from "./util"; describe("Catalog Search Utils", () => { + const packages = [ + ...new CatalogSearchAPI(catalogFixture.packages as CatalogPackage[], { + updated: "", + packages: {}, + }) + .search() + .values(), + ]; + describe("Sort Functions", () => { it("Sorts by Publish Date", () => { const resultsAscending = [...packages].sort( @@ -55,34 +68,17 @@ describe("Catalog Search Utils", () => { it("Filters by CDK Type", () => { const filterByCdk8s = FILTER_FUNCTIONS.cdkType(CDKType.cdk8s)!; expect(packages.filter(filterByCdk8s)).toEqual( - packages.filter((p) => p.metadata.constructFramework?.name === "cdk8s") + packages.filter((p) => p.constructFrameworks.get(CDKType.cdk8s)) ); }); it("Filters by CDK Version", () => { - const dataWithMoreVersions: ExtendedCatalogPackage[] = packages.map( - (p) => ({ - ...p, - metadata: { - ...p.metadata, - ...(p.metadata.constructFramework - ? { - constructFramework: { - ...p.metadata.constructFramework, - majorVersion: Math.round(Math.random()) + 1, - }, - } - : {}), - }, - }) - ); - expect( - dataWithMoreVersions.filter(FILTER_FUNCTIONS.cdkMajor(1)!) - ).toEqual( - dataWithMoreVersions.filter( - (p) => p.metadata.constructFramework?.majorVersion === 1 + packages.filter( + FILTER_FUNCTIONS.cdkMajor({ cdkType: CDKType.awscdk, cdkMajor: 1 })! ) + ).toEqual( + packages.filter((p) => p.constructFrameworks.get(CDKType.awscdk) === 1) ); }); @@ -129,59 +125,119 @@ describe("Catalog Search Utils", () => { .map((r) => r.name); expect(query("databases")).toStrictEqual([ - "aws-cdk-image-resize", "@aws-cdk/aws-lambda-nodejs", + "aws-cdk-image-resize", ]); expect(query("partners")).toStrictEqual(["aws-cdk-image-resize"]); expect(query("databases", "partners")).toStrictEqual([ - "aws-cdk-image-resize", "@aws-cdk/aws-lambda-nodejs", + "aws-cdk-image-resize", ]); // only search in tags that are associated with keywords and not highlights. expect(query("non-keyword")).toStrictEqual([]); }); }); -}); -describe("renderAllKeywords", () => { - it("returns a normalized set (all lowercase)", () => { - expect( - renderAllKeywords({ - ...packages[0], - keywords: ["Foo", "foo", "FoO", "bar", "eh"], - }) - ).toStrictEqual(["foo", "bar", "eh"]); - }); + describe("renderAllKeywords", () => { + it("returns a normalized set (all lowercase)", () => { + expect( + renderAllKeywords({ + ...packages[0], + keywords: ["Foo", "foo", "FoO", "bar", "eh"], + }) + ).toStrictEqual(["foo", "bar", "eh"]); + }); - it("includes both publisher keywords and tag keywords", () => { - expect( - renderAllKeywords({ - ...packages[0], - keywords: ["Foo", "foo", "FoO", "bar", "eh"], - metadata: { - date: "DATE", - packageTags: [ - { id: "id1", keyword: { label: "boom" } }, - { id: "id2", keyword: { label: "bar" } }, - { id: "id3", highlight: { label: "baz" } }, - ], - }, - }) - ).toStrictEqual(["foo", "bar", "eh", "boom"]); + it("includes both publisher keywords and tag keywords", () => { + expect( + renderAllKeywords({ + ...packages[0], + keywords: ["Foo", "foo", "FoO", "bar", "eh"], + metadata: { + date: "DATE", + packageTags: [ + { id: "id1", keyword: { label: "boom" } }, + { id: "id2", keyword: { label: "bar" } }, + { id: "id3", highlight: { label: "baz" } }, + ], + }, + }) + ).toStrictEqual(["foo", "bar", "eh", "boom"]); + }); + + it("filters out certain keywords", () => { + expect( + renderAllKeywords({ + ...packages[0], + keywords: ["cdk-construct", "foo"], + metadata: { + date: "DATE", + packageTags: [{ id: "id1", keyword: { label: "construct" } }], + }, + }) + ).toStrictEqual(["foo"]); + }); }); - it("filters out certain keywords", () => { - expect( - renderAllKeywords({ - ...packages[0], - keywords: ["cdk-construct", "foo"], - metadata: { - date: "DATE", - packageTags: [{ id: "id1", keyword: { label: "construct" } }], - }, - }) - ).toStrictEqual(["foo"]); + describe("mapConstructFrameworks", () => { + const { + constructFrameworks: _constructFrameworks, + constructFramework: _constructFramework, + ...baseMetadata + } = packages[0].metadata; + + const constructFrameworks = [ + { name: CDKType.awscdk, majorVersion: 1 }, + { name: CDKType.cdk8s }, + ]; + + const constructFramework = { name: CDKType.cdktf, majorVersion: 2 }; + + it("maps metadata.constructFrameworks to a Map", () => { + const metadata = { + ...baseMetadata, + constructFrameworks, + }; + + const result = mapConstructFrameworks(metadata); + + // Metadata defines AWS CDK with majorVersion 1 + expect(result.get(CDKType.awscdk)).toEqual(1); + + // Metadata defines cdk8s with no majorVersion + expect(result.get(CDKType.cdk8s)).toEqual(null); // Returns null because there is no majorVersion + + // Metadata does not define cdktf + expect(result.get(CDKType.cdktf)).toEqual(undefined); + }); + + // It should never have both properties + it("ignores deprecated constructFramework property if constructFrameworks is defined", () => { + const metadata = { + ...baseMetadata, + constructFramework, + constructFrameworks, + }; + + const result = mapConstructFrameworks(metadata); + + // Metadata defines AWS CDK with majorVersion 1 + expect(result.get(CDKType.awscdk)).toEqual(1); + + // Metadata defines cdk8s with no majorVersion + expect(result.get(CDKType.cdk8s)).toEqual(null); // Returns null because there is no majorVersion + + // constructFramework prop defines cdktf majorVersion 2, but should be ignored + expect(result.get(CDKType.cdktf)).toEqual(undefined); + }); + + it("supports deprecated constructFramework property", () => { + const metadata = { ...baseMetadata, constructFramework }; + const result = mapConstructFrameworks(metadata); + + expect(result.get(CDKType.cdktf)).toEqual(2); + }); }); }); diff --git a/src/api/catalog-search/util.ts b/src/api/catalog-search/util.ts index 1304a42c..d67acfb2 100644 --- a/src/api/catalog-search/util.ts +++ b/src/api/catalog-search/util.ts @@ -1,6 +1,8 @@ import { CatalogSearchFilters, ExtendedCatalogPackage } from "."; +import { CDKType } from "../../constants/constructs"; import { KEYWORD_IGNORE_LIST } from "../../constants/keywords"; import { Language } from "../../constants/languages"; +import { ConstructFramework, Metadata } from "../package/metadata"; import { CatalogPackage } from "../package/packages"; import { CatalogSearchSort } from "./constants"; @@ -68,14 +70,15 @@ const getCDKTypeFilter: FilterFunctionBuilder< CatalogSearchFilters["cdkType"] > = (cdkType) => { if (!cdkType) return undefined; - return (pkg) => pkg.metadata?.constructFramework?.name === cdkType; + return (pkg) => pkg.constructFrameworks.get(cdkType) !== undefined; }; -const getCDKMajorFilter: FilterFunctionBuilder< - CatalogSearchFilters["cdkMajor"] -> = (cdkMajor) => { - if (typeof cdkMajor !== "number") return undefined; - return (pkg) => pkg.metadata?.constructFramework?.majorVersion === cdkMajor; +const getCDKMajorFilter: FilterFunctionBuilder<{ + cdkType: CatalogSearchFilters["cdkType"]; + cdkMajor: CatalogSearchFilters["cdkMajor"]; +}> = ({ cdkType, cdkMajor }) => { + if (!cdkType || typeof cdkMajor !== "number") return undefined; + return (pkg) => pkg.constructFrameworks.get(cdkType) === cdkMajor; }; const getKeywordsFilter: FilterFunctionBuilder< @@ -132,11 +135,7 @@ export const SORT_FUNCTIONS: Record = { [CatalogSearchSort.DownloadsDesc]: getDownloadsSort(false), }; -export const FILTER_FUNCTIONS: { - [key in keyof Required]: FilterFunctionBuilder< - CatalogSearchFilters[key] - >; -} = { +export const FILTER_FUNCTIONS = { cdkType: getCDKTypeFilter, cdkMajor: getCDKMajorFilter, keywords: getKeywordsFilter, @@ -172,3 +171,31 @@ export const renderAllKeywords = (pkg: CatalogPackage) => { return Array.from(allKeywords); }; + +/** + * Creates a map of construct frameworks found in a construct's metadata + * If the metadata doesn't specify a majorVersion, the map will return null to distinguish + * from an undefined map.get() + */ +export const mapConstructFrameworks = ({ + constructFramework, + constructFrameworks, +}: Metadata): Map => { + const map = new Map(); + let frameworks = constructFrameworks ?? []; + + // To support the deprecated constructFramework property, re-map it to the new format + if (!frameworks.length && constructFramework?.name) { + frameworks = [constructFramework as ConstructFramework]; + } + + frameworks.forEach((framework) => { + const { name, majorVersion } = framework; + + if (name) { + map.set(name, majorVersion ?? null); + } + }); + + return map; +}; diff --git a/src/api/package/metadata.ts b/src/api/package/metadata.ts index bda692ce..15fee2fa 100644 --- a/src/api/package/metadata.ts +++ b/src/api/package/metadata.ts @@ -3,11 +3,24 @@ import { API_PATHS } from "../../constants/url"; import { PackageTagConfig } from "../config"; import { getAssetsPath } from "./util"; +export interface ConstructFramework { + name: CDKType; + majorVersion?: number; +} + export interface Metadata { - constructFramework?: { - name?: CDKType; - majorVersion?: number; - }; + /** + * Describes the associated Construct framework for a library. + * Back-end will introduce a new metadata.constructFrameworks property to replace metadata.constructFramework + * @deprecated Use constructFrameworks instead + */ + constructFramework?: Partial; + /** + * Describes the associated Construct frameworks for a library. + * Typically, libraries will be associated with a single framework, though some have no + * association or multiple associations. + */ + constructFrameworks?: ConstructFramework[]; date: string; links?: { npm: string; diff --git a/src/components/CDKType/CDKType.tsx b/src/components/CDKType/CDKType.tsx index 110475b1..31633284 100644 --- a/src/components/CDKType/CDKType.tsx +++ b/src/components/CDKType/CDKType.tsx @@ -2,58 +2,44 @@ import { Badge, BadgeProps, forwardRef, - Image, - ImageProps, Text, TextProps, + Tooltip, } from "@chakra-ui/react"; import { CDKType, CDKTYPE_RENDER_MAP } from "../../constants/constructs"; import { getSearchPath } from "../../util/url"; import { NavLink } from "../NavLink"; -interface CDKTypeIconProps extends ImageProps { +interface CDKTypeTextProps extends TextProps { name?: CDKType; majorVersion?: number; } -export const CDKTypeIcon = forwardRef( - ({ name, majorVersion, ...props }, ref) => { - if (!name) return null; - - return ( - {`${CDKTYPE_RENDER_MAP[name].name} - ); - } -); - -interface CDKTypeTextProps extends TextProps { - name?: CDKType; +const getText = ({ + name, + majorVersion, +}: { + name: CDKType; majorVersion?: number; -} +}) => + `${CDKTYPE_RENDER_MAP[name].name}${ + majorVersion !== undefined ? ` v${majorVersion}` : "" + }`; -export const CDKTypeText = forwardRef( +const CDKTypeText = forwardRef( ({ name, majorVersion, ...props }, ref) => { if (!name) return null; return ( - {CDKTYPE_RENDER_MAP[name].name} - {majorVersion !== undefined ? ` v${majorVersion}` : ""} + {getText({ name, majorVersion })} ); } ); -interface CDKTypeBadgeProps extends BadgeProps { - name?: CDKType; - majorVersion?: number; +export interface CDKTypeBadgeProps extends BadgeProps { + constructFrameworks?: Map; } const badgeColorMap = { @@ -62,29 +48,57 @@ const badgeColorMap = { [CDKType.cdktf]: "#5C4EE5", }; +const sharedProps = { + alignItems: "center", + borderRadius: "md", + display: "flex", + h: "1.5rem", + maxW: "5.5rem", + px: 1.5, + textTransform: "none" as const, +}; + export const CDKTypeBadge = forwardRef( - ({ name, majorVersion, ...badgeProps }, ref) => { - if (!name) return null; + ({ constructFrameworks, ...badgeProps }, ref) => { + if (!constructFrameworks?.size) return null; + + // If "multi-cdk" library, show a Multi-CDK badge with tooltip which lists supported libraries + if (constructFrameworks.size > 1) { + const frameworks = [...constructFrameworks.entries()]; + return ( + + getText({ name, majorVersion: majorVersion ?? undefined }) + ) + .join(", ")}`} + placement="left-start" + > + + Multi-CDK + + + ); + } + const [[name, majorVersion]] = constructFrameworks; const bg = badgeColorMap[name]; return ( - + ); } diff --git a/src/components/PackageCard/Heading.tsx b/src/components/PackageCard/Heading.tsx index e9a1261c..47a87cd1 100644 --- a/src/components/PackageCard/Heading.tsx +++ b/src/components/PackageCard/Heading.tsx @@ -20,14 +20,11 @@ export const Heading: FunctionComponent = () => { dataEvent, description, comment, - metadata: { constructFramework }, + constructFrameworks, name, version, } = usePackageCard(); - const cdkType = constructFramework?.name; - const cdkVersion = constructFramework?.majorVersion; - return ( <> { })} > - + { @@ -25,7 +25,6 @@ export const PackageList: FunctionComponent = memo( cardView = PackageCardType.Wide, items, loading, - // title, }) => { if (loading || !items) { return ( diff --git a/src/components/SearchBar/SearchSuggestions.tsx b/src/components/SearchBar/SearchSuggestions.tsx index f01f641b..f303bb44 100644 --- a/src/components/SearchBar/SearchSuggestions.tsx +++ b/src/components/SearchBar/SearchSuggestions.tsx @@ -67,7 +67,7 @@ export const SearchSuggestions: FunctionComponent = forwardRef< > {recommendations.map((pkg: ExtendedCatalogPackage, i) => { const navigate = () => push(getPackagePath(pkg)); - const constructFramework = pkg.metadata?.constructFramework ?? {}; + const { constructFrameworks } = pkg; return ( <> @@ -83,7 +83,10 @@ export const SearchSuggestions: FunctionComponent = forwardRef< name={ - + {pkg.name} diff --git a/src/lib/shortbread/source.js b/src/lib/shortbread/source.js index 27c62849..240017f5 100644 --- a/src/lib/shortbread/source.js +++ b/src/lib/shortbread/source.js @@ -1,3 +1,2 @@ /*! Version: 1.0.14 */ !function(e,a){if("object"==typeof exports&&"object"==typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var c=a();for(var t in c)("object"==typeof exports?exports:e)[t]=c[t]}}(window,(function(){return function(e){var a={};function c(t){if(a[t])return a[t].exports;var n=a[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,c),n.l=!0,n.exports}return c.m=e,c.c=a,c.d=function(e,a,t){c.o(e,a)||Object.defineProperty(e,a,{enumerable:!0,get:t})},c.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.t=function(e,a){if(1&a&&(e=c(e)),8&a)return e;if(4&a&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(c.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&a&&"string"!=typeof e)for(var n in e)c.d(t,n,function(a){return e[a]}.bind(null,n));return t},c.n=function(e){var a=e&&e.__esModule?function(){return e.default}:function(){return e};return c.d(a,"a",a),a},c.o=function(e,a){return Object.prototype.hasOwnProperty.call(e,a)},c.p="",c(c.s=13)}([function(e,a,c){"use strict";var t=this&&this.__assign||function(){return(t=Object.assign||function(e){for(var a,c=1,t=arguments.length;c0&&r.forEach((function(a){if("string"==typeof a)l.appendChild(t.createTextNode(a));else if("number"==typeof a)l.appendChild(t.createTextNode(r.toString()));else{if(null===a)throw Error("Unsupported child type "+a);e(l,a,t,!0)}})),o?a.appendChild(l):a.insertBefore(l,a.firstChild)}},function(e,a,c){"use strict";var t,n=function(){return void 0===t&&(t=Boolean(window&&document&&document.all&&!window.atob)),t},o=function(){var e={};return function(a){if(void 0===e[a]){var c=document.querySelector(a);if(window.HTMLIFrameElement&&c instanceof window.HTMLIFrameElement)try{c=c.contentDocument.head}catch(e){c=null}e[a]=c}return e[a]}}(),i=[];function s(e){for(var a=-1,c=0;c-1?"awsccc-Rtl":"";function b(){return document.querySelector("div[data-id="+s.BANNER_ID+"]")}function f(){return document.querySelector("div[data-id="+s.CUSTOMIZE_ID+"]")}function h(e,a){var c=document.querySelector("label[data-id=awsccc-u-cb-"+e+"-label]"),t=c.classList,n=c.querySelector("input");a?(n.setAttribute("checked",""),t.add("awsccc-u-cb-checkbox-active")):(t.remove("awsccc-u-cb-checkbox-active"),n.removeAttribute("checked")),n.setAttribute("aria-checked",""+a)}var g=function(e){var a=e.event,c=e.category;"checkbox"!==a.target.getAttribute("type")&&"awsccc-cs-s-title"!==a.target.getAttribute("class")||h(c,!p(c))},m=function(a){return function(c,t){var n=b().querySelector("div[data-id=awsccc-cb-tabstart]");document.querySelector("div[data-id="+s.CUSTOMIZE_ID+"]").style.display="none",b().style.display="none",n.setAttribute("tabindex","-1"),e.onSaveConsent(c),document.body.classList.remove("awsccc-cs-modal-open"),e.log("info")(a,{detail:"Save Consent Clicked",source:t,cookie:e.getConsentCookie()})}},k=function(e){"Escape"===e.key&&x()},v=function(){return e.getConsentCookie()||u.DEFAULT_COOKIE},w=function(a){var c;c=v(),i.COOKIE_CATEGORIES.filter((function(e){return e!==i.ESSENTIAL})).forEach((function(e){h(e,c[e])})),f().addEventListener("keydown",k),f().style.display="block",document.body.classList.add("awsccc-cs-modal-open");var t=document.querySelectorAll("div[data-id="+s.TABTRAP_ID+"]");l.convertToArray(t).forEach((function(e,a){0===a&&e.focus({preventScroll:!0}),e.setAttribute("tabindex","0")})),e.log("info")("customizeCookies",{detail:"Customize Consent Clicked",source:a,cookie:e.getConsentCookie()})},x=function(){f().removeEventListener("keydown",k),f().style.display="none",document.body.classList.remove("awsccc-cs-modal-open");var a=f().querySelectorAll("div[data-id="+s.TABTRAP_ID+"]");(l.convertToArray(a).forEach((function(e){e.setAttribute("tabindex","-1")})),"block"===b().style.display)&&b().querySelector("div[data-id=awsccc-cb-tabstart]").focus({preventScroll:!0});e.onModalClose&&e.onModalClose()};return d.default((function(){document.querySelector("#"+s.CONTAINER_ID)||t.render(e.parent||document.body,t.act("div",{id:s.CONTAINER_ID},t.act("div",{id:s.APP_ID,class:c},t.act(n.default,{showConsentSelector:w,handleSaveClick:m("acceptAll"),localizedText:a.consentBanner,hasConsoleNavFooter:e.hasConsoleNavFooter}),t.act(o.default,{consentState:v(),handleSaveClick:m("customize"),handleCheckboxToggle:g,localizedText:a.consentSelector,closeConsentSelector:x,darkModeEnabled:e.hasConsoleNavFooter}))))})),{showConsentSelector:function(e){d.default((function(){w(e)}))},showBanner:function(e){d.default((function(){var a;a=b().querySelector("div[data-id=awsccc-cb-tabstart]"),b().style.display="block",a.setAttribute("tabindex","0"),a.focus({preventScroll:!0}),e()}))}}}a.isChecked=p,a.default={createShortbreadUi:function(e){return b(e)}}},function(e,a,c){"use strict";var t=this&&this.__assign||function(){return(t=Object.assign||function(e){for(var a,c=1,t=arguments.length;c0)try{var i=JSON.parse(atob(n[n.length-1]));return 1===(t=i).e&&"number"==typeof t.p&&"number"==typeof t.f&&"number"==typeof t.a&&"string"==typeof t.i&&"string"==typeof t.v?{essential:1===(c=i).e,performance:1===c.p,functional:1===c.f,advertising:1===c.a,id:c.i,version:c.v}:void o("getCookie",{detail:"Cookie format is not valid",cookie:i})}catch(e){return void o("getCookie",{detail:"Error parsing cookie",cookie:n[n.length-1]})}}function s(e){document.cookie=e}a.getConsentCookie=function(e,a){void 0===e&&(e=function(){return document.cookie});var c=i(e(),a);if(c)return{essential:c.essential,performance:c.performance,functional:c.functional,advertising:c.advertising}},a.setConsentCookie=function(e,a,c,r,l,u,d,p){void 0===a&&(a=o.DEFAULT_DOMAIN),void 0===c&&(c=o.DEFAULT_COOKIE_AGE),void 0===r&&(r=n.default),void 0===l&&(l=s);var b,f=function(e){void 0===e&&(e=function(){return document.cookie});var a=i(e());if(a&&a.id)return a.id}()||r(u,d,p),h=t(t({},e),{id:f,version:o.COOKIE_VERSION}),g={e:(b=h).essential?1:0,p:b.performance?1:0,f:b.functional?1:0,a:b.advertising?1:0,i:b.id,v:b.version};return l("awsccc="+btoa(JSON.stringify(g))+"; domain="+a+"; path=/; max-age="+c+"; secure=true; SameSite=Lax"),h}},function(e,a,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var t=c(46);a.default=function(e,a,c){void 0===a&&(a=t.v4),void 0===c&&(c=function(){return"ts-"+Date.now().toString()});var n=e?e("error"):function(){};try{return a()}catch(e){return n("uuid",{detail:"Error generating UUID",errorMessage:e.message||""}),c()}}},function(e,a,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0}),a.queryGeolocationByHttpGetRequest=a.timestampUrl=a.QUERY_PARAM_KEY=a.DEFAULT_CONSOLE_INTEGRATION_GEOLOCATION_URL=a.DEFAULT_GEOLOCATION_URL=void 0;var t=c(12);a.DEFAULT_GEOLOCATION_URL="https://prod.tools.shortbread.aws.dev/1x1.png",a.DEFAULT_CONSOLE_INTEGRATION_GEOLOCATION_URL="https://prod.tools.shortbread.analytics.console.aws.a2z.com/ping",a.QUERY_PARAM_KEY="awsccc",a.timestampUrl=function(e){if(-1!==e.indexOf("?")){var c=e.split("?");e=c[0]+"?"+a.QUERY_PARAM_KEY+"="+Date.now()+"&"+c[1]}else{if(-1===e.indexOf("#"))return e+"?"+a.QUERY_PARAM_KEY+"="+Date.now();c=e.split("#");e=c[0]+"?"+a.QUERY_PARAM_KEY+"="+Date.now()+"#"+c[1]}return e},a.queryGeolocationByHttpGetRequest=function(e,c,n,o){function i(e,a,t,n,o){e("info")("geolocationLatency",{metric:a,region:t,detail:n,url:c,status:o})}return void 0===e&&(e=!1),void 0===c&&(c=a.DEFAULT_GEOLOCATION_URL),void 0===n&&(n=5e3),void 0===o&&(o=t.DEFAULT_LOGGER),function(s,r){void 0===r&&(r=o||t.DEFAULT_LOGGER);var l=Date.now(),u=new XMLHttpRequest,d="EU",p=200;e&&u.overrideMimeType("application/json"),u.addEventListener("load",(function(){if(p=u.status,e&&304!==p)try{var a=JSON.parse(u.response);403===(p=a.status)&&(d="NON-EU")}catch(e){r("error")("geolocationResponseError",{url:c,detail:"Failed to Parse the Received Geolocation Response"})}else d=403===p?"NON-EU":"EU";i(r,Date.now()-l,d,"Geolocation Response Received",p),s(d)})),u.addEventListener("timeout",(function(){s("EU");var e="Geolocation Request Timed out";i(r,n,"EU",e,u.status),r("error")("geolocationRequestTimeout",{url:c,timeoutSetting:n,detail:e})})),u.open("GET",a.timestampUrl(c)),u.timeout=n,u.send()}},a.default=a.queryGeolocationByHttpGetRequest},function(e,a,c){"use strict";var t=this&&this.__assign||function(){return(t=Object.assign||function(e){for(var a,c=1,t=arguments.length;cspan{color:#687078}",""]),e.exports=a},function(e,a,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var t=c(0),n=c(6),o=c(3);c(35);var i=c(5);a.default=function(e){var a=e.handleSaveClick,c=e.handleCancelClick,s=e.localizedText;return t.act("div",{id:"awsccc-cs-f-c"},t.act(n.default,{dataId:o.CUSTOMIZE_CANCEL_BTN_ID,variant:"secondary",events:{onclick:c},text:s["button-cancel"],props:{"aria-label":s["button-cancel-aria-label"]}}),t.act(n.default,{dataId:o.CUSTOMIZE_SAVE_BTN_ID,variant:"primary",events:{onclick:function(){a({essential:!0,performance:i.isChecked("performance"),functional:i.isChecked("functional"),advertising:i.isChecked("advertising")},"preferencesModal")}},text:s["button-save"],props:{"aria-label":s["button-save-aria-label"]}}))}},function(e,a,c){var t=c(1),n=c(36);"string"==typeof(n=n.__esModule?n.default:n)&&(n=[[e.i,n,""]]);var o={insert:"head",singleton:!1};t(n,o);e.exports=n.locals||{}},function(e,a,c){(a=c(2)(!1)).push([e.i,"#awsccc-sb-ux-c #awsccc-sb-a.awsccc-Rtl #awsccc-cs-f-c{text-align:left}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-f-c{text-decoration:none;padding:10px 20px;text-align:right;border-top:1px solid #eaeded;display:flex;justify-content:center;flex-wrap:wrap}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-f-c .awsccc-u-btn{margin-left:10px}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-f-c .awsccc-u-btn.awsccc-u-btn-secondary{background-color:#fff;border-color:#fff;color:#545b64;margin-bottom:6px}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-f-c .awsccc-u-btn.awsccc-u-btn-secondary:hover{color:#000;background-color:#fafafa}@media screen and (min-width: 700px){#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-f-c{display:block}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-f-c .awsccc-u-btn.awsccc-u-btn-secondary{margin-bottom:0}}",""]),e.exports=a},function(e,a,c){var t=c(1),n=c(38);"string"==typeof(n=n.__esModule?n.default:n)&&(n=[[e.i,n,""]]);var o={insert:"head",singleton:!1};t(n,o);e.exports=n.locals||{}},function(e,a,c){(a=c(2)(!1)).push([e.i,"#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-container{display:flex;align-items:center;justify-items:center;bottom:0;left:0;right:0;top:0;position:fixed;z-index:10002;outline:0;overflow:hidden}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-container-inner{max-width:820px;box-sizing:border-box;outline:none;margin:10px auto;width:calc(100vw - 20px)}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-content{background-color:#fff;border-radius:0;box-sizing:border-box;margin-bottom:0;word-wrap:break-word;box-shadow:0 1px 1px 0 rgba(0,28,36,.3),1px 1px 1px 0 rgba(0,28,36,.15),-1px 1px 1px 0 rgba(0,28,36,.15)}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-header{background-color:#fafafa;padding:19px 20px;border-bottom:1px solid #eaeded}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-title{min-width:0;word-break:break-word;color:#16191f;flex:auto}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-title h2{font-size:18px;font-weight:700;margin:0}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-modalBody{overflow-y:auto;max-height:calc(100vh - 200px);padding:19px 20px}@media screen and (max-width: 480px){#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-modalBody{max-height:calc(100vh - 275px)}}#awsccc-sb-ux-c #awsccc-sb-a #awsccc-cs-modalOverlay{background-color:rgba(242,243,243,.9);position:fixed;z-index:10001;right:0;top:0;bottom:0;left:0}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled{background-color:#2a2e33}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalOverlay{background-color:rgba(22,25,31,.8)}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-header{background-color:#21252c;border-bottom:1px solid #414750}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-title h2{color:#eaeded}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody{background-color:#2a2e33}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody #awsccc-cs-i-container{border-bottom:1px solid #414750}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody #awsccc-cs-i-container span{color:#eaeded}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody .awsccc-cs-s-container{border-bottom:1px solid #414750}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody .awsccc-cs-s-container h3{color:#eaeded}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody .awsccc-cs-s-container p{color:#eaeded}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody .awsccc-cs-s-container span{color:#eaeded}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody .awsccc-cs-s-container rect{fill:#1a2029}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody .awsccc-cs-s-container .awsccc-cs-s-text{border-top:0}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody .awsccc-cs-s-container .awscc-u-cb-checkbox-poly-line{display:none}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody .awsccc-cs-s-container .awsccc-u-cb-checkbox-active .awscc-u-cb-checkbox-poly-line{display:inline-block}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-modalBody .awsccc-cs-s-container .awsccc-u-cb-checkbox-active .awscc-u-cb-checkbox-rect{fill:#00a1c9;stroke:#00a1c9}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-f-c{border-top:1px solid #414750;background-color:#2a2e33}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-f-c .awsccc-u-btn-secondary{background-color:#2a2e33}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-f-c .awsccc-u-btn-secondary span{color:#d5dbdb}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-f-c .awsccc-u-btn-secondary:hover{background-color:#21252c}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-f-c .awsccc-u-btn-primary span{color:#16191f}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-l-container span{color:#eaeded}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-l-container span a{display:inline-block}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-l-container span a span{color:#44b9d6}#awsccc-sb-ux-c #awsccc-sb-a .dark-mode-enabled #awsccc-cs-l-container path{color:#44b9d6}div[data-id=awsccc-cs]{display:none}",""]),e.exports=a},function(e,a,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var t=c(0);c(40),a.default=function(){return t.act("div",{class:"awsccc-u-i-open-c"},t.act("svg",{class:"awsccc-u-i-open",viewBox:"0 0 16 16",focusable:"false","aria-hidden":"true"},t.act("path",{class:"awsccc-stroke-linecap-square",d:"M10 2h4v4"}),t.act("path",{d:"M6 10l8-8"}),t.act("path",{class:"awsccc-stroke-linejoin-round",d:"M14 9.048V14H2V2h5"})))}},function(e,a,c){var t=c(1),n=c(41);"string"==typeof(n=n.__esModule?n.default:n)&&(n=[[e.i,n,""]]);var o={insert:"head",singleton:!1};t(n,o);e.exports=n.locals||{}},function(e,a,c){(a=c(2)(!1)).push([e.i,"#awsccc-sb-ux-c #awsccc-sb-a .awsccc-u-i-open-c{display:inline-block;vertical-align:middle;line-height:1em;padding-left:.3em}#awsccc-sb-ux-c #awsccc-sb-a .awsccc-u-i-open-c svg{stroke-width:2px;pointer-events:none;fill:none;padding-bottom:1px;height:10px;width:10px}#awsccc-sb-ux-c #awsccc-sb-a .awsccc-u-i-open-c svg .awsccc-stroke-linecap-square{stroke-linecap:square}#awsccc-sb-ux-c #awsccc-sb-a .awsccc-u-i-open-c svg .awsccc-stroke-linejoin-round{stroke-linejoin:round}#awsccc-sb-ux-c #awsccc-sb-a .awsccc-u-i-open-c svg path{stroke:currentColor}",""]),e.exports=a},function(e,a,c){var t=c(1),n=c(43);"string"==typeof(n=n.__esModule?n.default:n)&&(n=[[e.i,n,""]]);var o={insert:"head",singleton:!1};t(n,o);e.exports=n.locals||{}},function(e,a,c){(a=c(2)(!1)).push([e.i,'#awsccc-sb-ux-c #awsccc-sb-a *{font-family:"Amazon Ember","HelveticaNeue","Helvetica Neue","Amazon Ember",Roboto,"Roboto-Regular","Amazon Ember",Helvetica,Arial,sans-serif;font-size:14px;line-height:21px;color:#16191f;text-align:left;background:none;border:0}#awsccc-sb-ux-c #awsccc-sb-a.awsccc-Rtl *{direction:rtl;text-align:right}#awsccc-sb-ux-c #awsccc-sb-a.awsccc-Rtl .awsccc-cs-s-container .awsccc-cs-s-action{right:auto;left:20px}@media screen and (min-width: 1020px){#awsccc-sb-ux-c #awsccc-sb-a.awsccc-Rtl #awsccc-cb-c #awsccc-cb-title{padding-right:40px}}#awsccc-sb-ux-c #awsccc-sb-a a,#awsccc-sb-ux-c #awsccc-sb-a a>span,#awsccc-sb-ux-c #awsccc-sb-a a svg path{color:#0073bb;text-decoration:none}#awsccc-sb-ux-c #awsccc-sb-a a:hover,#awsccc-sb-ux-c #awsccc-sb-a a>span:hover,#awsccc-sb-ux-c #awsccc-sb-a a svg path:hover{color:#0073bb;text-decoration:underline}#awsccc-sb-ux-c #awsccc-sb-a .awsccc-tab-helper{outline:0;text-decoration:none}.awsccc-cs-modal-open{overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box}',""]),e.exports=a},function(e,a,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0}),a.convertToArray=a.update=void 0,a.update=function(e,a){return Object.keys(a).forEach((function(c){e[c]=a[c]})),e},a.convertToArray=function(e){return Array.prototype.slice.call(e)}},function(e,a,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=function(e,a,c){function t(){a.removeEventListener("DOMContentLoaded",t),c.removeEventListener("load",t),e()}void 0===a&&(a=document),void 0===c&&(c=window),"loading"!==a.readyState?c.setTimeout(e):(a.addEventListener("DOMContentLoaded",t),c.addEventListener("load",t))}},function(e,a,c){"use strict";c.r(a),c.d(a,"v1",(function(){return b})),c.d(a,"v3",(function(){return y})),c.d(a,"v4",(function(){return C})),c.d(a,"v5",(function(){return E}));var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto),n=new Uint8Array(16);function o(){if(!t)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return t(n)}for(var i=[],s=0;s<256;++s)i.push((s+256).toString(16).substr(1));var r,l,u=function(e,a){var c=a||0,t=i;return(t[e[c+0]]+t[e[c+1]]+t[e[c+2]]+t[e[c+3]]+"-"+t[e[c+4]]+t[e[c+5]]+"-"+t[e[c+6]]+t[e[c+7]]+"-"+t[e[c+8]]+t[e[c+9]]+"-"+t[e[c+10]]+t[e[c+11]]+t[e[c+12]]+t[e[c+13]]+t[e[c+14]]+t[e[c+15]]).toLowerCase()},d=0,p=0;var b=function(e,a,c){var t=a&&c||0,n=a||[],i=(e=e||{}).node||r,s=void 0!==e.clockseq?e.clockseq:l;if(null==i||null==s){var b=e.random||(e.rng||o)();null==i&&(i=r=[1|b[0],b[1],b[2],b[3],b[4],b[5]]),null==s&&(s=l=16383&(b[6]<<8|b[7]))}var f=void 0!==e.msecs?e.msecs:Date.now(),h=void 0!==e.nsecs?e.nsecs:p+1,g=f-d+(h-p)/1e4;if(g<0&&void 0===e.clockseq&&(s=s+1&16383),(g<0||f>d)&&void 0===e.nsecs&&(h=0),h>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");d=f,p=h,l=s;var m=(1e4*(268435455&(f+=122192928e5))+h)%4294967296;n[t++]=m>>>24&255,n[t++]=m>>>16&255,n[t++]=m>>>8&255,n[t++]=255&m;var k=f/4294967296*1e4&268435455;n[t++]=k>>>8&255,n[t++]=255&k,n[t++]=k>>>24&15|16,n[t++]=k>>>16&255,n[t++]=s>>>8|128,n[t++]=255&s;for(var v=0;v<6;++v)n[t+v]=i[v];return a||u(n)};var f=function(e,a,c){function t(e,t,n,o){var i=n&&o||0;if("string"==typeof e&&(e=function(e){e=unescape(encodeURIComponent(e));for(var a=[],c=0;c>>9<<4)+1}function g(e,a){var c=(65535&e)+(65535&a);return(e>>16)+(a>>16)+(c>>16)<<16|65535&c}function m(e,a,c,t,n,o){return g((i=g(g(a,e),g(t,o)))<<(s=n)|i>>>32-s,c);var i,s}function k(e,a,c,t,n,o,i){return m(a&c|~a&t,e,a,n,o,i)}function v(e,a,c,t,n,o,i){return m(a&t|c&~t,e,a,n,o,i)}function w(e,a,c,t,n,o,i){return m(a^c^t,e,a,n,o,i)}function x(e,a,c,t,n,o,i){return m(c^(a|~t),e,a,n,o,i)}var y=f("v3",48,(function(e){if("string"==typeof e){var a=unescape(encodeURIComponent(e));e=new Uint8Array(a.length);for(var c=0;c>5]>>>t%32&255,o=parseInt("0123456789abcdef".charAt(n>>>4&15)+"0123456789abcdef".charAt(15&n),16);a.push(o)}return a}(function(e,a){e[a>>5]|=128<>5]|=(255&e[t/8])<>>32-a}var E=f("v5",80,(function(e){var a=[1518500249,1859775393,2400959708,3395469782],c=[1732584193,4023233417,2562383102,271733878,3285377520];if("string"==typeof e){var t=unescape(encodeURIComponent(e));e=[];for(var n=0;n>>0;v=k,k=m,m=_(g,30)>>>0,g=h,h=y}c[0]=c[0]+h>>>0,c[1]=c[1]+g>>>0,c[2]=c[2]+m>>>0,c[3]=c[3]+k>>>0,c[4]=c[4]+v>>>0}return[c[0]>>24&255,c[0]>>16&255,c[0]>>8&255,255&c[0],c[1]>>24&255,c[1]>>16&255,c[1]>>8&255,255&c[1],c[2]>>24&255,c[2]>>16&255,c[2]>>8&255,255&c[2],c[3]>>24&255,c[3]>>16&255,c[3]>>8&255,255&c[3],c[4]>>24&255,c[4]>>16&255,c[4]>>8&255,255&c[4]]}))}])})); -//# sourceMappingURL=index.js.map diff --git a/src/views/Home/PackageGrid.tsx b/src/views/Home/PackageGrid.tsx index af149126..e88d88bc 100644 --- a/src/views/Home/PackageGrid.tsx +++ b/src/views/Home/PackageGrid.tsx @@ -1,12 +1,12 @@ import { Grid } from "@chakra-ui/react"; import { FunctionComponent } from "react"; -import { CatalogPackage } from "../../api/package/packages"; +import { ExtendedCatalogPackage } from "../../api/catalog-search"; import { PackageCard } from "../../components/PackageCard"; import testIds from "./testIds"; export const PackageGrid: FunctionComponent<{ "data-event"?: string; - packages: CatalogPackage[]; + packages: ExtendedCatalogPackage[]; }> = ({ "data-event": dataEvent, packages }) => { return ( { if (isLoading || error || !results) return []; if (showLastUpdated) { return results.slice(0, showLastUpdated); - } else if (showPackages) { + } else if (showPackages && searchInstance) { return showPackages .map((p) => { - const pkg = findPackage({ packages: results }, p.name); + const [pkg] = searchInstance.findByName(p.name, { dedup: true }); + if (pkg) { return { ...pkg, @@ -36,9 +39,16 @@ export const useSection = ({ } return undefined; }) - .filter((pkg) => pkg !== undefined) as CatalogPackage[]; + .filter((pkg) => pkg !== undefined) as ExtendedCatalogPackage[]; } else { return undefined; } - }, [results, error, isLoading, showLastUpdated, showPackages]); + }, [ + isLoading, + error, + results, + showLastUpdated, + showPackages, + searchInstance, + ]); }; diff --git a/src/views/Package/PackageHeader/Heading.tsx b/src/views/Package/PackageHeader/Heading.tsx index cdbc5234..692a07db 100644 --- a/src/views/Package/PackageHeader/Heading.tsx +++ b/src/views/Package/PackageHeader/Heading.tsx @@ -7,6 +7,7 @@ import { } from "@chakra-ui/react"; import { Assembly } from "@jsii/spec"; import type { FunctionComponent } from "react"; +import { mapConstructFrameworks } from "../../../api/catalog-search/util"; import { Metadata } from "../../../api/package/metadata"; import { CDKTypeBadge } from "../../../components/CDKType"; import { PackageTag } from "../../../components/PackageTag"; @@ -36,7 +37,16 @@ export const Heading: FunctionComponent = ({ keywords: assembly?.keywords ?? [], }); - const cdkTypeProps = metadata.constructFramework ?? {}; + const constructFrameworks = mapConstructFrameworks(metadata); + const [constructFramework] = constructFrameworks; + const [cdkName, majorVersion] = constructFramework ?? []; + + const dataEvent = + constructFrameworks.size === 1 + ? PACKAGE_ANALYTICS.CDK_BADGE.eventName( + `${cdkName}${majorVersion !== undefined ? ` v${majorVersion}` : ""}` + ) + : undefined; return ( = ({ wrap="wrap" > {tags.map(({ id, keyword: { label, color } = {} }) => (