@internetarchive/collection-browser 2.12.0 → 2.12.1-alpha-webdev5427.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/app-root.d.ts +1 -0
- package/dist/src/app-root.js +48 -2
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.js +9 -1
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.js +3 -3
- package/dist/src/collection-facets/more-facets-content.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.js +4 -3
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.js.map +1 -1
- package/dist/src/collection-facets.d.ts +3 -1
- package/dist/src/collection-facets.js +22 -4
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/models.d.ts +14 -4
- package/dist/src/models.js +34 -3
- package/dist/src/models.js.map +1 -1
- package/dist/src/utils/facet-utils.js +8 -2
- package/dist/src/utils/facet-utils.js.map +1 -1
- package/dist/test/collection-facets.test.js +27 -0
- package/dist/test/collection-facets.test.js.map +1 -1
- package/dist/test/restoration-state-handler.test.js +17 -10
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/package.json +1 -1
- package/src/app-root.ts +49 -2
- package/src/collection-browser.ts +12 -0
- package/src/collection-facets/more-facets-content.ts +5 -4
- package/src/collection-facets/smart-facets/smart-facet-bar.ts +2 -2
- package/src/collection-facets.ts +20 -5
- package/src/models.ts +43 -8
- package/src/utils/facet-utils.ts +5 -3
- package/test/collection-facets.test.ts +33 -0
- package/test/restoration-state-handler.test.ts +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-facets.js","sourceRoot":"","sources":["../../src/collection-facets.ts"],"names":[],"mappings":";AAAA,OAAO,EACL,GAAG,EACH,IAAI,EACJ,UAAU,EAEV,OAAO,GAER,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AASvD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,mCAAmC,CAAC;AAC3C,OAAO,EACL,WAAW,GAEZ,MAAM,gCAAgC,CAAC;AAKxC,OAAO,WAAW,MAAM,4BAA4B,CAAC;AACrD,OAAO,UAAU,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAKL,iBAAiB,EACjB,WAAW,EACX,wBAAwB,EACxB,0BAA0B,EAE1B,qBAAqB,EACrB,gBAAgB,GAEjB,MAAM,UAAU,CAAC;AAKlB,OAAO,yCAAyC,CAAC;AACjD,OAAO,qCAAqC,CAAC;AAC7C,OAAO,yCAAyC,CAAC;AACjD,OAAO,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAGtB,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,UAAU;IAAzC;;QAawB,qBAAgB,GAAG,IAAI,CAAC;QAExB,kBAAa,GAAG,KAAK,CAAC;QAEtB,+BAA0B,GAAG,KAAK,CAAC;QAInC,sBAAiB,GAAG,KAAK,CAAC;QAI1B,4BAAuB,GAAG,KAAK,CAAC;QAEhC,6BAAwB,GAAG,KAAK,CAAC;QAMnC,sBAAiB,GAAa,EAAE,CAAC;QAMhC,uBAAkB,GAAW,WAAW,CAAC;QAExC,iBAAY,GAAG,KAAK,CAAC;QAoBzC,eAAU,GAAiC;YAClD,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,KAAK;YACjB,IAAI,EAAE,KAAK;SACZ,CAAC;QAEF;;WAEG;QACK,sBAAiB,GAAG,CAAC,CAAC;QA8ItB,mCAA8B,GAAG,GAAS,EAAE;;YAClD,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC9D,CAAC,CAAC;QAuDF;;;;;WAKG;QACK,8BAAyB,GAAG,CAClC,CAGE,EACI,EAAE;YACR,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC;YACtC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,2BAA2B,EAAE;gBACzD,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;aAC7B,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC,CAAC;IA0fJ,CAAC;IAhtBC,MAAM;QACJ,MAAM,gBAAgB,GAAG,QAAQ,CAAC;YAChC,OAAO,EAAE,IAAI,CAAC,aAAa;YAC3B,QAAQ,EAAE,IAAI,CAAC,YAAY;SAC5B,CAAC,CAAC;QAEH,2CAA2C;QAC3C,8EAA8E;QAC9E,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;QAC9C,OAAO,IAAI,CAAA;kCACmB,gBAAgB;UACxC,IAAI,CAAC,uBAAuB;YAC9B,CAAC,IAAI,CAAC,6BAA6B,IAAI,IAAI,CAAC,0BAA0B,CAAC;YACrE,CAAC,CAAC,IAAI,CAAA;;;kCAGkB,iBAAiB;;;yBAG1B,iBAAiB;;oBAEtB,IAAI,CAAC,2BAA2B;;kBAElC,IAAI,CAAC,iBAAiB;;aAE3B;YACH,CAAC,CAAC,OAAO;UACT,IAAI,CAAC,wBAAwB;UAC7B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CACnC,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CACvC;;KAEJ,CAAC;IACJ,CAAC;IAED,IAAY,wBAAwB;;QAClC,4DAA4D;QAC5D,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,iBAAiB,0CAAE,MAAM,CAAA;YAAE,OAAO,OAAO,CAAC;QAEpD,2CAA2C;QAC3C,sEAAsE;QACtE,MAAM,SAAS,GAAG,gBAAgB,CAAC;QACnC,OAAO,IAAI,CAAA;;;0BAGW,SAAS;;;;mBAIhB,SAAS,IAAI,GAAG,CAAC,SAAS,CAAC;;;YAGlC,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,EAAE;;YACrC,MAAM,aAAa,GAAG,GAAG,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,GAAG,MAAM,EAAE,CAAC;YAErF,OAAO,IAAI,CAAA;;uBAEA,aAAa;0BACV,MAAM;yBACP,IAAI,CAAC,uBAAuB;;kBAEnC,MAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,GAAG,CAAC,MAAM,CAAC,mCAAI,MAAM;;kBAE5C,CAAC;QACT,CAAC,CAAC;;;KAGP,CAAC;IACJ,CAAC;IAEO,uBAAuB,CAAC,CAAQ;;QACtC,MAAA,IAAI,CAAC,gBAAgB,0CAAE,SAAS,CAAC;YAC/B,QAAQ,EAAE,mBAAmB,CAAC,OAAO;YACrC,MAAM,EAAE,gBAAgB,CAAC,uBAAuB;YAChD,KAAK,EAAG,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,mBAAmB;;QACzB,MAAM,EAAE,6BAA6B,EAAE,GAAG,IAAI,CAAC;QAC/C,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,gBAAgB,CAAC;QAChE,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,eAAe,CAAC;QAC/D,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,OAAmB,CAAC;QAEnE,+EAA+E;QAC/E,gFAAgF;QAChF,kFAAkF;QAClF,qFAAqF;QACrF,yDAAyD;QACzD,qFAAqF;QACrF,iFAAiF;QACjF,8CAA8C;QAC9C,MAAM,yBAAyB,GAAG,CAAC,IAAc,EAAE,EAAE;YACnD,IAAI,IAAI,IAAI,IAAI,YAAY,kBAAkB,EAAE,CAAC;gBAC/C,MAAM,kBAAkB,GAAG,IAA0B,CAAC;gBACtD,kBAAkB,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;gBAC1D,kBAAkB,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;YAC5D,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,kBAAkB,GAAG,IAAI,CAAA;;UAEzB,GAAG,CAAC,yBAAyB,CAAC;mBACrB,OAAO;mBACP,OAAO;2BACC,IAAI,CAAC,eAAe;2BACpB,IAAI,CAAC,eAAe;mBAC5B,OAAO;wBACF,IAAI,CAAC,YAAY;4BACb,IAAI,CAAC,gBAAgB;qCACZ,IAAI,CAAC,yBAAyB;uBAC5C,IAAI,CAAC,8BAA8B;;KAErD,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC;YAC7B,SAAS,EAAE,MAAM;YACjB,WAAW,EAAE,SAAS;YACtB,cAAc,EAAE,KAAK;YACrB,oBAAoB,EAAE,IAAI,EAAE,+BAA+B;YAC3D,KAAK,EAAE,IAAI,CAAA,qBAAqB;SACjC,CAAC,CAAC;QAEH,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACzD,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC;YAC3B,MAAM;YACN,kBAAkB;YAClB,uBAAuB,EAAE,IAAI,CAAC,8BAA8B;SAC7D,CAAC,CAAC;QAEH,MAAA,IAAI,CAAC,gBAAgB,0CAAE,SAAS,CAAC;YAC/B,QAAQ,EAAE,mBAAmB,CAAC,OAAO;YACrC,MAAM,EAAE,gBAAgB,CAAC,iBAAiB;YAC1C,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;SAC5B,CAAC,CAAC;IACL,CAAC;IAMD,OAAO,CAAC,OAAuB;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;IAED,gCAAgC;IACxB,0BAA0B;QAChC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAiB,eAAe,EAAE;YAC7D,MAAM,EAAE,IAAI,CAAC,cAAc;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,IAAY,2BAA2B;QACrC,OAAO,IAAI,CAAC,wBAAwB,IAAI,CAAC,IAAI,CAAC,aAAa;YACzD,CAAC,CAAC,IAAI,CAAA;;;mBAGO,IAAI,CAAC,mBAAmB;;YAE/B,UAAU;kBACJ;YACZ,CAAC,CAAC,OAAO,CAAC;IACd,CAAC;IAED,IAAY,iBAAiB;;QAC3B,MAAM,EAAE,6BAA6B,EAAE,GAAG,IAAI,CAAC;QAC/C,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,gBAAgB,CAAC;QAChE,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,eAAe,CAAC;QAC/D,OAAO,IAAI,CAAC,0BAA0B;YACpC,CAAC,CAAC,IAAI,CAAA,yDAAyD,CAAC,iBAAiB;YACjF,CAAC,CAAC,IAAI,CAAA;;uBAEW,OAAO;uBACP,OAAO;+BACC,MAAA,IAAI,CAAC,eAAe,mCAAI,OAAO;+BAC/B,MAAA,IAAI,CAAC,eAAe,mCAAI,OAAO;2BACnC,GAAG;;qBAET,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,YAAY;gBAClD,CAAC,CAAC,IAAI,CAAC,YAAY;gBACnB,CAAC,CAAC,GAAG;oBACC,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,OAAmB;yCAC7B,IAAI,CAAC,yBAAyB;;SAE9D,CAAC;IACR,CAAC;IAqBD;;OAEG;IACH,IAAY,YAAY;QACtB,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;;YACnC,MAAM,kBAAkB,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CACtD,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,QAAQ,CAChC,CAAC;YACF,MAAM,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAC1D,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,QAAQ,CAChC,CAAC;YAEF,iFAAiF;YACjF,IAAI,kBAAkB,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC/C,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YAED,wEAAwE;YACxE,IAAI,CAAC,mBAAmB;gBAAE,OAAO;YAEjC,8EAA8E;YAC9E,MAAM,UAAU,GAAG,kBAAkB,aAAlB,kBAAkB,cAAlB,kBAAkB,GAAI,mBAAmB,CAAC;YAE7D,4CAA4C;YAC5C,IAAI,gBAAgB,GAClB,MAAA,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;gBACvC,MAAM,cAAc,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,CACrD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAC1B,CAAC;gBACF,OAAO,cAAc;oBACnB,CAAC,CAAC;wBACE,GAAG,MAAM;wBACT,KAAK,EAAE,cAAc,CAAC,KAAK;qBAC5B;oBACH,CAAC,CAAC,MAAM,CAAC;YACb,CAAC,CAAC,mCAAI,EAAE,CAAC;YAEX,uDAAuD;YACvD,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBAC3C,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC;gBACxE,IAAI,cAAc;oBAAE,OAAO;gBAC3B,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;YAEH;;;;;eAKG;YACH,IAAI,iBAAiB,GAAG,MAAA,MAAM,CAAC,IAAI,CACjC,CAAC,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,OAAc,KAAI,EAAE,CAC1C,0CAAE,MAAM,CAAC;YACV,IAAI,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC/C,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,8BAA8B;YAC5E,CAAC;YAED,gEAAgE;YAChE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,gBAAgB,GAAG,gBAAgB,CAAC,MAAM,CACxC,MAAM,CAAC,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,GAAsB,CAAC,CACpE,CAAC;YACJ,CAAC;YAED,iFAAiF;YACjF,2BAA2B,CAAC,gBAAgB,CAAC,CAAC;YAE9C,gFAAgF;YAChF,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;gBAC7B,MAAM,eAAe,GAAG,gBAAgB,CAAC,SAAS,CAChD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,KAAK,YAAY,CACtC,CAAC;gBAEF,IAAI,eAAe,IAAI,iBAAiB,EAAE,CAAC;oBACzC,MAAM,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC,MAAM,CAChD,eAAe,EACf,CAAC,CACF,CAAC;oBAEF,sFAAsF;oBACtF,IAAI,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBAC/C,iBAAiB,IAAI,CAAC,CAAC;oBACzB,CAAC;oBAED,gBAAgB,CAAC,MAAM,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;YAED,8DAA8D;YAC9D,UAAU,CAAC,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;YAElE,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,IAAY,mBAAmB;QAC7B,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,EAAE,CAAC;QAEpC,MAAM,WAAW,GAAiB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,CACvE,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,GAAkB,CAAC;YAClC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;YAElC,MAAM,OAAO,GAAkB,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,CAC/D,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE;;gBACrB,IAAI,WAAW,GAAW,KAAK,CAAC;gBAChC,2DAA2D;gBAC3D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,WAAW;wBACT,MAAA,wBAAwB,CAAC,KAAwB,CAAC,mCAAI,KAAK,CAAC;gBAChE,CAAC;gBACD,OAAO;oBACL,WAAW;oBACX,GAAG,EAAE,KAAK;oBACV,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,KAAK,EAAE,SAAS,CAAC,KAAK;iBACvB,CAAC;YACJ,CAAC,CACF,CAAC;YAEF,OAAO;gBACL,KAAK;gBACL,GAAG,EAAE,MAAM;gBACX,OAAO;aACR,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAY,sBAAsB;;QAChC,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,MAAA,IAAI,CAAC,YAAY,mCAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE;YACrE,4EAA4E;YAC5E,IAAI,GAAG,KAAK,gBAAgB;gBAAE,OAAO;YAErC,MAAM,MAAM,GAAG,GAAkB,CAAC;YAClC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC,KAAK;gBAAE,OAAO;YAEnB,IAAI,aAAa,GAAG,WAAW,CAAC,gBAAgB,CAC9C,gBAAgB,CAAC,MAAM,CAAC,CACb,CAAC;YAEd,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;gBAC5B,oFAAoF;gBACpF,aAAa,GAAG,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,CAAC,MAAM,CAAC,EAAE;;oBAC7C,MAAM,SAAS,GAAG,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,GAAG,0CAAE,QAAQ,EAAE,CAAC;oBAC1C,OAAO,CACL,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,UAAU,CAAC,MAAM,CAAC,CAAA,CACpE,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,YAAY,GAAkB,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;;gBAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC;gBAC7B,IAAI,WAAW,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;gBAClC,kEAAkE;gBAClE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,WAAW;wBACT,MAAA,wBAAwB,CAAC,MAAM,CAAC,GAAsB,CAAC,mCACvD,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;gBACpB,CAAC;gBACD,OAAO;oBACL,WAAW;oBACX,GAAG,EAAE,GAAG,SAAS,EAAE;oBACnB,KAAK,EAAE,MAAM,CAAC,SAAS;oBACvB,KAAK,EAAE,MAAM;iBACd,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,MAAM,KAAK,GAAe;gBACxB,KAAK;gBACL,GAAG,EAAE,MAAM;gBACX,OAAO,EAAE,YAAY;aACtB,CAAC;YACF,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,qBAAqB,CAC3B,UAAsB;QAEtB,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAE3E,MAAM,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAA;+BACK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,WAAW;KAC/D,CAAC;QAEF,MAAM,eAAe,GAAG,GAAG,EAAE;YAC3B,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC7C,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;YAC7B,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC;QAClC,CAAC,CAAC;QAEF,2CAA2C;QAC3C,sEAAsE;QACtE,MAAM,QAAQ,GAAG,4BAA4B,UAAU,CAAC,GAAG,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAA;;6BAEc,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;0BACzC,QAAQ;sBACZ,QAAQ;;;;iBAIb,QAAQ;qBACJ,eAAe;qBACf,eAAe;;cAEtB,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,UAAU,CAAC,KAAK;;;;;uCAKvC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;6CACd,UAAU,CAAC,GAAG;;YAE/C,IAAI,CAAC,aAAa;YAClB,CAAC,CAAC,IAAI,CAAC,8BAA8B,EAAE;YACvC,CAAC,CAAC,IAAI,CAAA;kBACA,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;kBACjC,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC;eACxC;;;KAGV,CAAC;IACJ,CAAC;IAEO,8BAA8B;QACpC,6BAA6B;QAC7B,OAAO,IAAI,CAAA;QACP,GAAG,CACH,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EACnB,GAAG,EAAE,CAAC,IAAI,CAAA,6CAA6C,CACxD;KACF,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,oBAAoB,CAC1B,UAAsB;QAEtB,8CAA8C;QAC9C,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,gDAAgD;QAChD,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,6EAA6E;QAC7E,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACpE,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,sEAAsE;QACtE,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAEnD,2CAA2C;QAC3C,0DAA0D;QAC1D,OAAO,IAAI,CAAA;;eAEA,GAAG,EAAE;;YACZ,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YAChD,MAAA,IAAI,CAAC,gBAAgB,0CAAE,SAAS,CAAC;gBAC/B,QAAQ,EAAE,mBAAmB,CAAC,OAAO;gBACrC,MAAM,EAAE,gBAAgB,CAAC,mBAAmB;gBAC5C,KAAK,EAAE,UAAU,CAAC,GAAG;aACtB,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC,CAC9D,CAAC;QACJ,CAAC;;;;cAIO,CAAC;IACb,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,UAAsB,EACtB,QAA6B;;QAE7B,MAAM,kBAAkB,GAAG,IAAI,CAAA;;4BAEP,IAAI,CAAC,gBAAgB;oBAC7B,UAAU,CAAC,GAAG;iBACjB,IAAI,CAAC,KAAK;qBACN,IAAI,CAAC,SAAS;+BACJ,IAAI,CAAC,mBAAmB;wBAC/B,IAAI,CAAC,YAAY;yBAChB,IAAI,CAAC,aAAa;sBACrB,IAAI,CAAC,UAAU;4BACT,IAAI,CAAC,gBAAgB;0BACvB,IAAI,CAAC,cAAc;oBACzB,QAAQ;yBACH,CAAC,CAAc,EAAE,EAAE;YAClC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAiB,eAAe,EAAE;gBAC7D,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;;;KAGJ,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC;YAC7B,SAAS,EAAE,MAAM;YACjB,WAAW,EAAE,SAAS;YACtB,cAAc,EAAE,KAAK;YACrB,oBAAoB,EAAE,IAAI,EAAE,+BAA+B;YAC3D,KAAK,EAAE,IAAI,CAAA,gBAAgB;SAC5B,CAAC,CAAC;QACH,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACvD,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC;YAC3B,MAAM;YACN,kBAAkB;YAClB,uBAAuB,EAAE,GAAG,EAAE;;gBAC5B,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,UAAsB;QAC7C,OAAO,IAAI,CAAA;;8BAEe,IAAI,CAAC,kBAAkB;sBAC/B,UAAU;0BACN,IAAI,CAAC,cAAc;4BACjB,IAAI,CAAC,gBAAgB;sBAC3B,CAAC,CAAiC,EAAE,EAAE;YAClD,IAAI,CAAC,cAAc,GAAG,yBAAyB,CAC7C,IAAI,CAAC,cAAc,EACnB,UAAU,CAAC,GAAG,EACd,CAAC,CAAC,MAAM,CAAC,MAAM,EACf,IAAI,CACL,CAAC;YAEF,MAAM,KAAK,GAAG,IAAI,WAAW,CAAiB,eAAe,EAAE;gBAC7D,MAAM,EAAE,IAAI,CAAC,cAAc;gBAC3B,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;;KAEJ,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,MAAM;QACf,OAAO;YACL,WAAW;YACX,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsHF;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AA3xB6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uDAAwC;AAEvC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oDAAyB;AAExB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAA4C;AAE3C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uEAA6C;AAE5C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yDAA0B;AAEzB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yDAA0B;AAExB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;0DAAyB;AAExB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;uDAAuB;AAEtB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;oEAAoC;AAEpC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wDAAiC;AAE/B;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;2DAA2B;AAE3B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAAuB;AAErB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;iEAAiC;AAEhC;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;kEAAkC;AAElC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAgB;AAEf;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6DAA2C;AAE3C;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;2DAAkC;AAEhC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;mDAAuB;AAEtB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2DAA4B;AAE3B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4DAA0C;AAExC;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;sDAAsB;AAGlD;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;sDACR;AAGrC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;wDACE;AAG/C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;gEACY;AAGzD;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0DACA;AAG7C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0DACA;AAG7C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0DACT;AAE3B;IAAR,KAAK,EAAE;oDAQN;AArES,gBAAgB;IAD5B,aAAa,CAAC,mBAAmB,CAAC;GACtB,gBAAgB,CA4xB5B","sourcesContent":["import {\n css,\n html,\n LitElement,\n PropertyValues,\n nothing,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { map } from 'lit/directives/map.js';\nimport { ref } from 'lit/directives/ref.js';\nimport { msg } from '@lit/localize';\nimport { classMap } from 'lit/directives/class-map.js';\nimport type {\n Aggregation,\n AggregationSortType,\n Bucket,\n FilterMap,\n SearchServiceInterface,\n SearchType,\n} from '@internetarchive/search-service';\nimport '@internetarchive/histogram-date-range';\nimport '@internetarchive/feature-feedback';\nimport {\n ModalConfig,\n ModalManagerInterface,\n} from '@internetarchive/modal-manager';\nimport type { FeatureFeedbackServiceInterface } from '@internetarchive/feature-feedback';\nimport type { RecaptchaManagerInterface } from '@internetarchive/recaptcha-manager';\nimport type { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';\nimport type { SharedResizeObserverInterface } from '@internetarchive/shared-resize-observer';\nimport chevronIcon from './assets/img/icons/chevron';\nimport expandIcon from './assets/img/icons/expand';\nimport {\n FacetOption,\n SelectedFacets,\n FacetGroup,\n FacetBucket,\n facetDisplayOrder,\n facetTitles,\n lendingFacetDisplayNames,\n lendingFacetKeysVisibility,\n LendingFacetKey,\n suppressedCollections,\n defaultFacetSort,\n FacetEventDetails,\n} from './models';\nimport type {\n CollectionTitles,\n PageSpecifierParams,\n} from './data-source/models';\nimport './collection-facets/more-facets-content';\nimport './collection-facets/facets-template';\nimport './collection-facets/facet-tombstone-row';\nimport './expanded-date-picker';\nimport {\n analyticsActions,\n analyticsCategories,\n} from './utils/analytics-events';\nimport { srOnlyStyle } from './styles/sr-only';\nimport { ExpandedDatePicker } from './expanded-date-picker';\nimport {\n sortBucketsBySelectionState,\n updateSelectedFacetBucket,\n} from './utils/facet-utils';\n\n@customElement('collection-facets')\nexport class CollectionFacets extends LitElement {\n @property({ type: Object }) searchService?: SearchServiceInterface;\n\n @property({ type: String }) searchType?: SearchType;\n\n @property({ type: Object }) aggregations?: Record<string, Aggregation>;\n\n @property({ type: Object }) fullYearsHistogramAggregation?: Aggregation;\n\n @property({ type: String }) minSelectedDate?: string;\n\n @property({ type: String }) maxSelectedDate?: string;\n\n @property({ type: Boolean }) moreLinksVisible = true;\n\n @property({ type: Boolean }) facetsLoading = false;\n\n @property({ type: Boolean }) fullYearAggregationLoading = false;\n\n @property({ type: Object }) selectedFacets?: SelectedFacets;\n\n @property({ type: Boolean }) collapsableFacets = false;\n\n @property({ type: Number }) contentWidth?: number;\n\n @property({ type: Boolean }) showHistogramDatePicker = false;\n\n @property({ type: Boolean }) allowExpandingDatePicker = false;\n\n @property({ type: String }) query?: string;\n\n @property({ type: Object }) pageSpecifierParams?: PageSpecifierParams;\n\n @property({ type: Array }) parentCollections: string[] = [];\n\n @property({ type: Object }) filterMap?: FilterMap;\n\n @property({ type: String }) baseNavigationUrl?: string;\n\n @property({ type: String }) collectionPagePath: string = '/details/';\n\n @property({ type: Boolean }) isManageView = false;\n\n @property({ type: Object, attribute: false })\n modalManager?: ModalManagerInterface;\n\n @property({ type: Object, attribute: false })\n resizeObserver?: SharedResizeObserverInterface;\n\n @property({ type: Object, attribute: false })\n featureFeedbackService?: FeatureFeedbackServiceInterface;\n\n @property({ type: Object, attribute: false })\n recaptchaManager?: RecaptchaManagerInterface;\n\n @property({ type: Object, attribute: false })\n analyticsHandler?: AnalyticsManagerInterface;\n\n @property({ type: Object, attribute: false })\n collectionTitles?: CollectionTitles;\n\n @state() openFacets: Record<FacetOption, boolean> = {\n subject: false,\n lending: false,\n mediatype: false,\n language: false,\n creator: false,\n collection: false,\n year: false,\n };\n\n /**\n * Maximum # of facet buckets to render per facet group\n */\n private allowedFacetCount = 6;\n\n render() {\n const containerClasses = classMap({\n loading: this.facetsLoading,\n managing: this.isManageView,\n });\n\n // Added data-testid for Playwright testing\n // Using facet-group class and aria-labels is not ideal for Playwright locator\n const datePickerLabelId = 'date-picker-label';\n return html`\n <div id=\"container\" class=${containerClasses}>\n ${this.showHistogramDatePicker &&\n (this.fullYearsHistogramAggregation || this.fullYearAggregationLoading)\n ? html`\n <section\n class=\"facet-group\"\n aria-labelledby=${datePickerLabelId}\n data-testid=\"facet-group-header-label-date-picker\"\n >\n <h3 id=${datePickerLabelId}>\n Year Published <span class=\"sr-only\">range filter</span>\n ${this.expandDatePickerBtnTemplate}\n </h3>\n ${this.histogramTemplate}\n </section>\n `\n : nothing}\n ${this.collectionPartOfTemplate}\n ${this.mergedFacets.map(facetGroup =>\n this.getFacetGroupTemplate(facetGroup),\n )}\n </div>\n `;\n }\n\n private get collectionPartOfTemplate(): TemplateResult | typeof nothing {\n // We only display the \"Part Of\" section on collection pages\n if (!this.parentCollections?.length) return nothing;\n\n // Added data-testid for Playwright testing\n // Using className and aria-labels is not ideal for Playwright locator\n const headingId = 'partof-heading';\n return html`\n <section\n class=\"facet-group partof-collections\"\n aria-labelledby=${headingId}\n data-testid=\"facet-group-partof-collections\"\n >\n <div class=\"facet-group-header\">\n <h3 id=${headingId}>${msg('Part Of')}</h3>\n </div>\n <ul>\n ${map(this.parentCollections, collxn => {\n const collectionURL = `${this.baseNavigationUrl}${this.collectionPagePath}${collxn}`;\n\n return html` <li>\n <a\n href=${collectionURL}\n data-id=${collxn}\n @click=${this.partOfCollectionClicked}\n >\n ${this.collectionTitles?.get(collxn) ?? collxn}\n </a>\n </li>`;\n })}\n </ul>\n </section>\n `;\n }\n\n private partOfCollectionClicked(e: Event): void {\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.partOfCollectionClicked,\n label: (e.target as HTMLElement).dataset.id,\n });\n }\n\n /**\n * Opens a modal dialog containing an enlarged version of the date picker.\n */\n private showDatePickerModal(): void {\n const { fullYearsHistogramAggregation } = this;\n const minDate = fullYearsHistogramAggregation?.first_bucket_key;\n const maxDate = fullYearsHistogramAggregation?.last_bucket_key;\n const buckets = fullYearsHistogramAggregation?.buckets as number[];\n\n // Because the modal manager does not clear its DOM content after being closed,\n // it may try to render the exact same date picker template when it is reopened.\n // And because it isn't actually a descendent of this collection-facets component,\n // changes to the template defined here may not trigger a reactive update to the date\n // picker, resulting in it displaying a stale date range.\n // This ref callback ensures that every time the date picker modal is opened, it will\n // always propagate the most recent date range into the date picker regardless of\n // whether Lit thinks the update is necessary.\n const expandedDatePickerChanged = (elmt?: Element) => {\n if (elmt && elmt instanceof ExpandedDatePicker) {\n const expandedDatePicker = elmt as ExpandedDatePicker;\n expandedDatePicker.minSelectedDate = this.minSelectedDate;\n expandedDatePicker.maxSelectedDate = this.maxSelectedDate;\n }\n };\n\n const customModalContent = html`\n <expanded-date-picker\n ${ref(expandedDatePickerChanged)}\n .minDate=${minDate}\n .maxDate=${maxDate}\n .minSelectedDate=${this.minSelectedDate}\n .maxSelectedDate=${this.maxSelectedDate}\n .buckets=${buckets}\n .modalManager=${this.modalManager}\n .analyticsHandler=${this.analyticsHandler}\n @histogramDateRangeApplied=${this.histogramDateRangeUpdated}\n @modalClosed=${this.handleExpandedDatePickerClosed}\n ></expanded-date-picker>\n `;\n\n const config = new ModalConfig({\n bodyColor: '#fff',\n headerColor: '#194880',\n showHeaderLogo: false,\n closeOnBackdropClick: true, // TODO: want to fire analytics\n title: html`Select a date range`,\n });\n\n this.modalManager?.classList.add('expanded-date-picker');\n this.modalManager?.showModal({\n config,\n customModalContent,\n userClosedModalCallback: this.handleExpandedDatePickerClosed,\n });\n\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.histogramExpanded,\n label: window.location.href,\n });\n }\n\n private handleExpandedDatePickerClosed = (): void => {\n this.modalManager?.classList.remove('expanded-date-picker');\n };\n\n updated(changed: PropertyValues) {\n if (changed.has('selectedFacets')) {\n this.dispatchFacetsChangedEvent();\n }\n }\n\n // TODO: want to fire analytics?\n private dispatchFacetsChangedEvent() {\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: this.selectedFacets,\n });\n this.dispatchEvent(event);\n }\n\n /**\n * Template for the \"Expand\" button to show the date picker modal, or\n * `nothing` if that button should currently not be shown.\n */\n private get expandDatePickerBtnTemplate(): TemplateResult | typeof nothing {\n return this.allowExpandingDatePicker && !this.facetsLoading\n ? html`<button\n class=\"expand-date-picker-btn\"\n aria-hidden=\"true\"\n @click=${this.showDatePickerModal}\n >\n ${expandIcon}\n </button>`\n : nothing;\n }\n\n private get histogramTemplate() {\n const { fullYearsHistogramAggregation } = this;\n const minDate = fullYearsHistogramAggregation?.first_bucket_key;\n const maxDate = fullYearsHistogramAggregation?.last_bucket_key;\n return this.fullYearAggregationLoading\n ? html`<div class=\"histogram-loading-indicator\">…</div>` // Ellipsis block\n : html`\n <histogram-date-range\n .minDate=${minDate}\n .maxDate=${maxDate}\n .minSelectedDate=${this.minSelectedDate ?? minDate}\n .maxSelectedDate=${this.maxSelectedDate ?? maxDate}\n .updateDelay=${100}\n missingDataMessage=\"...\"\n .width=${this.collapsableFacets && this.contentWidth\n ? this.contentWidth\n : 180}\n .bins=${fullYearsHistogramAggregation?.buckets as number[]}\n @histogramDateRangeUpdated=${this.histogramDateRangeUpdated}\n ></histogram-date-range>\n `;\n }\n\n /**\n * Dispatches a `histogramDateRangeUpdated` event with the date range copied from the\n * input event.\n *\n * Arrow function to ensure `this` is always bound to the current component.\n */\n private histogramDateRangeUpdated = (\n e: CustomEvent<{\n minDate: string;\n maxDate: string;\n }>,\n ): void => {\n const { minDate, maxDate } = e.detail;\n const event = new CustomEvent('histogramDateRangeUpdated', {\n detail: { minDate, maxDate },\n });\n this.dispatchEvent(event);\n };\n\n /**\n * Combines the selected facets with the aggregations to create a single list of facets\n */\n private get mergedFacets(): FacetGroup[] {\n const facetGroups: FacetGroup[] = [];\n\n facetDisplayOrder.forEach(facetKey => {\n const selectedFacetGroup = this.selectedFacetGroups.find(\n group => group.key === facetKey,\n );\n const aggregateFacetGroup = this.aggregationFacetGroups.find(\n group => group.key === facetKey,\n );\n\n // if the user selected a facet, but it's not in the aggregation, we add it as-is\n if (selectedFacetGroup && !aggregateFacetGroup) {\n facetGroups.push(selectedFacetGroup);\n return;\n }\n\n // if we don't have an aggregate facet group, don't add this to the list\n if (!aggregateFacetGroup) return;\n\n // start with either the selected group if we have one, or the aggregate group\n const facetGroup = selectedFacetGroup ?? aggregateFacetGroup;\n\n // attach the counts to the selected buckets\n let bucketsWithCount =\n selectedFacetGroup?.buckets.map(bucket => {\n const selectedBucket = aggregateFacetGroup.buckets.find(\n b => b.key === bucket.key,\n );\n return selectedBucket\n ? {\n ...bucket,\n count: selectedBucket.count,\n }\n : bucket;\n }) ?? [];\n\n // append any additional buckets that were not selected\n aggregateFacetGroup.buckets.forEach(bucket => {\n const existingBucket = bucketsWithCount.find(b => b.key === bucket.key);\n if (existingBucket) return;\n bucketsWithCount.push(bucket);\n });\n\n /**\n * render limited facet items on page facet area\n *\n * - by-default we are showing 6 items\n * - additionally want to show all items (selected/suppressed) in page facet area\n */\n let allowedFacetCount = Object.keys(\n (selectedFacetGroup?.buckets as []) || [],\n )?.length;\n if (allowedFacetCount < this.allowedFacetCount) {\n allowedFacetCount = this.allowedFacetCount; // splice start index from 0th\n }\n\n // For lending facets, only include a specific subset of buckets\n if (facetKey === 'lending') {\n bucketsWithCount = bucketsWithCount.filter(\n bucket => lendingFacetKeysVisibility[bucket.key as LendingFacetKey],\n );\n }\n\n // Sort the FacetBuckets so that selected and hidden buckets come before the rest\n sortBucketsBySelectionState(bucketsWithCount);\n\n // For mediatype facets, ensure the collection bucket is always shown if present\n if (facetKey === 'mediatype') {\n const collectionIndex = bucketsWithCount.findIndex(\n bucket => bucket.key === 'collection',\n );\n\n if (collectionIndex >= allowedFacetCount) {\n const [collectionBucket] = bucketsWithCount.splice(\n collectionIndex,\n 1,\n );\n\n // If we're showing lots of selected facets, ensure we're not cutting off the last one\n if (allowedFacetCount > this.allowedFacetCount) {\n allowedFacetCount += 1;\n }\n\n bucketsWithCount.splice(allowedFacetCount - 1, 0, collectionBucket);\n }\n }\n\n // slice off how many items we want to show in page facet area\n facetGroup.buckets = bucketsWithCount.slice(0, allowedFacetCount);\n\n facetGroups.push(facetGroup);\n });\n\n return facetGroups;\n }\n\n /**\n * Converts the selected facets to a `FacetGroup` array,\n * which is easier to work with\n */\n private get selectedFacetGroups(): FacetGroup[] {\n if (!this.selectedFacets) return [];\n\n const facetGroups: FacetGroup[] = Object.entries(this.selectedFacets).map(\n ([key, selectedFacets]) => {\n const option = key as FacetOption;\n const title = facetTitles[option];\n\n const buckets: FacetBucket[] = Object.entries(selectedFacets).map(\n ([value, facetData]) => {\n let displayText: string = value;\n // for lending facets, convert the key to a readable format\n if (option === 'lending') {\n displayText =\n lendingFacetDisplayNames[value as LendingFacetKey] ?? value;\n }\n return {\n displayText,\n key: value,\n count: facetData.count,\n state: facetData.state,\n };\n },\n );\n\n return {\n title,\n key: option,\n buckets,\n };\n },\n );\n\n return facetGroups;\n }\n\n /**\n * Converts the raw `aggregations` to `FacetGroups`, which are easier to use\n */\n private get aggregationFacetGroups(): FacetGroup[] {\n const facetGroups: FacetGroup[] = [];\n Object.entries(this.aggregations ?? []).forEach(([key, aggregation]) => {\n // the year_histogram data is in a different format so can't be handled here\n if (key === 'year_histogram') return;\n\n const option = key as FacetOption;\n const title = facetTitles[option];\n if (!title) return;\n\n let castedBuckets = aggregation.getSortedBuckets(\n defaultFacetSort[option],\n ) as Bucket[];\n\n if (option === 'collection') {\n // we are not showing fav- collections or certain deemphasized collections in facets\n castedBuckets = castedBuckets?.filter(bucket => {\n const bucketKey = bucket?.key?.toString();\n return (\n !suppressedCollections[bucketKey] && !bucketKey?.startsWith('fav-')\n );\n });\n }\n\n const facetBuckets: FacetBucket[] = castedBuckets.map(bucket => {\n const bucketKey = bucket.key;\n let displayText = `${bucket.key}`;\n // for lending facets, convert the bucket key to a readable format\n if (option === 'lending') {\n displayText =\n lendingFacetDisplayNames[bucket.key as LendingFacetKey] ??\n `${bucket.key}`;\n }\n return {\n displayText,\n key: `${bucketKey}`,\n count: bucket.doc_count,\n state: 'none',\n };\n });\n const group: FacetGroup = {\n title,\n key: option,\n buckets: facetBuckets,\n };\n facetGroups.push(group);\n });\n return facetGroups;\n }\n\n /**\n * Generate the template for a facet group with a header and the collapsible\n * chevron for the mobile view\n */\n private getFacetGroupTemplate(\n facetGroup: FacetGroup,\n ): TemplateResult | typeof nothing {\n if (!this.facetsLoading && facetGroup.buckets.length === 0) return nothing;\n\n const { key } = facetGroup;\n const isOpen = this.openFacets[key];\n const collapser = html`\n <span class=\"collapser ${isOpen ? 'open' : ''}\"> ${chevronIcon} </span>\n `;\n\n const toggleCollapsed = () => {\n const newOpenFacets = { ...this.openFacets };\n newOpenFacets[key] = !isOpen;\n this.openFacets = newOpenFacets;\n };\n\n // Added data-testid for Playwright testing\n // Using className and aria-labels is not ideal for Playwright locator\n const headerId = `facet-group-header-label-${facetGroup.key}`;\n return html`\n <section\n class=\"facet-group ${this.collapsableFacets ? 'mobile' : ''}\"\n aria-labelledby=${headerId}\n data-testid=${headerId}\n >\n <div class=\"facet-group-header\">\n <h3\n id=${headerId}\n @click=${toggleCollapsed}\n @keyup=${toggleCollapsed}\n >\n ${this.collapsableFacets ? collapser : nothing} ${facetGroup.title}\n <span class=\"sr-only\">filters</span>\n </h3>\n </div>\n <div\n class=\"facet-group-content ${isOpen ? 'open' : ''}\"\n data-testid=\"facet-group-content-${facetGroup.key}\"\n >\n ${this.facetsLoading\n ? this.getTombstoneFacetGroupTemplate()\n : html`\n ${this.getFacetTemplate(facetGroup)}\n ${this.searchMoreFacetsLink(facetGroup)}\n `}\n </div>\n </section>\n `;\n }\n\n private getTombstoneFacetGroupTemplate(): TemplateResult {\n // Render five tombstone rows\n return html`\n ${map(\n Array(5).fill(null),\n () => html`<facet-tombstone-row></facet-tombstone-row>`,\n )}\n `;\n }\n\n /**\n * Generate the More... link button just below the facets group\n *\n * TODO: want to fire analytics?\n */\n private searchMoreFacetsLink(\n facetGroup: FacetGroup,\n ): TemplateResult | typeof nothing {\n // Don't render More... links for FTS searches\n if (!this.moreLinksVisible) {\n return nothing;\n }\n\n // Don't render More... links for lending facets\n if (facetGroup.key === 'lending') {\n return nothing;\n }\n\n // Don't render More... link if the number of facets < this.allowedFacetCount\n if (Object.keys(facetGroup.buckets).length < this.allowedFacetCount) {\n return nothing;\n }\n\n // We sort years in numeric order by default, rather than bucket count\n const facetSort = defaultFacetSort[facetGroup.key];\n\n // Added data-testid for Playwright testing\n // Using the className is not ideal for Playwright locator\n return html`<button\n class=\"more-link\"\n @click=${() => {\n this.showMoreFacetsModal(facetGroup, facetSort);\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.showMoreFacetsModal,\n label: facetGroup.key,\n });\n this.dispatchEvent(\n new CustomEvent('showMoreFacets', { detail: facetGroup.key }),\n );\n }}\n data-testid=\"more-link-btn\"\n >\n More...\n </button>`;\n }\n\n async showMoreFacetsModal(\n facetGroup: FacetGroup,\n sortedBy: AggregationSortType,\n ): Promise<void> {\n const customModalContent = html`\n <more-facets-content\n .analyticsHandler=${this.analyticsHandler}\n .facetKey=${facetGroup.key}\n .query=${this.query}\n .filterMap=${this.filterMap}\n .pageSpecifierParams=${this.pageSpecifierParams}\n .modalManager=${this.modalManager}\n .searchService=${this.searchService}\n .searchType=${this.searchType}\n .collectionTitles=${this.collectionTitles}\n .selectedFacets=${this.selectedFacets}\n .sortedBy=${sortedBy}\n @facetsChanged=${(e: CustomEvent) => {\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: e.detail,\n bubbles: true,\n composed: true,\n });\n this.dispatchEvent(event);\n }}\n >\n </more-facets-content>\n `;\n\n const config = new ModalConfig({\n bodyColor: '#fff',\n headerColor: '#194880',\n showHeaderLogo: false,\n closeOnBackdropClick: true, // TODO: want to fire analytics\n title: html`Select filters`,\n });\n this.modalManager?.classList.add('more-search-facets');\n this.modalManager?.showModal({\n config,\n customModalContent,\n userClosedModalCallback: () => {\n this.modalManager?.classList.remove('more-search-facets');\n },\n });\n }\n\n /**\n * Generate the list template for each bucket in a facet group\n */\n private getFacetTemplate(facetGroup: FacetGroup): TemplateResult {\n return html`\n <facets-template\n .collectionPagePath=${this.collectionPagePath}\n .facetGroup=${facetGroup}\n .selectedFacets=${this.selectedFacets}\n .collectionTitles=${this.collectionTitles}\n @facetClick=${(e: CustomEvent<FacetEventDetails>) => {\n this.selectedFacets = updateSelectedFacetBucket(\n this.selectedFacets,\n facetGroup.key,\n e.detail.bucket,\n true,\n );\n\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: this.selectedFacets,\n bubbles: true,\n composed: true,\n });\n this.dispatchEvent(event);\n }}\n ></facets-template>\n `;\n }\n\n static get styles() {\n return [\n srOnlyStyle,\n css`\n a:link {\n text-decoration: none;\n color: var(--ia-theme-link-color, #4b64ff);\n }\n a:link:hover {\n text-decoration: underline;\n }\n\n #container.loading {\n opacity: 0.5;\n }\n\n #container.managing {\n opacity: 0.3;\n }\n\n .histogram-loading-indicator {\n width: 100%;\n height: 2.25rem;\n margin-top: 1.75rem;\n font-size: 1.4rem;\n text-align: center;\n }\n\n .collapser {\n display: inline-block;\n cursor: pointer;\n width: 10px;\n height: 10px;\n }\n\n .collapser svg {\n transition: transform 0.2s ease-in-out;\n }\n\n .collapser.open svg {\n transform: rotate(90deg);\n }\n\n .facet-group:not(:last-child) {\n margin-bottom: 2rem;\n }\n\n .facet-group h3 {\n margin-bottom: 0.7rem;\n }\n\n .facet-group.mobile h3 {\n cursor: pointer;\n }\n\n .facet-group-header {\n display: flex;\n margin-bottom: 0.7rem;\n justify-content: space-between;\n border-bottom: 1px solid rgb(232, 232, 232);\n }\n\n .facet-group-content {\n transition: max-height 0.2s ease-in-out;\n }\n\n .facet-group.mobile .facet-group-content {\n max-height: 0;\n overflow: hidden;\n }\n\n .facet-group.mobile .facet-group-content.open {\n max-height: 2000px;\n }\n\n .partof-collections ul {\n list-style-type: none;\n padding: 0;\n font-size: 1.2rem;\n }\n\n h3 {\n font-size: 1.4rem;\n font-weight: 200\n padding-bottom: 3px;\n margin: 0;\n }\n\n .more-link {\n font-size: 1.2rem;\n text-decoration: none;\n padding: 0;\n background: inherit;\n border: 0;\n color: var(--ia-theme-link-color, #4b64ff);\n cursor: pointer;\n }\n\n #date-picker-label {\n display: flex;\n justify-content: space-between;\n }\n\n .expand-date-picker-btn {\n margin: 0;\n padding: 0;\n border: 0;\n appearance: none;\n background: none;\n cursor: pointer;\n }\n\n .expand-date-picker-btn > svg {\n width: 14px;\n height: 14px;\n }\n\n .sorting-icon {\n height: 15px;\n cursor: pointer;\n }\n `,\n ];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"collection-facets.js","sourceRoot":"","sources":["../../src/collection-facets.ts"],"names":[],"mappings":";AAAA,OAAO,EACL,GAAG,EACH,IAAI,EACJ,UAAU,EAEV,OAAO,GAER,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AASvD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,mCAAmC,CAAC;AAC3C,OAAO,EACL,WAAW,GAEZ,MAAM,gCAAgC,CAAC;AAKxC,OAAO,WAAW,MAAM,4BAA4B,CAAC;AACrD,OAAO,UAAU,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAKL,wBAAwB,EACxB,WAAW,EACX,wBAAwB,EACxB,0BAA0B,EAE1B,qBAAqB,EACrB,gBAAgB,GAEjB,MAAM,UAAU,CAAC;AAKlB,OAAO,yCAAyC,CAAC;AACjD,OAAO,qCAAqC,CAAC;AAC7C,OAAO,yCAAyC,CAAC;AACjD,OAAO,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAGtB,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,UAAU;IAAzC;;QAawB,qBAAgB,GAAG,IAAI,CAAC;QAExB,kBAAa,GAAG,KAAK,CAAC;QAEtB,+BAA0B,GAAG,KAAK,CAAC;QAInC,sBAAiB,GAAG,KAAK,CAAC;QAI1B,4BAAuB,GAAG,KAAK,CAAC;QAEhC,6BAAwB,GAAG,KAAK,CAAC;QAEjC,0BAAqB,GAAG,KAAK,CAAC;QAMhC,sBAAiB,GAAa,EAAE,CAAC;QAMhC,uBAAkB,GAAW,WAAW,CAAC;QAExC,iBAAY,GAAG,KAAK,CAAC;QAEvB,sBAAiB,GAC1C,wBAAwB,CAAC;QAoBlB,eAAU,GAAiC;YAClD,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,KAAK;YACjB,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,KAAK;SACf,CAAC;QAEF;;WAEG;QACK,sBAAiB,GAAG,CAAC,CAAC;QA8ItB,mCAA8B,GAAG,GAAS,EAAE;;YAClD,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC9D,CAAC,CAAC;QA0DF;;;;;WAKG;QACK,8BAAyB,GAAG,CAClC,CAGE,EACI,EAAE;YACR,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC;YACtC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,2BAA2B,EAAE;gBACzD,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;aAC7B,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC,CAAC;IA8fJ,CAAC;IAvtBC,MAAM;QACJ,MAAM,gBAAgB,GAAG,QAAQ,CAAC;YAChC,OAAO,EAAE,IAAI,CAAC,aAAa;YAC3B,QAAQ,EAAE,IAAI,CAAC,YAAY;SAC5B,CAAC,CAAC;QAEH,2CAA2C;QAC3C,8EAA8E;QAC9E,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;QAC9C,OAAO,IAAI,CAAA;kCACmB,gBAAgB;UACxC,IAAI,CAAC,uBAAuB;YAC9B,CAAC,IAAI,CAAC,6BAA6B,IAAI,IAAI,CAAC,0BAA0B,CAAC;YACrE,CAAC,CAAC,IAAI,CAAA;;;kCAGkB,iBAAiB;;;yBAG1B,iBAAiB;;oBAEtB,IAAI,CAAC,2BAA2B;;kBAElC,IAAI,CAAC,iBAAiB;;aAE3B;YACH,CAAC,CAAC,OAAO;UACT,IAAI,CAAC,wBAAwB;UAC7B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CACnC,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CACvC;;KAEJ,CAAC;IACJ,CAAC;IAED,IAAY,wBAAwB;;QAClC,4DAA4D;QAC5D,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,iBAAiB,0CAAE,MAAM,CAAA;YAAE,OAAO,OAAO,CAAC;QAEpD,2CAA2C;QAC3C,sEAAsE;QACtE,MAAM,SAAS,GAAG,gBAAgB,CAAC;QACnC,OAAO,IAAI,CAAA;;;0BAGW,SAAS;;;;mBAIhB,SAAS,IAAI,GAAG,CAAC,SAAS,CAAC;;;YAGlC,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,EAAE;;YACrC,MAAM,aAAa,GAAG,GAAG,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,GAAG,MAAM,EAAE,CAAC;YAErF,OAAO,IAAI,CAAA;;uBAEA,aAAa;0BACV,MAAM;yBACP,IAAI,CAAC,uBAAuB;;kBAEnC,MAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,GAAG,CAAC,MAAM,CAAC,mCAAI,MAAM;;kBAE5C,CAAC;QACT,CAAC,CAAC;;;KAGP,CAAC;IACJ,CAAC;IAEO,uBAAuB,CAAC,CAAQ;;QACtC,MAAA,IAAI,CAAC,gBAAgB,0CAAE,SAAS,CAAC;YAC/B,QAAQ,EAAE,mBAAmB,CAAC,OAAO;YACrC,MAAM,EAAE,gBAAgB,CAAC,uBAAuB;YAChD,KAAK,EAAG,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,mBAAmB;;QACzB,MAAM,EAAE,6BAA6B,EAAE,GAAG,IAAI,CAAC;QAC/C,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,gBAAgB,CAAC;QAChE,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,eAAe,CAAC;QAC/D,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,OAAmB,CAAC;QAEnE,+EAA+E;QAC/E,gFAAgF;QAChF,kFAAkF;QAClF,qFAAqF;QACrF,yDAAyD;QACzD,qFAAqF;QACrF,iFAAiF;QACjF,8CAA8C;QAC9C,MAAM,yBAAyB,GAAG,CAAC,IAAc,EAAE,EAAE;YACnD,IAAI,IAAI,IAAI,IAAI,YAAY,kBAAkB,EAAE,CAAC;gBAC/C,MAAM,kBAAkB,GAAG,IAA0B,CAAC;gBACtD,kBAAkB,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;gBAC1D,kBAAkB,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;YAC5D,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,kBAAkB,GAAG,IAAI,CAAA;;UAEzB,GAAG,CAAC,yBAAyB,CAAC;mBACrB,OAAO;mBACP,OAAO;2BACC,IAAI,CAAC,eAAe;2BACpB,IAAI,CAAC,eAAe;mBAC5B,OAAO;wBACF,IAAI,CAAC,YAAY;4BACb,IAAI,CAAC,gBAAgB;qCACZ,IAAI,CAAC,yBAAyB;uBAC5C,IAAI,CAAC,8BAA8B;;KAErD,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC;YAC7B,SAAS,EAAE,MAAM;YACjB,WAAW,EAAE,SAAS;YACtB,cAAc,EAAE,KAAK;YACrB,oBAAoB,EAAE,IAAI,EAAE,+BAA+B;YAC3D,KAAK,EAAE,IAAI,CAAA,qBAAqB;SACjC,CAAC,CAAC;QAEH,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACzD,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC;YAC3B,MAAM;YACN,kBAAkB;YAClB,uBAAuB,EAAE,IAAI,CAAC,8BAA8B;SAC7D,CAAC,CAAC;QAEH,MAAA,IAAI,CAAC,gBAAgB,0CAAE,SAAS,CAAC;YAC/B,QAAQ,EAAE,mBAAmB,CAAC,OAAO;YACrC,MAAM,EAAE,gBAAgB,CAAC,iBAAiB;YAC1C,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;SAC5B,CAAC,CAAC;IACL,CAAC;IAMD,OAAO,CAAC,OAAuB;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;IAED,gCAAgC;IACxB,0BAA0B;QAChC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAiB,eAAe,EAAE;YAC7D,MAAM,EAAE,IAAI,CAAC,cAAc;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,IAAY,2BAA2B;QACrC,OAAO,IAAI,CAAC,wBAAwB,IAAI,CAAC,IAAI,CAAC,aAAa;YACzD,CAAC,CAAC,IAAI,CAAA;;;mBAGO,IAAI,CAAC,mBAAmB;;YAE/B,UAAU;kBACJ;YACZ,CAAC,CAAC,OAAO,CAAC;IACd,CAAC;IAED,IAAY,iBAAiB;;QAC3B,MAAM,EAAE,6BAA6B,EAAE,GAAG,IAAI,CAAC;QAC/C,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,gBAAgB,CAAC;QAChE,MAAM,OAAO,GAAG,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,eAAe,CAAC;QAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QACnE,OAAO,IAAI,CAAC,0BAA0B;YACpC,CAAC,CAAC,IAAI,CAAA,yDAAyD,CAAC,iBAAiB;YACjF,CAAC,CAAC,IAAI,CAAA;;oBAEQ,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO;uBACjD,OAAO;uBACP,OAAO;+BACC,MAAA,IAAI,CAAC,eAAe,mCAAI,OAAO;+BAC/B,MAAA,IAAI,CAAC,eAAe,mCAAI,OAAO;2BACnC,GAAG;0BACJ,UAAU;;qBAEf,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,YAAY;gBAClD,CAAC,CAAC,IAAI,CAAC,YAAY;gBACnB,CAAC,CAAC,GAAG;oBACC,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,OAAmB;yCAC7B,IAAI,CAAC,yBAAyB;;SAE9D,CAAC;IACR,CAAC;IAqBD;;OAEG;IACH,IAAY,YAAY;QACtB,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;;YACxC,MAAM,kBAAkB,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CACtD,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,QAAQ,CAChC,CAAC;YACF,MAAM,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAC1D,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,QAAQ,CAChC,CAAC;YAEF,iFAAiF;YACjF,IAAI,kBAAkB,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC/C,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YAED,wEAAwE;YACxE,IAAI,CAAC,mBAAmB;gBAAE,OAAO;YAEjC,8EAA8E;YAC9E,MAAM,UAAU,GAAG,kBAAkB,aAAlB,kBAAkB,cAAlB,kBAAkB,GAAI,mBAAmB,CAAC;YAE7D,4CAA4C;YAC5C,IAAI,gBAAgB,GAClB,MAAA,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;gBACvC,MAAM,cAAc,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,CACrD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAC1B,CAAC;gBACF,OAAO,cAAc;oBACnB,CAAC,CAAC;wBACE,GAAG,MAAM;wBACT,KAAK,EAAE,cAAc,CAAC,KAAK;qBAC5B;oBACH,CAAC,CAAC,MAAM,CAAC;YACb,CAAC,CAAC,mCAAI,EAAE,CAAC;YAEX,uDAAuD;YACvD,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBAC3C,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC;gBACxE,IAAI,cAAc;oBAAE,OAAO;gBAC3B,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;YAEH;;;;;eAKG;YACH,IAAI,iBAAiB,GAAG,MAAA,MAAM,CAAC,IAAI,CACjC,CAAC,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,OAAc,KAAI,EAAE,CAC1C,0CAAE,MAAM,CAAC;YACV,IAAI,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC/C,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,8BAA8B;YAC5E,CAAC;YAED,gEAAgE;YAChE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,gBAAgB,GAAG,gBAAgB,CAAC,MAAM,CACxC,MAAM,CAAC,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,GAAsB,CAAC,CACpE,CAAC;YACJ,CAAC;YAED,iFAAiF;YACjF,2BAA2B,CAAC,gBAAgB,CAAC,CAAC;YAE9C,gFAAgF;YAChF,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;gBAC7B,MAAM,eAAe,GAAG,gBAAgB,CAAC,SAAS,CAChD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,KAAK,YAAY,CACtC,CAAC;gBAEF,IAAI,eAAe,IAAI,iBAAiB,EAAE,CAAC;oBACzC,MAAM,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC,MAAM,CAChD,eAAe,EACf,CAAC,CACF,CAAC;oBAEF,sFAAsF;oBACtF,IAAI,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBAC/C,iBAAiB,IAAI,CAAC,CAAC;oBACzB,CAAC;oBAED,gBAAgB,CAAC,MAAM,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;YAED,8DAA8D;YAC9D,UAAU,CAAC,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;YAElE,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,IAAY,mBAAmB;QAC7B,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,EAAE,CAAC;QAEpC,MAAM,WAAW,GAAiB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,CACvE,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,GAAkB,CAAC;YAClC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;YAElC,MAAM,OAAO,GAAkB,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,GAAG,CAC/D,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE;;gBACrB,IAAI,WAAW,GAAW,KAAK,CAAC;gBAChC,2DAA2D;gBAC3D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,WAAW;wBACT,MAAA,wBAAwB,CAAC,KAAwB,CAAC,mCAAI,KAAK,CAAC;gBAChE,CAAC;gBACD,OAAO;oBACL,WAAW;oBACX,GAAG,EAAE,KAAK;oBACV,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,KAAK,EAAE,SAAS,CAAC,KAAK;iBACvB,CAAC;YACJ,CAAC,CACF,CAAC;YAEF,OAAO;gBACL,KAAK;gBACL,GAAG,EAAE,MAAM;gBACX,OAAO;aACR,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAY,sBAAsB;;QAChC,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,MAAA,IAAI,CAAC,YAAY,mCAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE;YACrE,4EAA4E;YAC5E,IAAI,GAAG,KAAK,gBAAgB;gBAAE,OAAO;YAErC,MAAM,MAAM,GAAG,GAAkB,CAAC;YAClC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC,KAAK;gBAAE,OAAO;YAEnB,IAAI,aAAa,GAAG,WAAW,CAAC,gBAAgB,CAC9C,gBAAgB,CAAC,MAAM,CAAC,CACb,CAAC;YAEd,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;gBAC5B,oFAAoF;gBACpF,aAAa,GAAG,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,CAAC,MAAM,CAAC,EAAE;;oBAC7C,MAAM,SAAS,GAAG,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,GAAG,0CAAE,QAAQ,EAAE,CAAC;oBAC1C,OAAO,CACL,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,UAAU,CAAC,MAAM,CAAC,CAAA,CACpE,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,YAAY,GAAkB,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;;gBAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC;gBAC7B,IAAI,WAAW,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;gBAClC,kEAAkE;gBAClE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,WAAW;wBACT,MAAA,wBAAwB,CAAC,MAAM,CAAC,GAAsB,CAAC,mCACvD,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;gBACpB,CAAC;gBACD,OAAO;oBACL,WAAW;oBACX,GAAG,EAAE,GAAG,SAAS,EAAE;oBACnB,KAAK,EAAE,MAAM,CAAC,SAAS;oBACvB,KAAK,EAAE,MAAM;iBACd,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,MAAM,KAAK,GAAe;gBACxB,KAAK;gBACL,GAAG,EAAE,MAAM;gBACX,OAAO,EAAE,YAAY;aACtB,CAAC;YACF,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,qBAAqB,CAC3B,UAAsB;QAEtB,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC;QAE3E,MAAM,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAA;+BACK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,WAAW;KAC/D,CAAC;QAEF,MAAM,eAAe,GAAG,GAAG,EAAE;YAC3B,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC7C,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;YAC7B,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC;QAClC,CAAC,CAAC;QAEF,2CAA2C;QAC3C,sEAAsE;QACtE,MAAM,QAAQ,GAAG,4BAA4B,UAAU,CAAC,GAAG,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAA;;6BAEc,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;0BACzC,QAAQ;sBACZ,QAAQ;;;;iBAIb,QAAQ;qBACJ,eAAe;qBACf,eAAe;;cAEtB,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,UAAU,CAAC,KAAK;;;;;uCAKvC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;6CACd,UAAU,CAAC,GAAG;;YAE/C,IAAI,CAAC,aAAa;YAClB,CAAC,CAAC,IAAI,CAAC,8BAA8B,EAAE;YACvC,CAAC,CAAC,IAAI,CAAA;kBACA,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;kBACjC,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC;eACxC;;;KAGV,CAAC;IACJ,CAAC;IAEO,8BAA8B;QACpC,6BAA6B;QAC7B,OAAO,IAAI,CAAA;QACP,GAAG,CACH,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EACnB,GAAG,EAAE,CAAC,IAAI,CAAA,6CAA6C,CACxD;KACF,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,oBAAoB,CAC1B,UAAsB;QAEtB,8CAA8C;QAC9C,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,gDAAgD;QAChD,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,6EAA6E;QAC7E,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACpE,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,sEAAsE;QACtE,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAEnD,2CAA2C;QAC3C,0DAA0D;QAC1D,OAAO,IAAI,CAAA;;eAEA,GAAG,EAAE;;YACZ,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YAChD,MAAA,IAAI,CAAC,gBAAgB,0CAAE,SAAS,CAAC;gBAC/B,QAAQ,EAAE,mBAAmB,CAAC,OAAO;gBACrC,MAAM,EAAE,gBAAgB,CAAC,mBAAmB;gBAC5C,KAAK,EAAE,UAAU,CAAC,GAAG;aACtB,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC,CAC9D,CAAC;QACJ,CAAC;;;;cAIO,CAAC;IACb,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,UAAsB,EACtB,QAA6B;;QAE7B,MAAM,kBAAkB,GAAG,IAAI,CAAA;;4BAEP,IAAI,CAAC,gBAAgB;oBAC7B,UAAU,CAAC,GAAG;iBACjB,IAAI,CAAC,KAAK;qBACN,IAAI,CAAC,SAAS;+BACJ,IAAI,CAAC,mBAAmB;wBAC/B,IAAI,CAAC,YAAY;yBAChB,IAAI,CAAC,aAAa;sBACrB,IAAI,CAAC,UAAU;4BACT,IAAI,CAAC,gBAAgB;0BACvB,IAAI,CAAC,cAAc;oBACzB,QAAQ;yBACH,CAAC,CAAc,EAAE,EAAE;YAClC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAiB,eAAe,EAAE;gBAC7D,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;;;KAGJ,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC;YAC7B,SAAS,EAAE,MAAM;YACjB,WAAW,EAAE,SAAS;YACtB,cAAc,EAAE,KAAK;YACrB,oBAAoB,EAAE,IAAI,EAAE,+BAA+B;YAC3D,KAAK,EAAE,IAAI,CAAA,gBAAgB;SAC5B,CAAC,CAAC;QACH,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACvD,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC;YAC3B,MAAM;YACN,kBAAkB;YAClB,uBAAuB,EAAE,GAAG,EAAE;;gBAC5B,MAAA,IAAI,CAAC,YAAY,0CAAE,SAAS,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAC5D,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,UAAsB;QAC7C,OAAO,IAAI,CAAA;;8BAEe,IAAI,CAAC,kBAAkB;sBAC/B,UAAU;0BACN,IAAI,CAAC,cAAc;4BACjB,IAAI,CAAC,gBAAgB;sBAC3B,CAAC,CAAiC,EAAE,EAAE;YAClD,IAAI,CAAC,cAAc,GAAG,yBAAyB,CAC7C,IAAI,CAAC,cAAc,EACnB,UAAU,CAAC,GAAG,EACd,CAAC,CAAC,MAAM,CAAC,MAAM,EACf,IAAI,CACL,CAAC;YAEF,MAAM,KAAK,GAAG,IAAI,WAAW,CAAiB,eAAe,EAAE;gBAC7D,MAAM,EAAE,IAAI,CAAC,cAAc;gBAC3B,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;;KAEJ,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,MAAM;QACf,OAAO;YACL,WAAW;YACX,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0HF;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AA1yB6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uDAAwC;AAEvC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oDAAyB;AAExB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAA4C;AAE3C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uEAA6C;AAE5C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yDAA0B;AAEzB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yDAA0B;AAExB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;0DAAyB;AAExB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;uDAAuB;AAEtB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;oEAAoC;AAEpC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wDAAiC;AAE/B;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;2DAA2B;AAE3B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAAuB;AAErB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;iEAAiC;AAEhC;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;kEAAkC;AAEjC;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;+DAA+B;AAE/B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAgB;AAEf;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6DAA2C;AAE3C;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;2DAAkC;AAEhC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;mDAAuB;AAEtB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2DAA4B;AAE3B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4DAA0C;AAExC;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;sDAAsB;AAEvB;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;2DACC;AAG3B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;sDACR;AAGrC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;wDACE;AAG/C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;gEACY;AAGzD;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0DACA;AAG7C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0DACA;AAG7C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0DACT;AAE3B;IAAR,KAAK,EAAE;oDAWN;AA7ES,gBAAgB;IAD5B,aAAa,CAAC,mBAAmB,CAAC;GACtB,gBAAgB,CA2yB5B","sourcesContent":["import {\n css,\n html,\n LitElement,\n PropertyValues,\n nothing,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { map } from 'lit/directives/map.js';\nimport { ref } from 'lit/directives/ref.js';\nimport { msg } from '@lit/localize';\nimport { classMap } from 'lit/directives/class-map.js';\nimport {\n Aggregation,\n AggregationSortType,\n Bucket,\n FilterMap,\n SearchServiceInterface,\n SearchType,\n} from '@internetarchive/search-service';\nimport '@internetarchive/histogram-date-range';\nimport '@internetarchive/feature-feedback';\nimport {\n ModalConfig,\n ModalManagerInterface,\n} from '@internetarchive/modal-manager';\nimport type { FeatureFeedbackServiceInterface } from '@internetarchive/feature-feedback';\nimport type { RecaptchaManagerInterface } from '@internetarchive/recaptcha-manager';\nimport type { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';\nimport type { SharedResizeObserverInterface } from '@internetarchive/shared-resize-observer';\nimport chevronIcon from './assets/img/icons/chevron';\nimport expandIcon from './assets/img/icons/expand';\nimport {\n FacetOption,\n SelectedFacets,\n FacetGroup,\n FacetBucket,\n defaultFacetDisplayOrder,\n facetTitles,\n lendingFacetDisplayNames,\n lendingFacetKeysVisibility,\n LendingFacetKey,\n suppressedCollections,\n defaultFacetSort,\n FacetEventDetails,\n} from './models';\nimport type {\n CollectionTitles,\n PageSpecifierParams,\n} from './data-source/models';\nimport './collection-facets/more-facets-content';\nimport './collection-facets/facets-template';\nimport './collection-facets/facet-tombstone-row';\nimport './expanded-date-picker';\nimport {\n analyticsActions,\n analyticsCategories,\n} from './utils/analytics-events';\nimport { srOnlyStyle } from './styles/sr-only';\nimport { ExpandedDatePicker } from './expanded-date-picker';\nimport {\n sortBucketsBySelectionState,\n updateSelectedFacetBucket,\n} from './utils/facet-utils';\n\n@customElement('collection-facets')\nexport class CollectionFacets extends LitElement {\n @property({ type: Object }) searchService?: SearchServiceInterface;\n\n @property({ type: Number }) searchType?: SearchType;\n\n @property({ type: Object }) aggregations?: Record<string, Aggregation>;\n\n @property({ type: Object }) fullYearsHistogramAggregation?: Aggregation;\n\n @property({ type: String }) minSelectedDate?: string;\n\n @property({ type: String }) maxSelectedDate?: string;\n\n @property({ type: Boolean }) moreLinksVisible = true;\n\n @property({ type: Boolean }) facetsLoading = false;\n\n @property({ type: Boolean }) fullYearAggregationLoading = false;\n\n @property({ type: Object }) selectedFacets?: SelectedFacets;\n\n @property({ type: Boolean }) collapsableFacets = false;\n\n @property({ type: Number }) contentWidth?: number;\n\n @property({ type: Boolean }) showHistogramDatePicker = false;\n\n @property({ type: Boolean }) allowExpandingDatePicker = false;\n\n @property({ type: Boolean }) allowDatePickerMonths = false;\n\n @property({ type: String }) query?: string;\n\n @property({ type: Object }) pageSpecifierParams?: PageSpecifierParams;\n\n @property({ type: Array }) parentCollections: string[] = [];\n\n @property({ type: Object }) filterMap?: FilterMap;\n\n @property({ type: String }) baseNavigationUrl?: string;\n\n @property({ type: String }) collectionPagePath: string = '/details/';\n\n @property({ type: Boolean }) isManageView = false;\n\n @property({ type: Array }) facetDisplayOrder: FacetOption[] =\n defaultFacetDisplayOrder;\n\n @property({ type: Object, attribute: false })\n modalManager?: ModalManagerInterface;\n\n @property({ type: Object, attribute: false })\n resizeObserver?: SharedResizeObserverInterface;\n\n @property({ type: Object, attribute: false })\n featureFeedbackService?: FeatureFeedbackServiceInterface;\n\n @property({ type: Object, attribute: false })\n recaptchaManager?: RecaptchaManagerInterface;\n\n @property({ type: Object, attribute: false })\n analyticsHandler?: AnalyticsManagerInterface;\n\n @property({ type: Object, attribute: false })\n collectionTitles?: CollectionTitles;\n\n @state() openFacets: Record<FacetOption, boolean> = {\n subject: false,\n lending: false,\n mediatype: false,\n language: false,\n creator: false,\n collection: false,\n year: false,\n program: false,\n person: false,\n sponsor: false,\n };\n\n /**\n * Maximum # of facet buckets to render per facet group\n */\n private allowedFacetCount = 6;\n\n render() {\n const containerClasses = classMap({\n loading: this.facetsLoading,\n managing: this.isManageView,\n });\n\n // Added data-testid for Playwright testing\n // Using facet-group class and aria-labels is not ideal for Playwright locator\n const datePickerLabelId = 'date-picker-label';\n return html`\n <div id=\"container\" class=${containerClasses}>\n ${this.showHistogramDatePicker &&\n (this.fullYearsHistogramAggregation || this.fullYearAggregationLoading)\n ? html`\n <section\n class=\"facet-group\"\n aria-labelledby=${datePickerLabelId}\n data-testid=\"facet-group-header-label-date-picker\"\n >\n <h3 id=${datePickerLabelId}>\n Year Published <span class=\"sr-only\">range filter</span>\n ${this.expandDatePickerBtnTemplate}\n </h3>\n ${this.histogramTemplate}\n </section>\n `\n : nothing}\n ${this.collectionPartOfTemplate}\n ${this.mergedFacets.map(facetGroup =>\n this.getFacetGroupTemplate(facetGroup),\n )}\n </div>\n `;\n }\n\n private get collectionPartOfTemplate(): TemplateResult | typeof nothing {\n // We only display the \"Part Of\" section on collection pages\n if (!this.parentCollections?.length) return nothing;\n\n // Added data-testid for Playwright testing\n // Using className and aria-labels is not ideal for Playwright locator\n const headingId = 'partof-heading';\n return html`\n <section\n class=\"facet-group partof-collections\"\n aria-labelledby=${headingId}\n data-testid=\"facet-group-partof-collections\"\n >\n <div class=\"facet-group-header\">\n <h3 id=${headingId}>${msg('Part Of')}</h3>\n </div>\n <ul>\n ${map(this.parentCollections, collxn => {\n const collectionURL = `${this.baseNavigationUrl}${this.collectionPagePath}${collxn}`;\n\n return html` <li>\n <a\n href=${collectionURL}\n data-id=${collxn}\n @click=${this.partOfCollectionClicked}\n >\n ${this.collectionTitles?.get(collxn) ?? collxn}\n </a>\n </li>`;\n })}\n </ul>\n </section>\n `;\n }\n\n private partOfCollectionClicked(e: Event): void {\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.partOfCollectionClicked,\n label: (e.target as HTMLElement).dataset.id,\n });\n }\n\n /**\n * Opens a modal dialog containing an enlarged version of the date picker.\n */\n private showDatePickerModal(): void {\n const { fullYearsHistogramAggregation } = this;\n const minDate = fullYearsHistogramAggregation?.first_bucket_key;\n const maxDate = fullYearsHistogramAggregation?.last_bucket_key;\n const buckets = fullYearsHistogramAggregation?.buckets as number[];\n\n // Because the modal manager does not clear its DOM content after being closed,\n // it may try to render the exact same date picker template when it is reopened.\n // And because it isn't actually a descendent of this collection-facets component,\n // changes to the template defined here may not trigger a reactive update to the date\n // picker, resulting in it displaying a stale date range.\n // This ref callback ensures that every time the date picker modal is opened, it will\n // always propagate the most recent date range into the date picker regardless of\n // whether Lit thinks the update is necessary.\n const expandedDatePickerChanged = (elmt?: Element) => {\n if (elmt && elmt instanceof ExpandedDatePicker) {\n const expandedDatePicker = elmt as ExpandedDatePicker;\n expandedDatePicker.minSelectedDate = this.minSelectedDate;\n expandedDatePicker.maxSelectedDate = this.maxSelectedDate;\n }\n };\n\n const customModalContent = html`\n <expanded-date-picker\n ${ref(expandedDatePickerChanged)}\n .minDate=${minDate}\n .maxDate=${maxDate}\n .minSelectedDate=${this.minSelectedDate}\n .maxSelectedDate=${this.maxSelectedDate}\n .buckets=${buckets}\n .modalManager=${this.modalManager}\n .analyticsHandler=${this.analyticsHandler}\n @histogramDateRangeApplied=${this.histogramDateRangeUpdated}\n @modalClosed=${this.handleExpandedDatePickerClosed}\n ></expanded-date-picker>\n `;\n\n const config = new ModalConfig({\n bodyColor: '#fff',\n headerColor: '#194880',\n showHeaderLogo: false,\n closeOnBackdropClick: true, // TODO: want to fire analytics\n title: html`Select a date range`,\n });\n\n this.modalManager?.classList.add('expanded-date-picker');\n this.modalManager?.showModal({\n config,\n customModalContent,\n userClosedModalCallback: this.handleExpandedDatePickerClosed,\n });\n\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.histogramExpanded,\n label: window.location.href,\n });\n }\n\n private handleExpandedDatePickerClosed = (): void => {\n this.modalManager?.classList.remove('expanded-date-picker');\n };\n\n updated(changed: PropertyValues) {\n if (changed.has('selectedFacets')) {\n this.dispatchFacetsChangedEvent();\n }\n }\n\n // TODO: want to fire analytics?\n private dispatchFacetsChangedEvent() {\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: this.selectedFacets,\n });\n this.dispatchEvent(event);\n }\n\n /**\n * Template for the \"Expand\" button to show the date picker modal, or\n * `nothing` if that button should currently not be shown.\n */\n private get expandDatePickerBtnTemplate(): TemplateResult | typeof nothing {\n return this.allowExpandingDatePicker && !this.facetsLoading\n ? html`<button\n class=\"expand-date-picker-btn\"\n aria-hidden=\"true\"\n @click=${this.showDatePickerModal}\n >\n ${expandIcon}\n </button>`\n : nothing;\n }\n\n private get histogramTemplate() {\n const { fullYearsHistogramAggregation } = this;\n const minDate = fullYearsHistogramAggregation?.first_bucket_key;\n const maxDate = fullYearsHistogramAggregation?.last_bucket_key;\n const dateFormat = this.allowDatePickerMonths ? 'YYYY-MM' : 'YYYY';\n return this.fullYearAggregationLoading\n ? html`<div class=\"histogram-loading-indicator\">…</div>` // Ellipsis block\n : html`\n <histogram-date-range\n class=${this.allowDatePickerMonths ? 'wide-inputs' : nothing}\n .minDate=${minDate}\n .maxDate=${maxDate}\n .minSelectedDate=${this.minSelectedDate ?? minDate}\n .maxSelectedDate=${this.maxSelectedDate ?? maxDate}\n .updateDelay=${100}\n .dateFormat=${dateFormat}\n missingDataMessage=\"...\"\n .width=${this.collapsableFacets && this.contentWidth\n ? this.contentWidth\n : 180}\n .bins=${fullYearsHistogramAggregation?.buckets as number[]}\n @histogramDateRangeUpdated=${this.histogramDateRangeUpdated}\n ></histogram-date-range>\n `;\n }\n\n /**\n * Dispatches a `histogramDateRangeUpdated` event with the date range copied from the\n * input event.\n *\n * Arrow function to ensure `this` is always bound to the current component.\n */\n private histogramDateRangeUpdated = (\n e: CustomEvent<{\n minDate: string;\n maxDate: string;\n }>,\n ): void => {\n const { minDate, maxDate } = e.detail;\n const event = new CustomEvent('histogramDateRangeUpdated', {\n detail: { minDate, maxDate },\n });\n this.dispatchEvent(event);\n };\n\n /**\n * Combines the selected facets with the aggregations to create a single list of facets\n */\n private get mergedFacets(): FacetGroup[] {\n const facetGroups: FacetGroup[] = [];\n\n this.facetDisplayOrder.forEach(facetKey => {\n const selectedFacetGroup = this.selectedFacetGroups.find(\n group => group.key === facetKey,\n );\n const aggregateFacetGroup = this.aggregationFacetGroups.find(\n group => group.key === facetKey,\n );\n\n // if the user selected a facet, but it's not in the aggregation, we add it as-is\n if (selectedFacetGroup && !aggregateFacetGroup) {\n facetGroups.push(selectedFacetGroup);\n return;\n }\n\n // if we don't have an aggregate facet group, don't add this to the list\n if (!aggregateFacetGroup) return;\n\n // start with either the selected group if we have one, or the aggregate group\n const facetGroup = selectedFacetGroup ?? aggregateFacetGroup;\n\n // attach the counts to the selected buckets\n let bucketsWithCount =\n selectedFacetGroup?.buckets.map(bucket => {\n const selectedBucket = aggregateFacetGroup.buckets.find(\n b => b.key === bucket.key,\n );\n return selectedBucket\n ? {\n ...bucket,\n count: selectedBucket.count,\n }\n : bucket;\n }) ?? [];\n\n // append any additional buckets that were not selected\n aggregateFacetGroup.buckets.forEach(bucket => {\n const existingBucket = bucketsWithCount.find(b => b.key === bucket.key);\n if (existingBucket) return;\n bucketsWithCount.push(bucket);\n });\n\n /**\n * render limited facet items on page facet area\n *\n * - by-default we are showing 6 items\n * - additionally want to show all items (selected/suppressed) in page facet area\n */\n let allowedFacetCount = Object.keys(\n (selectedFacetGroup?.buckets as []) || [],\n )?.length;\n if (allowedFacetCount < this.allowedFacetCount) {\n allowedFacetCount = this.allowedFacetCount; // splice start index from 0th\n }\n\n // For lending facets, only include a specific subset of buckets\n if (facetKey === 'lending') {\n bucketsWithCount = bucketsWithCount.filter(\n bucket => lendingFacetKeysVisibility[bucket.key as LendingFacetKey],\n );\n }\n\n // Sort the FacetBuckets so that selected and hidden buckets come before the rest\n sortBucketsBySelectionState(bucketsWithCount);\n\n // For mediatype facets, ensure the collection bucket is always shown if present\n if (facetKey === 'mediatype') {\n const collectionIndex = bucketsWithCount.findIndex(\n bucket => bucket.key === 'collection',\n );\n\n if (collectionIndex >= allowedFacetCount) {\n const [collectionBucket] = bucketsWithCount.splice(\n collectionIndex,\n 1,\n );\n\n // If we're showing lots of selected facets, ensure we're not cutting off the last one\n if (allowedFacetCount > this.allowedFacetCount) {\n allowedFacetCount += 1;\n }\n\n bucketsWithCount.splice(allowedFacetCount - 1, 0, collectionBucket);\n }\n }\n\n // slice off how many items we want to show in page facet area\n facetGroup.buckets = bucketsWithCount.slice(0, allowedFacetCount);\n\n facetGroups.push(facetGroup);\n });\n\n return facetGroups;\n }\n\n /**\n * Converts the selected facets to a `FacetGroup` array,\n * which is easier to work with\n */\n private get selectedFacetGroups(): FacetGroup[] {\n if (!this.selectedFacets) return [];\n\n const facetGroups: FacetGroup[] = Object.entries(this.selectedFacets).map(\n ([key, selectedFacets]) => {\n const option = key as FacetOption;\n const title = facetTitles[option];\n\n const buckets: FacetBucket[] = Object.entries(selectedFacets).map(\n ([value, facetData]) => {\n let displayText: string = value;\n // for lending facets, convert the key to a readable format\n if (option === 'lending') {\n displayText =\n lendingFacetDisplayNames[value as LendingFacetKey] ?? value;\n }\n return {\n displayText,\n key: value,\n count: facetData.count,\n state: facetData.state,\n };\n },\n );\n\n return {\n title,\n key: option,\n buckets,\n };\n },\n );\n\n return facetGroups;\n }\n\n /**\n * Converts the raw `aggregations` to `FacetGroups`, which are easier to use\n */\n private get aggregationFacetGroups(): FacetGroup[] {\n const facetGroups: FacetGroup[] = [];\n Object.entries(this.aggregations ?? []).forEach(([key, aggregation]) => {\n // the year_histogram data is in a different format so can't be handled here\n if (key === 'year_histogram') return;\n\n const option = key as FacetOption;\n const title = facetTitles[option];\n if (!title) return;\n\n let castedBuckets = aggregation.getSortedBuckets(\n defaultFacetSort[option],\n ) as Bucket[];\n\n if (option === 'collection') {\n // we are not showing fav- collections or certain deemphasized collections in facets\n castedBuckets = castedBuckets?.filter(bucket => {\n const bucketKey = bucket?.key?.toString();\n return (\n !suppressedCollections[bucketKey] && !bucketKey?.startsWith('fav-')\n );\n });\n }\n\n const facetBuckets: FacetBucket[] = castedBuckets.map(bucket => {\n const bucketKey = bucket.key;\n let displayText = `${bucket.key}`;\n // for lending facets, convert the bucket key to a readable format\n if (option === 'lending') {\n displayText =\n lendingFacetDisplayNames[bucket.key as LendingFacetKey] ??\n `${bucket.key}`;\n }\n return {\n displayText,\n key: `${bucketKey}`,\n count: bucket.doc_count,\n state: 'none',\n };\n });\n const group: FacetGroup = {\n title,\n key: option,\n buckets: facetBuckets,\n };\n facetGroups.push(group);\n });\n return facetGroups;\n }\n\n /**\n * Generate the template for a facet group with a header and the collapsible\n * chevron for the mobile view\n */\n private getFacetGroupTemplate(\n facetGroup: FacetGroup,\n ): TemplateResult | typeof nothing {\n if (!this.facetsLoading && facetGroup.buckets.length === 0) return nothing;\n\n const { key } = facetGroup;\n const isOpen = this.openFacets[key];\n const collapser = html`\n <span class=\"collapser ${isOpen ? 'open' : ''}\"> ${chevronIcon} </span>\n `;\n\n const toggleCollapsed = () => {\n const newOpenFacets = { ...this.openFacets };\n newOpenFacets[key] = !isOpen;\n this.openFacets = newOpenFacets;\n };\n\n // Added data-testid for Playwright testing\n // Using className and aria-labels is not ideal for Playwright locator\n const headerId = `facet-group-header-label-${facetGroup.key}`;\n return html`\n <section\n class=\"facet-group ${this.collapsableFacets ? 'mobile' : ''}\"\n aria-labelledby=${headerId}\n data-testid=${headerId}\n >\n <div class=\"facet-group-header\">\n <h3\n id=${headerId}\n @click=${toggleCollapsed}\n @keyup=${toggleCollapsed}\n >\n ${this.collapsableFacets ? collapser : nothing} ${facetGroup.title}\n <span class=\"sr-only\">filters</span>\n </h3>\n </div>\n <div\n class=\"facet-group-content ${isOpen ? 'open' : ''}\"\n data-testid=\"facet-group-content-${facetGroup.key}\"\n >\n ${this.facetsLoading\n ? this.getTombstoneFacetGroupTemplate()\n : html`\n ${this.getFacetTemplate(facetGroup)}\n ${this.searchMoreFacetsLink(facetGroup)}\n `}\n </div>\n </section>\n `;\n }\n\n private getTombstoneFacetGroupTemplate(): TemplateResult {\n // Render five tombstone rows\n return html`\n ${map(\n Array(5).fill(null),\n () => html`<facet-tombstone-row></facet-tombstone-row>`,\n )}\n `;\n }\n\n /**\n * Generate the More... link button just below the facets group\n *\n * TODO: want to fire analytics?\n */\n private searchMoreFacetsLink(\n facetGroup: FacetGroup,\n ): TemplateResult | typeof nothing {\n // Don't render More... links for FTS searches\n if (!this.moreLinksVisible) {\n return nothing;\n }\n\n // Don't render More... links for lending facets\n if (facetGroup.key === 'lending') {\n return nothing;\n }\n\n // Don't render More... link if the number of facets < this.allowedFacetCount\n if (Object.keys(facetGroup.buckets).length < this.allowedFacetCount) {\n return nothing;\n }\n\n // We sort years in numeric order by default, rather than bucket count\n const facetSort = defaultFacetSort[facetGroup.key];\n\n // Added data-testid for Playwright testing\n // Using the className is not ideal for Playwright locator\n return html`<button\n class=\"more-link\"\n @click=${() => {\n this.showMoreFacetsModal(facetGroup, facetSort);\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.showMoreFacetsModal,\n label: facetGroup.key,\n });\n this.dispatchEvent(\n new CustomEvent('showMoreFacets', { detail: facetGroup.key }),\n );\n }}\n data-testid=\"more-link-btn\"\n >\n More...\n </button>`;\n }\n\n async showMoreFacetsModal(\n facetGroup: FacetGroup,\n sortedBy: AggregationSortType,\n ): Promise<void> {\n const customModalContent = html`\n <more-facets-content\n .analyticsHandler=${this.analyticsHandler}\n .facetKey=${facetGroup.key}\n .query=${this.query}\n .filterMap=${this.filterMap}\n .pageSpecifierParams=${this.pageSpecifierParams}\n .modalManager=${this.modalManager}\n .searchService=${this.searchService}\n .searchType=${this.searchType}\n .collectionTitles=${this.collectionTitles}\n .selectedFacets=${this.selectedFacets}\n .sortedBy=${sortedBy}\n @facetsChanged=${(e: CustomEvent) => {\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: e.detail,\n bubbles: true,\n composed: true,\n });\n this.dispatchEvent(event);\n }}\n >\n </more-facets-content>\n `;\n\n const config = new ModalConfig({\n bodyColor: '#fff',\n headerColor: '#194880',\n showHeaderLogo: false,\n closeOnBackdropClick: true, // TODO: want to fire analytics\n title: html`Select filters`,\n });\n this.modalManager?.classList.add('more-search-facets');\n this.modalManager?.showModal({\n config,\n customModalContent,\n userClosedModalCallback: () => {\n this.modalManager?.classList.remove('more-search-facets');\n },\n });\n }\n\n /**\n * Generate the list template for each bucket in a facet group\n */\n private getFacetTemplate(facetGroup: FacetGroup): TemplateResult {\n return html`\n <facets-template\n .collectionPagePath=${this.collectionPagePath}\n .facetGroup=${facetGroup}\n .selectedFacets=${this.selectedFacets}\n .collectionTitles=${this.collectionTitles}\n @facetClick=${(e: CustomEvent<FacetEventDetails>) => {\n this.selectedFacets = updateSelectedFacetBucket(\n this.selectedFacets,\n facetGroup.key,\n e.detail.bucket,\n true,\n );\n\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: this.selectedFacets,\n bubbles: true,\n composed: true,\n });\n this.dispatchEvent(event);\n }}\n ></facets-template>\n `;\n }\n\n static get styles() {\n return [\n srOnlyStyle,\n css`\n a:link {\n text-decoration: none;\n color: var(--ia-theme-link-color, #4b64ff);\n }\n a:link:hover {\n text-decoration: underline;\n }\n\n #container.loading {\n opacity: 0.5;\n }\n\n #container.managing {\n opacity: 0.3;\n }\n\n .histogram-loading-indicator {\n width: 100%;\n height: 2.25rem;\n margin-top: 1.75rem;\n font-size: 1.4rem;\n text-align: center;\n }\n\n .collapser {\n display: inline-block;\n cursor: pointer;\n width: 10px;\n height: 10px;\n }\n\n .collapser svg {\n transition: transform 0.2s ease-in-out;\n }\n\n .collapser.open svg {\n transform: rotate(90deg);\n }\n\n .facet-group:not(:last-child) {\n margin-bottom: 2rem;\n }\n\n .facet-group h3 {\n margin-bottom: 0.7rem;\n }\n\n .facet-group.mobile h3 {\n cursor: pointer;\n }\n\n .facet-group-header {\n display: flex;\n margin-bottom: 0.7rem;\n justify-content: space-between;\n border-bottom: 1px solid rgb(232, 232, 232);\n }\n\n .facet-group-content {\n transition: max-height 0.2s ease-in-out;\n }\n\n .facet-group.mobile .facet-group-content {\n max-height: 0;\n overflow: hidden;\n }\n\n .facet-group.mobile .facet-group-content.open {\n max-height: 2000px;\n }\n\n .partof-collections ul {\n list-style-type: none;\n padding: 0;\n font-size: 1.2rem;\n }\n\n h3 {\n font-size: 1.4rem;\n font-weight: 200;\n padding-bottom: 3px;\n margin: 0;\n }\n\n .more-link {\n font-size: 1.2rem;\n text-decoration: none;\n padding: 0;\n background: inherit;\n border: 0;\n color: var(--ia-theme-link-color, #4b64ff);\n cursor: pointer;\n }\n\n #date-picker-label {\n display: flex;\n justify-content: space-between;\n }\n\n .expand-date-picker-btn {\n margin: 0;\n padding: 0;\n border: 0;\n appearance: none;\n background: none;\n cursor: pointer;\n }\n\n .expand-date-picker-btn > svg {\n width: 14px;\n height: 14px;\n }\n\n .sorting-icon {\n height: 15px;\n cursor: pointer;\n }\n\n histogram-date-range.wide-inputs {\n --histogramDateRangeInputWidth: 4.8rem;\n }\n `,\n ];\n }\n}\n"]}
|
package/dist/src/models.d.ts
CHANGED
|
@@ -159,7 +159,7 @@ export type FacetLoadStrategy = 'eager' | 'lazy-mobile' | 'opt-in-or-login' | 'o
|
|
|
159
159
|
/**
|
|
160
160
|
* Union of the facet types that are available in the sidebar.
|
|
161
161
|
*/
|
|
162
|
-
export type FacetOption = 'subject' | 'lending' | 'mediatype' | 'language' | 'creator' | 'collection' | 'year';
|
|
162
|
+
export type FacetOption = 'subject' | 'lending' | 'mediatype' | 'language' | 'creator' | 'collection' | 'year' | 'program' | 'person' | 'sponsor';
|
|
163
163
|
export type SelectedFacetState = 'selected' | 'hidden';
|
|
164
164
|
export type FacetState = SelectedFacetState | 'none';
|
|
165
165
|
export interface FacetBucket {
|
|
@@ -192,9 +192,19 @@ export type FacetEventDetails = {
|
|
|
192
192
|
negative: boolean;
|
|
193
193
|
};
|
|
194
194
|
export type FacetValue = string;
|
|
195
|
-
export type SelectedFacets = Record<FacetOption, Record<FacetValue, FacetBucket
|
|
196
|
-
export declare const getDefaultSelectedFacets: () => SelectedFacets
|
|
197
|
-
|
|
195
|
+
export type SelectedFacets = Partial<Record<FacetOption, Record<FacetValue, FacetBucket>>>;
|
|
196
|
+
export declare const getDefaultSelectedFacets: () => Required<SelectedFacets>;
|
|
197
|
+
/**
|
|
198
|
+
* Facet display order when presenting results for all search types *except* TV (see below).
|
|
199
|
+
*/
|
|
200
|
+
export declare const defaultFacetDisplayOrder: FacetOption[];
|
|
201
|
+
/**
|
|
202
|
+
* Specialized facet ordering when displaying TV search results
|
|
203
|
+
*/
|
|
204
|
+
export declare const tvFacetDisplayOrder: FacetOption[];
|
|
205
|
+
/**
|
|
206
|
+
* Human-readable titles for each facet group.
|
|
207
|
+
*/
|
|
198
208
|
export declare const facetTitles: Record<FacetOption, string>;
|
|
199
209
|
/**
|
|
200
210
|
* The default sort type to use for each facet type
|
package/dist/src/models.js
CHANGED
|
@@ -322,8 +322,14 @@ export const getDefaultSelectedFacets = () => ({
|
|
|
322
322
|
creator: {},
|
|
323
323
|
collection: {},
|
|
324
324
|
year: {},
|
|
325
|
+
program: {},
|
|
326
|
+
person: {},
|
|
327
|
+
sponsor: {},
|
|
325
328
|
});
|
|
326
|
-
|
|
329
|
+
/**
|
|
330
|
+
* Facet display order when presenting results for all search types *except* TV (see below).
|
|
331
|
+
*/
|
|
332
|
+
export const defaultFacetDisplayOrder = [
|
|
327
333
|
'mediatype',
|
|
328
334
|
// 'lending', Commenting this out removes the lending facet from the sidebar for now
|
|
329
335
|
'year',
|
|
@@ -332,6 +338,22 @@ export const facetDisplayOrder = [
|
|
|
332
338
|
'creator',
|
|
333
339
|
'language',
|
|
334
340
|
];
|
|
341
|
+
/**
|
|
342
|
+
* Specialized facet ordering when displaying TV search results
|
|
343
|
+
*/
|
|
344
|
+
export const tvFacetDisplayOrder = [
|
|
345
|
+
'program',
|
|
346
|
+
'creator',
|
|
347
|
+
'year',
|
|
348
|
+
'subject',
|
|
349
|
+
'collection',
|
|
350
|
+
'person',
|
|
351
|
+
'sponsor',
|
|
352
|
+
'language',
|
|
353
|
+
];
|
|
354
|
+
/**
|
|
355
|
+
* Human-readable titles for each facet group.
|
|
356
|
+
*/
|
|
335
357
|
export const facetTitles = {
|
|
336
358
|
subject: 'Subject',
|
|
337
359
|
lending: 'Availability',
|
|
@@ -340,6 +362,9 @@ export const facetTitles = {
|
|
|
340
362
|
creator: 'Creator',
|
|
341
363
|
collection: 'Collection',
|
|
342
364
|
year: 'Year',
|
|
365
|
+
program: 'Program',
|
|
366
|
+
person: 'Person',
|
|
367
|
+
sponsor: 'Sponsor',
|
|
343
368
|
};
|
|
344
369
|
/**
|
|
345
370
|
* The default sort type to use for each facet type
|
|
@@ -351,7 +376,10 @@ export const defaultFacetSort = {
|
|
|
351
376
|
language: AggregationSortType.COUNT,
|
|
352
377
|
creator: AggregationSortType.COUNT,
|
|
353
378
|
collection: AggregationSortType.COUNT,
|
|
354
|
-
year: AggregationSortType.NUMERIC,
|
|
379
|
+
year: AggregationSortType.NUMERIC, // Year facets are ordered by their numeric value by default
|
|
380
|
+
program: AggregationSortType.COUNT,
|
|
381
|
+
person: AggregationSortType.COUNT,
|
|
382
|
+
sponsor: AggregationSortType.COUNT,
|
|
355
383
|
};
|
|
356
384
|
/**
|
|
357
385
|
* The sort type corresponding to facet bucket values, for each facet type
|
|
@@ -364,7 +392,10 @@ export const valueFacetSort = {
|
|
|
364
392
|
language: AggregationSortType.ALPHABETICAL,
|
|
365
393
|
creator: AggregationSortType.ALPHABETICAL,
|
|
366
394
|
collection: AggregationSortType.ALPHABETICAL,
|
|
367
|
-
year: AggregationSortType.NUMERIC,
|
|
395
|
+
year: AggregationSortType.NUMERIC, // Year facets' values should be compared numerically, not lexicographically (year 2001 > year 3)
|
|
396
|
+
program: AggregationSortType.ALPHABETICAL,
|
|
397
|
+
person: AggregationSortType.ALPHABETICAL,
|
|
398
|
+
sponsor: AggregationSortType.ALPHABETICAL,
|
|
368
399
|
};
|
|
369
400
|
/**
|
|
370
401
|
* Maps valid lending keys to whether they should be visible in the facet sidebar
|
package/dist/src/models.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TemplateResult } from 'lit';\nimport { msg } from '@lit/localize';\nimport type { MediaType } from '@internetarchive/field-parsers';\nimport {\n AggregationSortType,\n Review,\n SearchResult,\n SortDirection,\n} from '@internetarchive/search-service';\nimport { collapseRepeatedQuotes } from './utils/collapse-repeated-quotes';\nimport { resolveMediatype } from './utils/resolve-mediatype';\n\nimport { loginRequiredIcon } from './assets/img/icons/login-required';\nimport { restrictedIcon } from './assets/img/icons/restricted';\n\n/**\n * Flags that can affect the visibility of content on a tile\n */\ninterface TileFlags {\n loginRequired: boolean;\n contentWarning: boolean;\n}\n\n/**\n * Different types of tile overlays, corresponding to the above flags.\n */\nexport type TileOverlayType = 'login-required' | 'content-warning';\n\nexport const TILE_OVERLAY_TEXT: Record<TileOverlayType, string> = {\n 'login-required': msg('Log in to view this item'),\n 'content-warning': msg('Content may be inappropriate'),\n};\n\nexport const TILE_OVERLAY_ICONS: Record<TileOverlayType, TemplateResult> = {\n 'login-required': loginRequiredIcon,\n 'content-warning': restrictedIcon,\n};\n\n/**\n * Class for converting & storing raw search results in the correct format for UI tiles.\n */\nexport class TileModel {\n averageRating?: number;\n\n captureDates?: Date[]; // List of capture dates for a URL, used on profile Web Archives tiles\n\n checked: boolean; // Whether this tile is currently checked for item management functions\n\n collectionIdentifier?: string;\n\n collectionName?: string;\n\n collectionFilesCount: number;\n\n collections: string[];\n\n collectionSize: number;\n\n commentCount: number;\n\n creator?: string;\n\n creators: string[];\n\n dateStr?: string; // A string representation of the publication date, used strictly for passing preformatted dates to the parent\n\n dateAdded?: Date; // Date added to public search (software-defined) [from: addeddate]\n\n dateArchived?: Date; // Date archived (software-defined) item created on archive.org [from: publicdate]\n\n datePublished?: Date; // Date work published in the world (user-defined) [from: date]\n\n dateReviewed?: Date; // Date reviewed (user-created) most recent review [from: reviewdate]\n\n description?: string;\n\n favCount: number;\n\n href?: string;\n\n identifier?: string;\n\n issue?: string;\n\n itemCount: number;\n\n mediatype: MediaType;\n\n review?: Review;\n\n source?: string;\n\n snippets?: string[];\n\n subjects: string[];\n\n thumbnailUrl?: string;\n\n title: string;\n\n tvClipCount?: number;\n\n viewCount?: number;\n\n volume?: string;\n\n weeklyViewCount?: number;\n\n loginRequired: boolean;\n\n contentWarning: boolean;\n\n constructor(result: SearchResult) {\n const flags = this.getFlags(result);\n\n this.averageRating = result.avg_rating?.value;\n this.captureDates = result.capture_dates?.values;\n this.checked = false;\n this.collections = result.collection?.values ?? [];\n this.collectionFilesCount = result.collection_files_count?.value ?? 0;\n this.collectionSize = result.collection_size?.value ?? 0;\n this.commentCount = result.num_reviews?.value ?? 0;\n this.creator = result.creator?.value;\n this.creators = result.creator?.values ?? [];\n this.dateAdded = result.addeddate?.value;\n this.dateArchived = result.publicdate?.value;\n this.datePublished = result.date?.value;\n this.dateReviewed = result.reviewdate?.value;\n this.description = result.description?.values.join('\\n');\n this.favCount = result.num_favorites?.value ?? 0;\n this.href = collapseRepeatedQuotes(\n result.review?.__href__ ?? result.__href__?.value,\n );\n this.identifier = TileModel.cleanIdentifier(result.identifier);\n this.issue = result.issue?.value;\n this.itemCount = result.item_count?.value ?? 0;\n this.mediatype = resolveMediatype(result);\n this.review = result.review;\n this.snippets = result.highlight?.values ?? [];\n this.source = result.source?.value;\n this.subjects = result.subject?.values ?? [];\n this.thumbnailUrl = result.__img__?.value;\n this.title = result.title?.value ?? '';\n this.tvClipCount = result.num_clips?.value ?? 0;\n this.volume = result.volume?.value;\n this.viewCount = result.downloads?.value;\n this.weeklyViewCount = result.week?.value;\n this.loginRequired = flags.loginRequired;\n this.contentWarning = flags.contentWarning;\n }\n\n /**\n * Copies the contents of this TileModel onto a new instance\n */\n clone(): TileModel {\n const cloned = new TileModel({});\n cloned.averageRating = this.averageRating;\n cloned.captureDates = this.captureDates;\n cloned.checked = this.checked;\n cloned.collections = this.collections;\n cloned.collectionFilesCount = this.collectionFilesCount;\n cloned.collectionSize = this.collectionSize;\n cloned.commentCount = this.commentCount;\n cloned.creator = this.creator;\n cloned.creators = this.creators;\n cloned.dateStr = this.dateStr;\n cloned.dateAdded = this.dateAdded;\n cloned.dateArchived = this.dateArchived;\n cloned.datePublished = this.datePublished;\n cloned.dateReviewed = this.dateReviewed;\n cloned.description = this.description;\n cloned.favCount = this.favCount;\n cloned.href = this.href;\n cloned.identifier = this.identifier;\n cloned.issue = this.issue;\n cloned.itemCount = this.itemCount;\n cloned.mediatype = this.mediatype;\n cloned.snippets = this.snippets;\n cloned.source = this.source;\n cloned.subjects = this.subjects;\n cloned.thumbnailUrl = this.thumbnailUrl;\n cloned.title = this.title;\n cloned.tvClipCount = this.tvClipCount;\n cloned.volume = this.volume;\n cloned.viewCount = this.viewCount;\n cloned.weeklyViewCount = this.weeklyViewCount;\n cloned.loginRequired = this.loginRequired;\n cloned.contentWarning = this.contentWarning;\n return cloned;\n }\n\n /**\n * Determines the appropriate tile flags for the given search result\n * (login required and/or content warning)\n */\n private getFlags(result: SearchResult): TileFlags {\n const flags: TileFlags = {\n loginRequired: false,\n contentWarning: false,\n };\n\n // Check if item and item in \"modifying\" collection, setting above flags\n if (\n result.collection?.values.length &&\n result.mediatype?.value !== 'collection'\n ) {\n for (const collection of result.collection?.values ?? []) {\n if (collection === 'loggedin') {\n flags.loginRequired = true;\n if (flags.contentWarning) break;\n }\n if (collection === 'no-preview') {\n flags.contentWarning = true;\n if (flags.loginRequired) break;\n }\n }\n }\n\n return flags;\n }\n\n private static cleanIdentifier(\n identifier: string | undefined,\n ): string | undefined {\n // Some identifiers (e.g., from Whisper) represent documents rather than items, and\n // are suffixed with values that need to be stripped. Those values are separated\n // from the item identifier itself with '|'.\n const barIndex = identifier?.indexOf('|') ?? -1;\n const cleaned = barIndex > 0 ? identifier?.slice(0, barIndex) : identifier;\n return cleaned;\n }\n}\n\nexport type RequestKind = 'full' | 'hits' | 'aggregations';\n\nexport type CollectionDisplayMode = 'grid' | 'list-compact' | 'list-detail';\n\nexport type TileDisplayMode =\n | 'grid'\n | 'list-compact'\n | 'list-detail'\n | 'list-header';\n\n/**\n * This is mainly used to set the cookies for the collection display mode.\n *\n * It allows the user to set different modes for different contexts (collection page, search page, profile page etc).\n */\nexport type CollectionBrowserContext = 'collection' | 'search' | 'profile';\n\n/**\n * The sort fields shown in the sort filter bar\n */\nexport enum SortField {\n 'default' = 'default',\n 'unrecognized' = 'unrecognized',\n 'relevance' = 'relevance',\n 'alltimeview' = 'alltimeview',\n 'weeklyview' = 'weeklyview',\n 'title' = 'title',\n 'date' = 'date',\n 'datearchived' = 'datearchived',\n 'datereviewed' = 'datereviewed',\n 'dateadded' = 'dateadded',\n 'datefavorited' = 'datefavorited',\n 'creator' = 'creator',\n}\n\nexport interface SortOption {\n /**\n * The SortField enum member corresponding to this option.\n */\n field: SortField;\n\n /**\n * The default sort direction to apply when this sort option is first selected.\n */\n defaultSortDirection: SortDirection | null;\n\n /**\n * Whether this sort option allows its sort direction to be changed from the default.\n */\n canSetDirection: boolean;\n\n /**\n * Whether this sort option may appear in the sort bar.\n */\n shownInSortBar: boolean;\n\n /**\n * Whether this sort option should be saved to the URL.\n * If false, then no `sort` param will be added to the URL when this sort option\n * is selected.\n */\n shownInURL: boolean;\n\n /**\n * Whether this sort option is passed to the search service.\n * If false, then no sort param will be passed to the search service at all when\n * this sort option is selected.\n */\n handledBySearchService: boolean;\n\n /**\n * The string identifying this sort field to the search service & backend API.\n */\n searchServiceKey?: string;\n\n /**\n * The human-readable name to use for this option in the sort bar (if applicable).\n */\n displayName: string;\n\n /**\n * A list of URL param keys that should be mapped to this sort option.\n * E.g., both `title` and `titleSorter` in the URL map to the `SortField.title` option.\n */\n urlNames: (string | null | undefined)[];\n}\n\nexport const SORT_OPTIONS: Record<SortField, SortOption> = {\n // Default sort is the case where the user has not specified a sort option via the sort bar or URL.\n // In these cases, we defer to whatever sort the backend chooses.\n // For the search page, the default is always relevance sort.\n // For collection pages _without a query_, the default is usually weekly views, but this can be\n // overridden by the collection's `sort-by` metadata entry. If a query _is_ specified, then the\n // default is again relevance sort.\n // For fav-* collections only, the default is instead sorting by date favorited.\n [SortField.default]: {\n field: SortField.default,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: false, // We rely on the PPS default sort handling in these cases\n displayName: '',\n urlNames: ['', null, undefined], // Empty or nullish sort params result in default sorting\n },\n // Unrecognized sort is the case where the user has specified a sort in the URL, but it is not\n // one of the options listed in this map. We still want these unrecognized sorts to be applied\n // when searching, but they are not displayed in the sort bar and we do not actively manage\n // their URL param beyond flipping the direction as needed.\n [SortField.unrecognized]: {\n field: SortField.unrecognized,\n defaultSortDirection: null,\n canSetDirection: true,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: true, // The unrecognized sort param is passed along as-is\n displayName: '',\n urlNames: [],\n },\n // Relevance sort is unique in that it does not produce a URL param when it is set.\n // It is only available when there is a user-specified query that relevancy can be scored against.\n // Therefore, it does not appear as a sort bar option when browsing a collection with no query set.\n [SortField.relevance]: {\n field: SortField.relevance,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: true,\n shownInURL: false,\n handledBySearchService: false,\n displayName: 'Relevance',\n urlNames: ['_score'],\n },\n [SortField.alltimeview]: {\n field: SortField.alltimeview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'downloads',\n displayName: 'All-time views',\n urlNames: ['downloads'],\n },\n [SortField.weeklyview]: {\n field: SortField.weeklyview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'week',\n displayName: 'Weekly views',\n urlNames: ['week'],\n },\n [SortField.title]: {\n field: SortField.title,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'titleSorter',\n displayName: 'Title',\n urlNames: ['title', 'titleSorter'],\n },\n [SortField.date]: {\n field: SortField.date,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'date',\n displayName: 'Date published',\n urlNames: ['date'],\n },\n [SortField.datearchived]: {\n field: SortField.datearchived,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'publicdate',\n displayName: 'Date archived',\n urlNames: ['publicdate'],\n },\n [SortField.datereviewed]: {\n field: SortField.datereviewed,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'reviewdate',\n displayName: 'Date reviewed',\n urlNames: ['reviewdate'],\n },\n [SortField.dateadded]: {\n field: SortField.dateadded,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'addeddate',\n displayName: 'Date added',\n urlNames: ['addeddate'],\n },\n [SortField.datefavorited]: {\n field: SortField.datefavorited,\n defaultSortDirection: 'desc',\n canSetDirection: false,\n shownInSortBar: true, // But only when viewing fav-* collections\n shownInURL: false,\n handledBySearchService: false,\n searchServiceKey: 'favoritedate',\n displayName: 'Date favorited',\n urlNames: ['favoritedate'],\n },\n [SortField.creator]: {\n field: SortField.creator,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'creatorSorter',\n displayName: 'Creator',\n urlNames: ['creator', 'creatorSorter'],\n },\n};\n\n/**\n * Returns the SortOption corresponding to the given API sort name, or\n * the \"unrecognized\" SortOption if none matches.\n */\nexport function sortOptionFromAPIString(sortName?: string | null): SortOption {\n return (\n Object.values(SORT_OPTIONS).find(opt =>\n opt.urlNames.some(name => sortName === name),\n ) ?? SORT_OPTIONS[SortField.unrecognized]\n );\n}\n\nexport const defaultProfileElementSorts: Record<\n string,\n Exclude<SortField, SortField.default>\n> = {\n uploads: SortField.datearchived,\n reviews: SortField.datereviewed,\n collections: SortField.datearchived,\n web_archives: SortField.datearchived,\n};\n\n/** A union of the fields that permit prefix filtering (e.g., alphabetical filtering) */\nexport type PrefixFilterType = 'title' | 'creator';\n\n/** A map from prefixes (e.g., initial letters) to the number of items matching that prefix */\nexport type PrefixFilterCounts = Record<string, number>;\n\n/**\n * A map from prefix filter types to the corresponding aggregation keys\n * that are needed to fetch the filter counts from the backend.\n */\nexport const prefixFilterAggregationKeys: Record<PrefixFilterType, string> = {\n title: 'firstTitle',\n creator: 'firstCreator',\n};\n\n/**\n * Different facet loading strategies that can be used with collection browser.\n * - `eager`: Facet data is always loaded as soon as a search is performed\n * - `lazy-mobile`: In the desktop layout, functions exactly as `eager`.\n * In the mobile layout, facet data will only be loaded once the \"Filters\" accordion is opened.\n * - `opt-in-or-login`: Same as `opt-in` for guest users not logged into an account, but same as `eager` for\n * any logged in user.\n * - `opt-in`: In the desktop layout, facet data will only be loaded after the user presses a \"Load Facets\" button.\n * In the mobile layout, functions exactly as `lazy-mobile`.\n * - `off`: Facet data will never be loaded, and a message will be displayed in place of facets\n * indicating that they are unavailable.\n */\nexport type FacetLoadStrategy =\n | 'eager'\n | 'lazy-mobile'\n | 'opt-in-or-login'\n | 'opt-in'\n | 'off';\n\n/**\n * Union of the facet types that are available in the sidebar.\n */\nexport type FacetOption =\n | 'subject'\n | 'lending'\n | 'mediatype'\n | 'language'\n | 'creator'\n | 'collection'\n | 'year';\n\nexport type SelectedFacetState = 'selected' | 'hidden';\n\nexport type FacetState = SelectedFacetState | 'none';\n\nexport interface FacetBucket {\n // for some facets, we augment the key with a display value\n displayText?: string;\n key: string;\n count: number;\n state: FacetState;\n}\n\nexport interface FacetGroup {\n title: string;\n key: FacetOption;\n buckets: FacetBucket[];\n}\n\n/**\n * Information about a user interaction event on a facet.\n */\nexport type FacetEventDetails = {\n /**\n * The type of facet that was interacted with (e.g., 'mediatype', 'language', ...).\n */\n facetType: FacetOption;\n /**\n * The bucket corresponding to the facet that was interacted with, including the\n * updated state of the facet after the interaction.\n */\n bucket: FacetBucket;\n /**\n * Whether the interaction occurred on a negative facet.\n */\n negative: boolean;\n};\n\nexport type FacetValue = string;\n\nexport type SelectedFacets = Record<\n FacetOption,\n Record<FacetValue, FacetBucket>\n>;\n\nexport const getDefaultSelectedFacets = (): SelectedFacets => ({\n subject: {},\n lending: {},\n mediatype: {},\n language: {},\n creator: {},\n collection: {},\n year: {},\n});\n\nexport const facetDisplayOrder: FacetOption[] = [\n 'mediatype',\n // 'lending', Commenting this out removes the lending facet from the sidebar for now\n 'year',\n 'subject',\n 'collection',\n 'creator',\n 'language',\n];\n\nexport const facetTitles: Record<FacetOption, string> = {\n subject: 'Subject',\n lending: 'Availability',\n mediatype: 'Media Type',\n language: 'Language',\n creator: 'Creator',\n collection: 'Collection',\n year: 'Year',\n};\n\n/**\n * The default sort type to use for each facet type\n */\nexport const defaultFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.COUNT,\n lending: AggregationSortType.COUNT,\n mediatype: AggregationSortType.COUNT,\n language: AggregationSortType.COUNT,\n creator: AggregationSortType.COUNT,\n collection: AggregationSortType.COUNT,\n year: AggregationSortType.NUMERIC,\n};\n\n/**\n * The sort type corresponding to facet bucket values, for each facet type\n * (i.e., the opposite of \"sort by count\" for that type).\n */\nexport const valueFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.ALPHABETICAL,\n lending: AggregationSortType.ALPHABETICAL,\n mediatype: AggregationSortType.ALPHABETICAL,\n language: AggregationSortType.ALPHABETICAL,\n creator: AggregationSortType.ALPHABETICAL,\n collection: AggregationSortType.ALPHABETICAL,\n year: AggregationSortType.NUMERIC,\n};\n\nexport type LendingFacetKey =\n | 'is_lendable'\n | 'is_borrowable'\n | 'available_to_borrow'\n | 'is_browsable'\n | 'available_to_browse'\n | 'is_readable'\n | 'available_to_waitlist';\n\n/**\n * Maps valid lending keys to whether they should be visible in the facet sidebar\n */\nexport const lendingFacetKeysVisibility: Record<LendingFacetKey, boolean> = {\n is_lendable: true,\n is_borrowable: false,\n available_to_borrow: true,\n is_browsable: false,\n available_to_browse: false,\n is_readable: true,\n available_to_waitlist: false,\n};\n\n/**\n * Maps valid, visible lending keys to their facet sidebar display text\n */\nexport const lendingFacetDisplayNames: Partial<\n Record<LendingFacetKey, string>\n> = {\n is_lendable: 'Lending Library',\n available_to_borrow: 'Borrow 14 Days',\n is_readable: 'Always Available',\n};\n\n/**\n * A record of which admin-only collections should be suppressed from being displayed\n * as facets or in an item's list of collections.\n */\nexport const suppressedCollections: Record<string, boolean> = {\n deemphasize: true,\n community: true,\n stream_only: true,\n samples_only: true,\n test_collection: true,\n printdisabled: true,\n 'openlibrary-ol': true,\n nationalemergencylibrary: true,\n china: true,\n americana: true,\n toronto: true,\n};\n\n/**\n * A record of manageable item\n */\nexport interface ManageableItem {\n identifier: string;\n title?: string;\n dateStr?: string;\n date?: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TemplateResult } from 'lit';\nimport { msg } from '@lit/localize';\nimport type { MediaType } from '@internetarchive/field-parsers';\nimport {\n AggregationSortType,\n Review,\n SearchResult,\n SortDirection,\n} from '@internetarchive/search-service';\nimport { collapseRepeatedQuotes } from './utils/collapse-repeated-quotes';\nimport { resolveMediatype } from './utils/resolve-mediatype';\n\nimport { loginRequiredIcon } from './assets/img/icons/login-required';\nimport { restrictedIcon } from './assets/img/icons/restricted';\n\n/**\n * Flags that can affect the visibility of content on a tile\n */\ninterface TileFlags {\n loginRequired: boolean;\n contentWarning: boolean;\n}\n\n/**\n * Different types of tile overlays, corresponding to the above flags.\n */\nexport type TileOverlayType = 'login-required' | 'content-warning';\n\nexport const TILE_OVERLAY_TEXT: Record<TileOverlayType, string> = {\n 'login-required': msg('Log in to view this item'),\n 'content-warning': msg('Content may be inappropriate'),\n};\n\nexport const TILE_OVERLAY_ICONS: Record<TileOverlayType, TemplateResult> = {\n 'login-required': loginRequiredIcon,\n 'content-warning': restrictedIcon,\n};\n\n/**\n * Class for converting & storing raw search results in the correct format for UI tiles.\n */\nexport class TileModel {\n averageRating?: number;\n\n captureDates?: Date[]; // List of capture dates for a URL, used on profile Web Archives tiles\n\n checked: boolean; // Whether this tile is currently checked for item management functions\n\n collectionIdentifier?: string;\n\n collectionName?: string;\n\n collectionFilesCount: number;\n\n collections: string[];\n\n collectionSize: number;\n\n commentCount: number;\n\n creator?: string;\n\n creators: string[];\n\n dateStr?: string; // A string representation of the publication date, used strictly for passing preformatted dates to the parent\n\n dateAdded?: Date; // Date added to public search (software-defined) [from: addeddate]\n\n dateArchived?: Date; // Date archived (software-defined) item created on archive.org [from: publicdate]\n\n datePublished?: Date; // Date work published in the world (user-defined) [from: date]\n\n dateReviewed?: Date; // Date reviewed (user-created) most recent review [from: reviewdate]\n\n description?: string;\n\n favCount: number;\n\n href?: string;\n\n identifier?: string;\n\n issue?: string;\n\n itemCount: number;\n\n mediatype: MediaType;\n\n review?: Review;\n\n source?: string;\n\n snippets?: string[];\n\n subjects: string[];\n\n thumbnailUrl?: string;\n\n title: string;\n\n tvClipCount?: number;\n\n viewCount?: number;\n\n volume?: string;\n\n weeklyViewCount?: number;\n\n loginRequired: boolean;\n\n contentWarning: boolean;\n\n constructor(result: SearchResult) {\n const flags = this.getFlags(result);\n\n this.averageRating = result.avg_rating?.value;\n this.captureDates = result.capture_dates?.values;\n this.checked = false;\n this.collections = result.collection?.values ?? [];\n this.collectionFilesCount = result.collection_files_count?.value ?? 0;\n this.collectionSize = result.collection_size?.value ?? 0;\n this.commentCount = result.num_reviews?.value ?? 0;\n this.creator = result.creator?.value;\n this.creators = result.creator?.values ?? [];\n this.dateAdded = result.addeddate?.value;\n this.dateArchived = result.publicdate?.value;\n this.datePublished = result.date?.value;\n this.dateReviewed = result.reviewdate?.value;\n this.description = result.description?.values.join('\\n');\n this.favCount = result.num_favorites?.value ?? 0;\n this.href = collapseRepeatedQuotes(\n result.review?.__href__ ?? result.__href__?.value,\n );\n this.identifier = TileModel.cleanIdentifier(result.identifier);\n this.issue = result.issue?.value;\n this.itemCount = result.item_count?.value ?? 0;\n this.mediatype = resolveMediatype(result);\n this.review = result.review;\n this.snippets = result.highlight?.values ?? [];\n this.source = result.source?.value;\n this.subjects = result.subject?.values ?? [];\n this.thumbnailUrl = result.__img__?.value;\n this.title = result.title?.value ?? '';\n this.tvClipCount = result.num_clips?.value ?? 0;\n this.volume = result.volume?.value;\n this.viewCount = result.downloads?.value;\n this.weeklyViewCount = result.week?.value;\n this.loginRequired = flags.loginRequired;\n this.contentWarning = flags.contentWarning;\n }\n\n /**\n * Copies the contents of this TileModel onto a new instance\n */\n clone(): TileModel {\n const cloned = new TileModel({});\n cloned.averageRating = this.averageRating;\n cloned.captureDates = this.captureDates;\n cloned.checked = this.checked;\n cloned.collections = this.collections;\n cloned.collectionFilesCount = this.collectionFilesCount;\n cloned.collectionSize = this.collectionSize;\n cloned.commentCount = this.commentCount;\n cloned.creator = this.creator;\n cloned.creators = this.creators;\n cloned.dateStr = this.dateStr;\n cloned.dateAdded = this.dateAdded;\n cloned.dateArchived = this.dateArchived;\n cloned.datePublished = this.datePublished;\n cloned.dateReviewed = this.dateReviewed;\n cloned.description = this.description;\n cloned.favCount = this.favCount;\n cloned.href = this.href;\n cloned.identifier = this.identifier;\n cloned.issue = this.issue;\n cloned.itemCount = this.itemCount;\n cloned.mediatype = this.mediatype;\n cloned.snippets = this.snippets;\n cloned.source = this.source;\n cloned.subjects = this.subjects;\n cloned.thumbnailUrl = this.thumbnailUrl;\n cloned.title = this.title;\n cloned.tvClipCount = this.tvClipCount;\n cloned.volume = this.volume;\n cloned.viewCount = this.viewCount;\n cloned.weeklyViewCount = this.weeklyViewCount;\n cloned.loginRequired = this.loginRequired;\n cloned.contentWarning = this.contentWarning;\n return cloned;\n }\n\n /**\n * Determines the appropriate tile flags for the given search result\n * (login required and/or content warning)\n */\n private getFlags(result: SearchResult): TileFlags {\n const flags: TileFlags = {\n loginRequired: false,\n contentWarning: false,\n };\n\n // Check if item and item in \"modifying\" collection, setting above flags\n if (\n result.collection?.values.length &&\n result.mediatype?.value !== 'collection'\n ) {\n for (const collection of result.collection?.values ?? []) {\n if (collection === 'loggedin') {\n flags.loginRequired = true;\n if (flags.contentWarning) break;\n }\n if (collection === 'no-preview') {\n flags.contentWarning = true;\n if (flags.loginRequired) break;\n }\n }\n }\n\n return flags;\n }\n\n private static cleanIdentifier(\n identifier: string | undefined,\n ): string | undefined {\n // Some identifiers (e.g., from Whisper) represent documents rather than items, and\n // are suffixed with values that need to be stripped. Those values are separated\n // from the item identifier itself with '|'.\n const barIndex = identifier?.indexOf('|') ?? -1;\n const cleaned = barIndex > 0 ? identifier?.slice(0, barIndex) : identifier;\n return cleaned;\n }\n}\n\nexport type RequestKind = 'full' | 'hits' | 'aggregations';\n\nexport type CollectionDisplayMode = 'grid' | 'list-compact' | 'list-detail';\n\nexport type TileDisplayMode =\n | 'grid'\n | 'list-compact'\n | 'list-detail'\n | 'list-header';\n\n/**\n * This is mainly used to set the cookies for the collection display mode.\n *\n * It allows the user to set different modes for different contexts (collection page, search page, profile page etc).\n */\nexport type CollectionBrowserContext = 'collection' | 'search' | 'profile';\n\n/**\n * The sort fields shown in the sort filter bar\n */\nexport enum SortField {\n 'default' = 'default',\n 'unrecognized' = 'unrecognized',\n 'relevance' = 'relevance',\n 'alltimeview' = 'alltimeview',\n 'weeklyview' = 'weeklyview',\n 'title' = 'title',\n 'date' = 'date',\n 'datearchived' = 'datearchived',\n 'datereviewed' = 'datereviewed',\n 'dateadded' = 'dateadded',\n 'datefavorited' = 'datefavorited',\n 'creator' = 'creator',\n}\n\nexport interface SortOption {\n /**\n * The SortField enum member corresponding to this option.\n */\n field: SortField;\n\n /**\n * The default sort direction to apply when this sort option is first selected.\n */\n defaultSortDirection: SortDirection | null;\n\n /**\n * Whether this sort option allows its sort direction to be changed from the default.\n */\n canSetDirection: boolean;\n\n /**\n * Whether this sort option may appear in the sort bar.\n */\n shownInSortBar: boolean;\n\n /**\n * Whether this sort option should be saved to the URL.\n * If false, then no `sort` param will be added to the URL when this sort option\n * is selected.\n */\n shownInURL: boolean;\n\n /**\n * Whether this sort option is passed to the search service.\n * If false, then no sort param will be passed to the search service at all when\n * this sort option is selected.\n */\n handledBySearchService: boolean;\n\n /**\n * The string identifying this sort field to the search service & backend API.\n */\n searchServiceKey?: string;\n\n /**\n * The human-readable name to use for this option in the sort bar (if applicable).\n */\n displayName: string;\n\n /**\n * A list of URL param keys that should be mapped to this sort option.\n * E.g., both `title` and `titleSorter` in the URL map to the `SortField.title` option.\n */\n urlNames: (string | null | undefined)[];\n}\n\nexport const SORT_OPTIONS: Record<SortField, SortOption> = {\n // Default sort is the case where the user has not specified a sort option via the sort bar or URL.\n // In these cases, we defer to whatever sort the backend chooses.\n // For the search page, the default is always relevance sort.\n // For collection pages _without a query_, the default is usually weekly views, but this can be\n // overridden by the collection's `sort-by` metadata entry. If a query _is_ specified, then the\n // default is again relevance sort.\n // For fav-* collections only, the default is instead sorting by date favorited.\n [SortField.default]: {\n field: SortField.default,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: false, // We rely on the PPS default sort handling in these cases\n displayName: '',\n urlNames: ['', null, undefined], // Empty or nullish sort params result in default sorting\n },\n // Unrecognized sort is the case where the user has specified a sort in the URL, but it is not\n // one of the options listed in this map. We still want these unrecognized sorts to be applied\n // when searching, but they are not displayed in the sort bar and we do not actively manage\n // their URL param beyond flipping the direction as needed.\n [SortField.unrecognized]: {\n field: SortField.unrecognized,\n defaultSortDirection: null,\n canSetDirection: true,\n shownInSortBar: false,\n shownInURL: false,\n handledBySearchService: true, // The unrecognized sort param is passed along as-is\n displayName: '',\n urlNames: [],\n },\n // Relevance sort is unique in that it does not produce a URL param when it is set.\n // It is only available when there is a user-specified query that relevancy can be scored against.\n // Therefore, it does not appear as a sort bar option when browsing a collection with no query set.\n [SortField.relevance]: {\n field: SortField.relevance,\n defaultSortDirection: null,\n canSetDirection: false,\n shownInSortBar: true,\n shownInURL: false,\n handledBySearchService: false,\n displayName: 'Relevance',\n urlNames: ['_score'],\n },\n [SortField.alltimeview]: {\n field: SortField.alltimeview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'downloads',\n displayName: 'All-time views',\n urlNames: ['downloads'],\n },\n [SortField.weeklyview]: {\n field: SortField.weeklyview,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'week',\n displayName: 'Weekly views',\n urlNames: ['week'],\n },\n [SortField.title]: {\n field: SortField.title,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'titleSorter',\n displayName: 'Title',\n urlNames: ['title', 'titleSorter'],\n },\n [SortField.date]: {\n field: SortField.date,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'date',\n displayName: 'Date published',\n urlNames: ['date'],\n },\n [SortField.datearchived]: {\n field: SortField.datearchived,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'publicdate',\n displayName: 'Date archived',\n urlNames: ['publicdate'],\n },\n [SortField.datereviewed]: {\n field: SortField.datereviewed,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'reviewdate',\n displayName: 'Date reviewed',\n urlNames: ['reviewdate'],\n },\n [SortField.dateadded]: {\n field: SortField.dateadded,\n defaultSortDirection: 'desc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'addeddate',\n displayName: 'Date added',\n urlNames: ['addeddate'],\n },\n [SortField.datefavorited]: {\n field: SortField.datefavorited,\n defaultSortDirection: 'desc',\n canSetDirection: false,\n shownInSortBar: true, // But only when viewing fav-* collections\n shownInURL: false,\n handledBySearchService: false,\n searchServiceKey: 'favoritedate',\n displayName: 'Date favorited',\n urlNames: ['favoritedate'],\n },\n [SortField.creator]: {\n field: SortField.creator,\n defaultSortDirection: 'asc',\n canSetDirection: true,\n shownInSortBar: true,\n shownInURL: true,\n handledBySearchService: true,\n searchServiceKey: 'creatorSorter',\n displayName: 'Creator',\n urlNames: ['creator', 'creatorSorter'],\n },\n};\n\n/**\n * Returns the SortOption corresponding to the given API sort name, or\n * the \"unrecognized\" SortOption if none matches.\n */\nexport function sortOptionFromAPIString(sortName?: string | null): SortOption {\n return (\n Object.values(SORT_OPTIONS).find(opt =>\n opt.urlNames.some(name => sortName === name),\n ) ?? SORT_OPTIONS[SortField.unrecognized]\n );\n}\n\nexport const defaultProfileElementSorts: Record<\n string,\n Exclude<SortField, SortField.default>\n> = {\n uploads: SortField.datearchived,\n reviews: SortField.datereviewed,\n collections: SortField.datearchived,\n web_archives: SortField.datearchived,\n};\n\n/** A union of the fields that permit prefix filtering (e.g., alphabetical filtering) */\nexport type PrefixFilterType = 'title' | 'creator';\n\n/** A map from prefixes (e.g., initial letters) to the number of items matching that prefix */\nexport type PrefixFilterCounts = Record<string, number>;\n\n/**\n * A map from prefix filter types to the corresponding aggregation keys\n * that are needed to fetch the filter counts from the backend.\n */\nexport const prefixFilterAggregationKeys: Record<PrefixFilterType, string> = {\n title: 'firstTitle',\n creator: 'firstCreator',\n};\n\n/**\n * Different facet loading strategies that can be used with collection browser.\n * - `eager`: Facet data is always loaded as soon as a search is performed\n * - `lazy-mobile`: In the desktop layout, functions exactly as `eager`.\n * In the mobile layout, facet data will only be loaded once the \"Filters\" accordion is opened.\n * - `opt-in-or-login`: Same as `opt-in` for guest users not logged into an account, but same as `eager` for\n * any logged in user.\n * - `opt-in`: In the desktop layout, facet data will only be loaded after the user presses a \"Load Facets\" button.\n * In the mobile layout, functions exactly as `lazy-mobile`.\n * - `off`: Facet data will never be loaded, and a message will be displayed in place of facets\n * indicating that they are unavailable.\n */\nexport type FacetLoadStrategy =\n | 'eager'\n | 'lazy-mobile'\n | 'opt-in-or-login'\n | 'opt-in'\n | 'off';\n\n/**\n * Union of the facet types that are available in the sidebar.\n */\nexport type FacetOption =\n | 'subject'\n | 'lending'\n | 'mediatype'\n | 'language'\n | 'creator'\n | 'collection'\n | 'year'\n // TV-specific facet options:\n | 'program'\n | 'person'\n | 'sponsor';\n\nexport type SelectedFacetState = 'selected' | 'hidden';\n\nexport type FacetState = SelectedFacetState | 'none';\n\nexport interface FacetBucket {\n // for some facets, we augment the key with a display value\n displayText?: string;\n key: string;\n count: number;\n state: FacetState;\n}\n\nexport interface FacetGroup {\n title: string;\n key: FacetOption;\n buckets: FacetBucket[];\n}\n\n/**\n * Information about a user interaction event on a facet.\n */\nexport type FacetEventDetails = {\n /**\n * The type of facet that was interacted with (e.g., 'mediatype', 'language', ...).\n */\n facetType: FacetOption;\n /**\n * The bucket corresponding to the facet that was interacted with, including the\n * updated state of the facet after the interaction.\n */\n bucket: FacetBucket;\n /**\n * Whether the interaction occurred on a negative facet.\n */\n negative: boolean;\n};\n\nexport type FacetValue = string;\n\nexport type SelectedFacets = Partial<\n Record<FacetOption, Record<FacetValue, FacetBucket>>\n>;\n\nexport const getDefaultSelectedFacets = (): Required<SelectedFacets> => ({\n subject: {},\n lending: {},\n mediatype: {},\n language: {},\n creator: {},\n collection: {},\n year: {},\n program: {},\n person: {},\n sponsor: {},\n});\n\n/**\n * Facet display order when presenting results for all search types *except* TV (see below).\n */\nexport const defaultFacetDisplayOrder: FacetOption[] = [\n 'mediatype',\n // 'lending', Commenting this out removes the lending facet from the sidebar for now\n 'year',\n 'subject',\n 'collection',\n 'creator',\n 'language',\n];\n\n/**\n * Specialized facet ordering when displaying TV search results\n */\nexport const tvFacetDisplayOrder: FacetOption[] = [\n 'program',\n 'creator',\n 'year',\n 'subject',\n 'collection',\n 'person',\n 'sponsor',\n 'language',\n];\n\n/**\n * Human-readable titles for each facet group.\n */\nexport const facetTitles: Record<FacetOption, string> = {\n subject: 'Subject',\n lending: 'Availability',\n mediatype: 'Media Type',\n language: 'Language',\n creator: 'Creator',\n collection: 'Collection',\n year: 'Year',\n program: 'Program',\n person: 'Person',\n sponsor: 'Sponsor',\n};\n\n/**\n * The default sort type to use for each facet type\n */\nexport const defaultFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.COUNT,\n lending: AggregationSortType.COUNT,\n mediatype: AggregationSortType.COUNT,\n language: AggregationSortType.COUNT,\n creator: AggregationSortType.COUNT,\n collection: AggregationSortType.COUNT,\n year: AggregationSortType.NUMERIC, // Year facets are ordered by their numeric value by default\n program: AggregationSortType.COUNT,\n person: AggregationSortType.COUNT,\n sponsor: AggregationSortType.COUNT,\n};\n\n/**\n * The sort type corresponding to facet bucket values, for each facet type\n * (i.e., the opposite of \"sort by count\" for that type).\n */\nexport const valueFacetSort: Record<FacetOption, AggregationSortType> = {\n subject: AggregationSortType.ALPHABETICAL,\n lending: AggregationSortType.ALPHABETICAL,\n mediatype: AggregationSortType.ALPHABETICAL,\n language: AggregationSortType.ALPHABETICAL,\n creator: AggregationSortType.ALPHABETICAL,\n collection: AggregationSortType.ALPHABETICAL,\n year: AggregationSortType.NUMERIC, // Year facets' values should be compared numerically, not lexicographically (year 2001 > year 3)\n program: AggregationSortType.ALPHABETICAL,\n person: AggregationSortType.ALPHABETICAL,\n sponsor: AggregationSortType.ALPHABETICAL,\n};\n\nexport type LendingFacetKey =\n | 'is_lendable'\n | 'is_borrowable'\n | 'available_to_borrow'\n | 'is_browsable'\n | 'available_to_browse'\n | 'is_readable'\n | 'available_to_waitlist';\n\n/**\n * Maps valid lending keys to whether they should be visible in the facet sidebar\n */\nexport const lendingFacetKeysVisibility: Record<LendingFacetKey, boolean> = {\n is_lendable: true,\n is_borrowable: false,\n available_to_borrow: true,\n is_browsable: false,\n available_to_browse: false,\n is_readable: true,\n available_to_waitlist: false,\n};\n\n/**\n * Maps valid, visible lending keys to their facet sidebar display text\n */\nexport const lendingFacetDisplayNames: Partial<\n Record<LendingFacetKey, string>\n> = {\n is_lendable: 'Lending Library',\n available_to_borrow: 'Borrow 14 Days',\n is_readable: 'Always Available',\n};\n\n/**\n * A record of which admin-only collections should be suppressed from being displayed\n * as facets or in an item's list of collections.\n */\nexport const suppressedCollections: Record<string, boolean> = {\n deemphasize: true,\n community: true,\n stream_only: true,\n samples_only: true,\n test_collection: true,\n printdisabled: true,\n 'openlibrary-ol': true,\n nationalemergencylibrary: true,\n china: true,\n americana: true,\n toronto: true,\n};\n\n/**\n * A record of manageable item\n */\nexport interface ManageableItem {\n identifier: string;\n title?: string;\n dateStr?: string;\n date?: string;\n}\n"]}
|
|
@@ -41,6 +41,7 @@ export function forEachFacetBucket(selectedFacets, fn) {
|
|
|
41
41
|
* the `'none'` state in place.
|
|
42
42
|
*/
|
|
43
43
|
export function updateSelectedFacetBucket(selectedFacets, facetType, bucket, omitNoneState = false) {
|
|
44
|
+
var _a;
|
|
44
45
|
const defaultedSelectedFacets = selectedFacets !== null && selectedFacets !== void 0 ? selectedFacets : getDefaultSelectedFacets();
|
|
45
46
|
const newFacets = {
|
|
46
47
|
...defaultedSelectedFacets,
|
|
@@ -50,7 +51,7 @@ export function updateSelectedFacetBucket(selectedFacets, facetType, bucket, omi
|
|
|
50
51
|
},
|
|
51
52
|
};
|
|
52
53
|
if (omitNoneState && bucket.state === 'none') {
|
|
53
|
-
|
|
54
|
+
(_a = newFacets[facetType]) === null || _a === void 0 ? true : delete _a[bucket.key];
|
|
54
55
|
}
|
|
55
56
|
return newFacets;
|
|
56
57
|
}
|
|
@@ -68,6 +69,8 @@ export function updateSelectedFacetBucket(selectedFacets, facetType, bucket, omi
|
|
|
68
69
|
export function cloneSelectedFacets(selectedFacets) {
|
|
69
70
|
const cloneResult = getDefaultSelectedFacets();
|
|
70
71
|
forEachFacetBucket(selectedFacets, (facetType, bucketKey, bucket) => {
|
|
72
|
+
if (!cloneResult[facetType])
|
|
73
|
+
cloneResult[facetType] = {};
|
|
71
74
|
cloneResult[facetType][bucketKey] = bucket;
|
|
72
75
|
});
|
|
73
76
|
return cloneResult;
|
|
@@ -95,12 +98,15 @@ export function cloneSelectedFacets(selectedFacets) {
|
|
|
95
98
|
export function mergeSelectedFacets(destination, source) {
|
|
96
99
|
const mergeResult = cloneSelectedFacets(destination);
|
|
97
100
|
forEachFacetBucket(source, (facetType, bucketKey, bucket) => {
|
|
101
|
+
if (!mergeResult[facetType])
|
|
102
|
+
mergeResult[facetType] = {};
|
|
98
103
|
mergeResult[facetType][bucketKey] = bucket;
|
|
99
104
|
});
|
|
100
105
|
// Normalize any 'none' states on the result (from either source or destination)
|
|
101
106
|
forEachFacetBucket(mergeResult, (facetType, bucketKey, bucket) => {
|
|
107
|
+
var _a;
|
|
102
108
|
if (bucket.state === 'none') {
|
|
103
|
-
|
|
109
|
+
(_a = mergeResult[facetType]) === null || _a === void 0 ? true : delete _a[bucketKey];
|
|
104
110
|
}
|
|
105
111
|
});
|
|
106
112
|
return mergeResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facet-utils.js","sourceRoot":"","sources":["../../../src/utils/facet-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AggregationSortType } from '@internetarchive/search-service';\nimport {\n FacetOption,\n getDefaultSelectedFacets,\n type FacetBucket,\n type SelectedFacets,\n} from '../models';\n\n// This file contains several helper functions designed to make working immutably\n// with SelectedFacet objects and FacetGroups cleaner & easier.\n\n/**\n * Calls the given function for each FacetBucket specified in the given SelectedFacets\n * object. The function is always called with the facet type, bucket key, bucket object,\n * and the given SelectedFacets object.\n *\n * @param selectedFacets The SelectedFacets object whose buckets should be iterated over\n * @param fn The function to apply to each facet bucket.\n *\n * @example\n * forEachFacetBucket(\n * myFacets,\n * (facetType, bucketKey, bucket) => {\n * if (facetType === 'collection' && bucket.state === 'hidden') {\n * console.log(`Excluding any results in the ${bucketKey} collection`);\n * }\n * }\n * );\n */\nexport function forEachFacetBucket(\n selectedFacets: SelectedFacets | undefined,\n fn: (\n facetType: FacetOption,\n bucketKey: string,\n bucket: FacetBucket,\n selectedFacets: SelectedFacets,\n ) => unknown,\n): void {\n if (!selectedFacets) return;\n for (const [facetType, facetBuckets] of Object.entries(selectedFacets)) {\n for (const [bucketKey, bucket] of Object.entries(facetBuckets)) {\n fn(facetType as FacetOption, bucketKey, bucket, selectedFacets);\n }\n }\n}\n\n/**\n * Returns a new SelectedFacets object having only the specified bucket changed to\n * reflect its new provided value. The bucket key is determined from the provided\n * `bucket` itself.\n * @param selectedFacets The SelectedFacets object to produce an updated clone of\n * @param facetType The type of facet to be modified (e.g., 'mediatype', 'subject', ...)\n * @param bucket The new bucket that should be present on the result\n * @param omitNoneState If set to true, the returned object will omit the given\n * bucket entirely if it is updated to state `'none'`. Default is false, which leaves\n * the `'none'` state in place.\n */\nexport function updateSelectedFacetBucket(\n selectedFacets: SelectedFacets | undefined,\n facetType: FacetOption,\n bucket: FacetBucket,\n omitNoneState = false,\n): SelectedFacets {\n const defaultedSelectedFacets = selectedFacets ?? getDefaultSelectedFacets();\n const newFacets = {\n ...defaultedSelectedFacets,\n [facetType]: {\n ...defaultedSelectedFacets[facetType],\n [bucket.key]: bucket,\n },\n };\n\n if (omitNoneState && bucket.state === 'none') {\n delete newFacets[facetType][bucket.key];\n }\n\n return newFacets;\n}\n\n/**\n * Creates a clone of the given SelectedFacets object.\n *\n * Note that the underlying FacetBucket objects are not deep-cloned -- they will\n * be references to the same objects as in the input. However, the objects\n * containing the FacetBuckets for each FacetOption are created anew.\n *\n * If the provided argument is undefined, returns an empty SelectedFacets object.\n *\n * @param selectedFacets The SelectedFacets object to be cloned\n */\nexport function cloneSelectedFacets(\n selectedFacets: SelectedFacets | undefined,\n): SelectedFacets {\n const cloneResult = getDefaultSelectedFacets();\n forEachFacetBucket(selectedFacets, (facetType, bucketKey, bucket) => {\n cloneResult[facetType][bucketKey] = bucket;\n });\n return cloneResult;\n}\n\n/**\n * Creates a new SelectedFacets object representing a merge of the `source` facets object\n * into the `destination` facets object. Any facets existing in `source` take precedence\n * over those in `destination` in the event of conflicts.\n *\n * The resulting SelectedFacets object is normalized to omit any facet buckets whose\n * state is `'none'` in the merged result. Consequently, any facets buckets with state\n * `'none'` in `source` will always be absent from the end result. Likewise, any facet\n * buckets with state `'none'` in `destination` will be absent _unless_ they are also\n * present in `source` with a state of `'selected'` or `'hidden'` (in which case `source`\n * takes precedence as usual).\n *\n * @param source The source of the new facets to merge in. Any facet buckets existing in\n * this `source` object will take precedence over those in `destination` having the same\n * key, if they exist in both. Any facet buckets that are _not_ present in `source` will\n * remain unmodified from their state in `destination`, if they are present there at all.\n * @param destination The destination onto which facets should be merged. Note that this\n * object is _not_ re-used for the return value, but it is conceptually the \"existing base\"\n * onto which the source facets are merged.\n */\nexport function mergeSelectedFacets(\n destination: SelectedFacets | undefined,\n source: SelectedFacets | undefined,\n): SelectedFacets {\n const mergeResult = cloneSelectedFacets(destination);\n forEachFacetBucket(source, (facetType, bucketKey, bucket) => {\n mergeResult[facetType][bucketKey] = bucket;\n });\n\n // Normalize any 'none' states on the result (from either source or destination)\n forEachFacetBucket(mergeResult, (facetType, bucketKey, bucket) => {\n if (bucket.state === 'none') {\n delete mergeResult[facetType][bucketKey];\n }\n });\n\n return mergeResult;\n}\n\n/**\n * Defines the order of states in which to display SelectedFacets buckets\n */\nconst BUCKET_STATE_ORDER = ['selected', 'hidden', 'none'];\n\n/**\n * Sorts the provided FacetBuckets so that:\n * - Any selected items come first\n * - Any hidden items come after all the selected items\n * - Any unselected / unhidden items come last\n *\n * Within each of the above groups, the buckets will be sorted according to\n * the provided sort type, or by their bucket count by default.\n *\n * The sort is performed in-place using `Array.sort`, so the return value is\n * a reference to the same array that was passed in, only sorted.\n *\n * @param buckets The array of facet buckets to sort\n * @param sort (Optional) How buckets within each state group should be sorted.\n * Defaults to `AggregationSortType.COUNT` (i.e., descending by bucket count).\n */\nexport function sortBucketsBySelectionState(\n buckets: FacetBucket[],\n sort = AggregationSortType.COUNT,\n) {\n return buckets.sort((a, b) => {\n const aStateIndex = BUCKET_STATE_ORDER.indexOf(a.state);\n const bStateIndex = BUCKET_STATE_ORDER.indexOf(b.state);\n const stateDiff = aStateIndex - bStateIndex; // Sort bucket states primarily in the order defined by BUCKET_STATE_ORDER\n\n let secondaryDiff;\n if (sort === AggregationSortType.ALPHABETICAL) {\n secondaryDiff = a.key.localeCompare(b.key); // Ascending alphabetically by bucket key\n } else if (sort === AggregationSortType.NUMERIC) {\n secondaryDiff = Number(b.key) - Number(a.key); // Descending numerically by bucket key\n } else {\n secondaryDiff = b.count - a.count; // Descending by bucket count\n }\n\n return stateDiff || secondaryDiff; // Primary sort on state, secondary sort on the given sort type (defaulting to descending count)\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"facet-utils.js","sourceRoot":"","sources":["../../../src/utils/facet-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AggregationSortType } from '@internetarchive/search-service';\nimport {\n FacetOption,\n getDefaultSelectedFacets,\n type FacetBucket,\n type SelectedFacets,\n} from '../models';\n\n// This file contains several helper functions designed to make working immutably\n// with SelectedFacet objects and FacetGroups cleaner & easier.\n\n/**\n * Calls the given function for each FacetBucket specified in the given SelectedFacets\n * object. The function is always called with the facet type, bucket key, bucket object,\n * and the given SelectedFacets object.\n *\n * @param selectedFacets The SelectedFacets object whose buckets should be iterated over\n * @param fn The function to apply to each facet bucket.\n *\n * @example\n * forEachFacetBucket(\n * myFacets,\n * (facetType, bucketKey, bucket) => {\n * if (facetType === 'collection' && bucket.state === 'hidden') {\n * console.log(`Excluding any results in the ${bucketKey} collection`);\n * }\n * }\n * );\n */\nexport function forEachFacetBucket(\n selectedFacets: SelectedFacets | undefined,\n fn: (\n facetType: FacetOption,\n bucketKey: string,\n bucket: FacetBucket,\n selectedFacets: SelectedFacets,\n ) => unknown,\n): void {\n if (!selectedFacets) return;\n for (const [facetType, facetBuckets] of Object.entries(selectedFacets)) {\n for (const [bucketKey, bucket] of Object.entries(facetBuckets)) {\n fn(facetType as FacetOption, bucketKey, bucket, selectedFacets);\n }\n }\n}\n\n/**\n * Returns a new SelectedFacets object having only the specified bucket changed to\n * reflect its new provided value. The bucket key is determined from the provided\n * `bucket` itself.\n * @param selectedFacets The SelectedFacets object to produce an updated clone of\n * @param facetType The type of facet to be modified (e.g., 'mediatype', 'subject', ...)\n * @param bucket The new bucket that should be present on the result\n * @param omitNoneState If set to true, the returned object will omit the given\n * bucket entirely if it is updated to state `'none'`. Default is false, which leaves\n * the `'none'` state in place.\n */\nexport function updateSelectedFacetBucket(\n selectedFacets: SelectedFacets | undefined,\n facetType: FacetOption,\n bucket: FacetBucket,\n omitNoneState = false,\n): SelectedFacets {\n const defaultedSelectedFacets = selectedFacets ?? getDefaultSelectedFacets();\n const newFacets: SelectedFacets = {\n ...defaultedSelectedFacets,\n [facetType]: {\n ...defaultedSelectedFacets[facetType],\n [bucket.key]: bucket,\n },\n };\n\n if (omitNoneState && bucket.state === 'none') {\n delete newFacets[facetType]?.[bucket.key];\n }\n\n return newFacets;\n}\n\n/**\n * Creates a clone of the given SelectedFacets object.\n *\n * Note that the underlying FacetBucket objects are not deep-cloned -- they will\n * be references to the same objects as in the input. However, the objects\n * containing the FacetBuckets for each FacetOption are created anew.\n *\n * If the provided argument is undefined, returns an empty SelectedFacets object.\n *\n * @param selectedFacets The SelectedFacets object to be cloned\n */\nexport function cloneSelectedFacets(\n selectedFacets: SelectedFacets | undefined,\n): SelectedFacets {\n const cloneResult = getDefaultSelectedFacets();\n forEachFacetBucket(selectedFacets, (facetType, bucketKey, bucket) => {\n if (!cloneResult[facetType]) cloneResult[facetType] = {};\n cloneResult[facetType][bucketKey] = bucket;\n });\n return cloneResult;\n}\n\n/**\n * Creates a new SelectedFacets object representing a merge of the `source` facets object\n * into the `destination` facets object. Any facets existing in `source` take precedence\n * over those in `destination` in the event of conflicts.\n *\n * The resulting SelectedFacets object is normalized to omit any facet buckets whose\n * state is `'none'` in the merged result. Consequently, any facets buckets with state\n * `'none'` in `source` will always be absent from the end result. Likewise, any facet\n * buckets with state `'none'` in `destination` will be absent _unless_ they are also\n * present in `source` with a state of `'selected'` or `'hidden'` (in which case `source`\n * takes precedence as usual).\n *\n * @param source The source of the new facets to merge in. Any facet buckets existing in\n * this `source` object will take precedence over those in `destination` having the same\n * key, if they exist in both. Any facet buckets that are _not_ present in `source` will\n * remain unmodified from their state in `destination`, if they are present there at all.\n * @param destination The destination onto which facets should be merged. Note that this\n * object is _not_ re-used for the return value, but it is conceptually the \"existing base\"\n * onto which the source facets are merged.\n */\nexport function mergeSelectedFacets(\n destination: SelectedFacets | undefined,\n source: SelectedFacets | undefined,\n): SelectedFacets {\n const mergeResult = cloneSelectedFacets(destination);\n forEachFacetBucket(source, (facetType, bucketKey, bucket) => {\n if (!mergeResult[facetType]) mergeResult[facetType] = {};\n mergeResult[facetType][bucketKey] = bucket;\n });\n\n // Normalize any 'none' states on the result (from either source or destination)\n forEachFacetBucket(mergeResult, (facetType, bucketKey, bucket) => {\n if (bucket.state === 'none') {\n delete mergeResult[facetType]?.[bucketKey];\n }\n });\n\n return mergeResult;\n}\n\n/**\n * Defines the order of states in which to display SelectedFacets buckets\n */\nconst BUCKET_STATE_ORDER = ['selected', 'hidden', 'none'];\n\n/**\n * Sorts the provided FacetBuckets so that:\n * - Any selected items come first\n * - Any hidden items come after all the selected items\n * - Any unselected / unhidden items come last\n *\n * Within each of the above groups, the buckets will be sorted according to\n * the provided sort type, or by their bucket count by default.\n *\n * The sort is performed in-place using `Array.sort`, so the return value is\n * a reference to the same array that was passed in, only sorted.\n *\n * @param buckets The array of facet buckets to sort\n * @param sort (Optional) How buckets within each state group should be sorted.\n * Defaults to `AggregationSortType.COUNT` (i.e., descending by bucket count).\n */\nexport function sortBucketsBySelectionState(\n buckets: FacetBucket[],\n sort = AggregationSortType.COUNT,\n) {\n return buckets.sort((a, b) => {\n const aStateIndex = BUCKET_STATE_ORDER.indexOf(a.state);\n const bStateIndex = BUCKET_STATE_ORDER.indexOf(b.state);\n const stateDiff = aStateIndex - bStateIndex; // Sort bucket states primarily in the order defined by BUCKET_STATE_ORDER\n\n let secondaryDiff;\n if (sort === AggregationSortType.ALPHABETICAL) {\n secondaryDiff = a.key.localeCompare(b.key); // Ascending alphabetically by bucket key\n } else if (sort === AggregationSortType.NUMERIC) {\n secondaryDiff = Number(b.key) - Number(a.key); // Descending numerically by bucket key\n } else {\n secondaryDiff = b.count - a.count; // Descending by bucket count\n }\n\n return stateDiff || secondaryDiff; // Primary sort on state, secondary sort on the given sort type (defaulting to descending count)\n });\n}\n"]}
|