@adminide-stack/yantra-mobile 12.0.131 → 12.0.132-alpha.0
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/lib/components/CustomDrawer.js +2 -2
- package/lib/components/CustomDrawer.js.map +1 -1
- package/lib/features/apps/AppsCatalog.js +7 -1
- package/lib/features/apps/AppsCatalog.js.map +1 -1
- package/lib/features/apps/nativeSurfaceTwin.js +35 -0
- package/lib/features/apps/nativeSurfaceTwin.js.map +1 -0
- package/lib/features/canvas/CanvasBoardsGrid.js +49 -49
- package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
- package/lib/features/canvas/CanvasExperience.js +69 -28
- package/lib/features/canvas/CanvasExperience.js.map +1 -1
- package/lib/features/canvas/audioEditor/AudioWaveform.js +1 -1
- package/lib/features/canvas/designCatalog.js +63 -39
- package/lib/features/canvas/designCatalog.js.map +1 -1
- package/lib/features/canvas/designCategories.js +56 -0
- package/lib/features/canvas/designCategories.js.map +1 -1
- package/lib/features/canvas/generator/DirectorSheet.js +3 -2
- package/lib/features/canvas/generator/DirectorSheet.js.map +1 -1
- package/lib/features/canvas/home/HeroComposer.js +165 -76
- package/lib/features/canvas/home/HeroComposer.js.map +1 -1
- package/lib/features/canvas/home/HeroMonitor.js +75 -46
- package/lib/features/canvas/home/HeroMonitor.js.map +1 -1
- package/lib/features/canvas/home/TemplatesGallery.js +273 -138
- package/lib/features/canvas/home/TemplatesGallery.js.map +1 -1
- package/lib/features/canvas/home/templatesGallerySources.js +221 -0
- package/lib/features/canvas/home/templatesGallerySources.js.map +1 -0
- package/lib/features/canvas/homeWork.js +12 -11
- package/lib/features/canvas/homeWork.js.map +1 -1
- package/lib/features/canvas/lazyEditors.js +51 -0
- package/lib/features/canvas/lazyEditors.js.map +1 -0
- package/lib/features/canvas/rankedCatalogSearch.js +33 -23
- package/lib/features/canvas/rankedCatalogSearch.js.map +1 -1
- package/lib/features/canvas/set/SetViewportWebView.js +1 -1
- package/lib/features/canvas/set/agent/tools.js +1 -1
- package/lib/features/canvas/studioCatalog.js +2 -2
- package/lib/features/canvas/studioCatalog.js.map +1 -1
- package/lib/features/canvas/templateSearch.js +8 -1
- package/lib/features/canvas/templateSearch.js.map +1 -1
- package/lib/features/canvas/videoEditor/BlurBoxOverlay.js +1 -1
- package/lib/features/design/DesignEditorExperience.js +103 -29
- package/lib/features/design/DesignEditorExperience.js.map +1 -1
- package/lib/features/design/DesignExperience.js +4 -3
- package/lib/features/design/DesignExperience.js.map +1 -1
- package/lib/features/design/doc/aiDesign.js +1 -1
- package/lib/features/design/doc/aiDesign.js.map +1 -1
- package/lib/features/design/doc/artifacts.js +40 -13
- package/lib/features/design/doc/artifacts.js.map +1 -1
- package/lib/features/design/doc/chart.js +387 -13
- package/lib/features/design/doc/chart.js.map +1 -1
- package/lib/features/design/doc/copyStyle.js +47 -0
- package/lib/features/design/doc/copyStyle.js.map +1 -0
- package/lib/features/design/doc/docOps.js +22 -4
- package/lib/features/design/doc/docOps.js.map +1 -1
- package/lib/features/design/doc/geometry.js +32 -18
- package/lib/features/design/doc/geometry.js.map +1 -1
- package/lib/features/design/doc/newDoc.js +5 -1
- package/lib/features/design/doc/newDoc.js.map +1 -1
- package/lib/features/design/doc/resize.js +101 -0
- package/lib/features/design/doc/resize.js.map +1 -0
- package/lib/features/design/doc/sizes.js +15 -2
- package/lib/features/design/doc/sizes.js.map +1 -1
- package/lib/features/design/editor/ChartDataPanel.js +49 -9
- package/lib/features/design/editor/ChartDataPanel.js.map +1 -1
- package/lib/features/design/editor/CropOverlay.js +1 -1
- package/lib/features/design/editor/DesignCanvas.js +14 -13
- package/lib/features/design/editor/DesignCanvas.js.map +1 -1
- package/lib/features/design/editor/ExportSheet.js +8 -4
- package/lib/features/design/editor/ExportSheet.js.map +1 -1
- package/lib/features/design/editor/LayerTools.js +37 -5
- package/lib/features/design/editor/LayerTools.js.map +1 -1
- package/lib/features/design/editor/Slideshow.js +30 -5
- package/lib/features/design/editor/Slideshow.js.map +1 -1
- package/lib/features/design/editor/useDesignSave.js +21 -36
- package/lib/features/design/editor/useDesignSave.js.map +1 -1
- package/lib/features/design/export/exportDesign.js +3 -1
- package/lib/features/design/export/exportDesign.js.map +1 -1
- package/lib/features/design/home/DesignHome.js +7 -2
- package/lib/features/design/home/DesignHome.js.map +1 -1
- package/lib/features/design/render/DesignPageView.js +1 -1
- package/lib/features/design/render/DesignPageView.js.map +1 -1
- package/lib/features/design/render/PageCapture.js +11 -10
- package/lib/features/design/render/PageCapture.js.map +1 -1
- package/lib/features/design/render/fontRegistry.js +27 -3
- package/lib/features/design/render/fontRegistry.js.map +1 -1
- package/lib/features/design/render/svgParts.js +27 -74
- package/lib/features/design/render/svgParts.js.map +1 -1
- package/lib/features/devices/brands/qnScale.js +7 -2
- package/lib/features/devices/brands/qnScale.js.map +1 -1
- package/lib/features/devices/brands/uuids.js +2 -1
- package/lib/features/devices/brands/uuids.js.map +1 -1
- package/lib/features/devices/devices.js +2 -1
- package/lib/features/devices/devices.js.map +1 -1
- package/lib/features/docs/DocBlockRow.js +1 -1
- package/lib/features/docs/docArtifacts.js +2 -2
- package/lib/features/docs/docArtifacts.js.map +1 -1
- package/lib/features/health/healthSync.js +3 -1
- package/lib/features/health/healthSync.js.map +1 -1
- package/lib/features/health/nativeHealth.js +8 -0
- package/lib/features/health/nativeHealth.js.map +1 -0
- package/lib/features/links/openInApp.js +11 -1
- package/lib/features/links/openInApp.js.map +1 -1
- package/lib/features/webbuilder/WebBuilderExperience.js +135 -28
- package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
- package/lib/features/webbuilder/buildFragments.js +14 -6
- package/lib/features/webbuilder/buildFragments.js.map +1 -1
- package/lib/features/webbuilder/components/PreviewFrame.js +28 -3
- package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -1
- package/lib/features/webbuilder/components/PreviewScreen.js +1 -1
- package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -1
- package/lib/features/webbuilder/components/ProjectChat.js +24 -5
- package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
- package/lib/features/webbuilder/components/ProjectsScreen.js +18 -2
- package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -1
- package/lib/features/webbuilder/components/ui.js +20 -6
- package/lib/features/webbuilder/components/ui.js.map +1 -1
- package/lib/features/webbuilder/exportCode.js +52 -0
- package/lib/features/webbuilder/exportCode.js.map +1 -0
- package/lib/features/webbuilder/siteAddress.js +71 -0
- package/lib/features/webbuilder/siteAddress.js.map +1 -0
- package/lib/features/webbuilder/widgetBlocks.js +30 -0
- package/lib/features/webbuilder/widgetBlocks.js.map +1 -0
- package/lib/screens/Chat/index.js +5 -6
- package/lib/screens/Chat/index.js.map +1 -1
- package/lib/screens/ChatHistory/index.js +3 -2
- package/lib/screens/ChatHistory/index.js.map +1 -1
- package/lib/screens/Home/HomeScreen.js +20 -4
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/WebBuilderCodePrewarm.js +18 -0
- package/lib/screens/Home/components/WebBuilderCodePrewarm.js.map +1 -0
- package/lib/screens/WebBuilderNative/index.js +1 -1
- package/lib/screens/WebBuilderNative/index.js.map +1 -1
- package/lib/screens/WebBuilderNative/keepAlive.js +112 -0
- package/lib/screens/WebBuilderNative/keepAlive.js.map +1 -0
- package/lib/screens/WebBuilderNative/runningBuilds.js +40 -0
- package/lib/screens/WebBuilderNative/runningBuilds.js.map +1 -0
- package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js +57 -0
- package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js.map +1 -0
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +73 -14
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js +143 -34
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +17 -5
- package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
- package/lib/screens/WebBuilderNative/versionUndo.js +144 -0
- package/lib/screens/WebBuilderNative/versionUndo.js.map +1 -0
- package/lib/screens/WebBuilderNative/webbuilderSnapshotKey.js +1 -0
- package/lib/screens/WebBuilderNative/webbuilderSnapshotKey.js.map +1 -0
- package/lib/screens/WebBuilderNative/webbuilderTransport.js +90 -6
- package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templateSearch.js","sources":["../../../src/features/canvas/templateSearch.ts"],"sourcesContent":["/**\n * Template search: what a person (or the brain) typed -> the templates that fit\n * it, best first. One implementation for every page that searches a catalog\n * (the Templates page, the chat templates card, the image and audio lanes).\n *\n * The catalog backend matches every word of a search as a substring and keeps\n * only rows that hold ALL of them, unranked. That is a fine way to FIND\n * candidates and a poor way to choose between them:\n *\n * - Style and vibe words (\"clean modern fancy\") filtered a business card search\n * down to nothing, because no row says \"fancy\".\n * - One loose word carried a whole phrase: \"store opening flyer\" fell back to\n * \"opening\" and listed \"Seven opening lines that make people stop and read\".\n *\n * So a query is read here first: filler (\"templates for my\") and the category's\n * own name (\"flyer\") are left out, typos of either are recognised, and what is\n * left splits into SUBJECT words (what the template is about: coffee shop,\n * roadmap, 2030) and STYLE words (how it looks: clean, modern, fancy). Each\n * word brings a few near words (store ~ shop, fancy ~ elegant ~ luxury).\n *\n * Then each candidate is scored on the whole query: subject words in its title\n * or tags (its real subject) count most, the same words only in its visual\n * summary count little, style words rank and never exclude, and subject words\n * that sit together in the title (\"coffee shop\") score as a phrase. A template\n * is an `exact` match when every subject word is its real subject (a style-only\n * query: at least half the looks asked for), `close` when only part of the\n * query fits, and anything else is not a match at all - the category's own\n * best templates follow the matches as `popular`, so a search never comes back\n * empty while the category has templates.\n *\n * Pure: no I/O. The catalog reads that feed it live in ./rankedCatalogSearch.\n *\n * Native port of surface-kit `templateCatalogs/templateSearch` (kit 0.43). Kept\n * Hermes-safe: no Unicode property escapes in literals (built in a try with an\n * ASCII + Latin fallback) and `normalize` guarded.\n */\n\n/** Builds a regex from a Unicode-property source, or its fallback where the engine lacks them. */\nfunction unicodeRegExp(source: string, flags: string, fallback: RegExp): RegExp {\n try {\n return new RegExp(source, `${flags}u`);\n } catch {\n return fallback;\n }\n}\n\n/** A run of anything but letters and digits. */\nexport const NON_WORD: RegExp = unicodeRegExp('[^\\\\p{L}\\\\p{N}]+', '', /[^A-Za-z0-9\\u00C0-\\u024F]+/);\nconst NON_WORD_ALL: RegExp = unicodeRegExp('[^\\\\p{L}\\\\p{N}]+', 'g', /[^A-Za-z0-9\\u00C0-\\u024F]+/g);\n/** Text that ends in a letter or digit (a word still being typed). */\nconst WORD_END: RegExp = unicodeRegExp('[\\\\p{L}\\\\p{N}]$', '', /[A-Za-z0-9\\u00C0-\\u024F]$/);\n\n/** How a listed template relates to the search. */\nexport type TemplateMatch = 'exact' | 'close' | 'popular';\n\nexport type TemplateConceptKind = 'subject' | 'style';\n\n/** One word of a query, with the near words that count for it. */\nexport interface TemplateQueryConcept {\n /** The word as read (lower case, typo fixed). */\n word: string;\n kind: TemplateConceptKind;\n /** Its stem first, then its near words' stems; a multi-word term (\"real estate\") is space-joined. */\n terms: string[];\n /**\n * The last word of a query still being typed (\"coff\"): it also matches the words it starts.\n * Only an unknown word of 3+ letters at the very end, so a finished query never matches loosely.\n */\n prefix?: boolean;\n /**\n * A word the reader does not know, perhaps misspelled (\"cofee\"): it also matches a word one\n * typo away (\"coffee\"). Known words never do, so \"wedding\" does not match \"welding\".\n */\n typo?: boolean;\n}\n\nexport interface TemplateQuery {\n /** What was typed, whitespace collapsed. */\n text: string;\n subjects: TemplateQueryConcept[];\n styles: TemplateQueryConcept[];\n /** Words left out: filler, the category's own name, and typos of either. */\n ignored: string[];\n /** Nothing searchable was typed: list the category as it is. */\n empty: boolean;\n}\n\nexport interface TemplateQueryOptions {\n /**\n * Words and phrases that name the category being searched (\"business card\",\n * \"flyer\", \"slides\"): a search inside the category says nothing by them.\n */\n categoryWords?: readonly string[];\n}\n\n/** At most this many words of one query count; the rest are ignored. */\nconst MAX_CONCEPTS = 8;\n\n// ─── Words ──────────────────────────────────────────────────────────────────\n\n/** Words that say nothing about which template: \"show me some templates for my ...\". */\nconst FILLER = new Set(\n (\n 'a an the and or of for in on at to from by with without about into onto over under as is are be ' +\n 'my our your their his her its me i we you us it this that these those some any all every each ' +\n 'one ones template templates design designs designed idea ideas example examples sample samples ' +\n 'option options show find search make create build need needs want looking look get give please ' +\n 'new best good great nice cool really very something kind type types version style styles styled ' +\n 'theme themed based using use free just also like more other etc page pages custom editable own ' +\n 'quick easy pro printable print ready can could would should will do does help thanks hi hello ' +\n 'want wanted some something someone pick choose choice list see view'\n ).split(' '),\n);\n\n/**\n * How a template looks, as people say it. A style word ranks; it never excludes.\n * Each group is a set of near words: any of them counts for any other.\n */\n// prettier-ignore\nconst STYLE_GROUPS: readonly (readonly string[])[] = [\n ['clean', 'minimal', 'minimalist', 'simple', 'crisp', 'tidy', 'uncluttered'],\n ['minimal', 'minimalist', 'simple', 'clean', 'minimalistic', 'minimalism', 'plain'],\n ['simple', 'minimal', 'minimalist', 'clean', 'basic', 'plain'],\n ['modern', 'contemporary', 'sleek', 'trendy'],\n ['fancy', 'elegant', 'luxury', 'gold', 'premium', 'luxurious', 'golden', 'sophisticated', 'classy', 'glamorous', 'chic', 'ornate', 'upscale'],\n ['elegant', 'sophisticated', 'luxury', 'classy', 'refined', 'graceful', 'chic', 'elegance', 'fancy'],\n ['luxury', 'luxurious', 'premium', 'gold', 'elegant', 'upscale', 'golden', 'fancy'],\n ['bold', 'vibrant', 'striking', 'strong', 'punchy', 'loud'],\n ['playful', 'fun', 'cute', 'colorful', 'whimsical', 'cheerful', 'quirky', 'cartoon'],\n ['fun', 'playful', 'colorful', 'cheerful', 'cute'],\n ['cute', 'playful', 'adorable', 'sweet', 'kawaii'],\n ['warm', 'cozy', 'earthy', 'beige', 'cream', 'terracotta'],\n ['professional', 'corporate', 'formal', 'businesslike'],\n ['corporate', 'professional', 'formal'],\n ['formal', 'professional', 'classic'],\n ['classic', 'timeless', 'traditional', 'vintage'],\n ['vintage', 'retro', 'antique', 'nostalgic', 'classic', 'risograph'],\n ['retro', 'vintage', 'groovy', 'nostalgic'],\n ['rustic', 'kraft', 'wooden', 'farmhouse', 'earthy'],\n ['creative', 'artistic', 'unique', 'abstract'],\n ['colorful', 'vibrant', 'bright', 'colourful', 'rainbow', 'multicolor', 'multicolored'],\n ['bright', 'vibrant', 'colorful', 'neon'],\n ['dark', 'black', 'moody'],\n ['light', 'white', 'airy'],\n ['pastel', 'soft', 'muted', 'gentle'],\n ['soft', 'pastel', 'gentle', 'muted'],\n ['floral', 'flower', 'botanical', 'blossom'],\n ['geometric', 'shapes', 'angular', 'lines'],\n ['abstract', 'shapes', 'artistic'],\n ['gradient', 'ombre'],\n ['watercolor', 'watercolour', 'painted', 'painterly'],\n ['illustrated', 'illustration', 'illustrative', 'drawn', 'handdrawn', 'doodle', 'cartoon', 'sketch'],\n ['futuristic', 'neon', 'cyber', 'scifi'],\n ['feminine', 'pink', 'girly', 'delicate'],\n ['masculine', 'rugged'],\n ['beautiful', 'elegant', 'pretty', 'stunning', 'lovely', 'aesthetic', 'gorgeous'],\n ['stylish', 'chic', 'trendy', 'fashionable'],\n ['friendly', 'approachable', 'welcoming', 'casual'],\n ['casual', 'relaxed', 'friendly'],\n ['calm', 'serene', 'peaceful', 'zen', 'tranquil'],\n ['monochrome', 'monochromatic', 'grayscale'],\n ['grunge', 'textured', 'distressed'],\n ['handwritten', 'script', 'calligraphy'],\n ['typographic', 'typography', 'lettering'],\n ['sleek', 'modern', 'smooth', 'minimal'],\n ['gray', 'grey'],\n ['gold', 'golden'],\n ['purple', 'violet', 'plum', 'lavender'],\n ['beige', 'cream', 'ivory', 'tan'],\n ['black'], ['white'], ['silver'], ['blue'], ['navy'], ['green'], ['red'], ['pink'], ['yellow'], ['orange'],\n ['brown'], ['teal'], ['turquoise'], ['mint'], ['maroon'], ['burgundy'], ['peach'], ['coral'], ['olive'],\n ['sage'], ['mustard'], ['emerald'], ['neon'],\n];\n\n/**\n * What a template is about, with the few near words that mean the same thing\n * in a catalog title (\"store\" ~ \"shop\"). Words not listed are subjects too;\n * they just bring no near words.\n */\n// prettier-ignore\nconst SUBJECT_GROUPS: readonly (readonly string[])[] = [\n ['store', 'shop', 'boutique', 'retail', 'storefront'],\n ['shop', 'store', 'boutique', 'retail', 'shopping'],\n ['opening', 'grand opening', 'launch', 'inauguration', 'reopening'],\n ['coffee', 'cafe', 'espresso', 'barista', 'coffeehouse', 'latte'],\n ['cafe', 'coffee', 'coffeehouse', 'bistro'],\n ['bakery', 'baker', 'baking', 'bakeshop', 'pastry', 'patisserie', 'bread', 'cake', 'cupcake'],\n ['cake', 'cupcake', 'bakery', 'dessert', 'pastry'],\n ['restaurant', 'dining', 'diner', 'bistro', 'eatery', 'cuisine'],\n ['food', 'culinary', 'meal', 'kitchen', 'cooking'],\n ['chef', 'cook', 'culinary', 'catering'],\n ['roadmap', 'road map', 'timeline', 'milestone'],\n ['ice cream', 'gelato', 'dessert'],\n ['social media', 'instagram', 'facebook', 'tiktok'],\n ['strategy', 'strategic', 'planning'],\n ['plan', 'planning', 'planner'],\n ['real estate', 'realtor', 'realty', 'property', 'housing'],\n ['realtor', 'real estate', 'realty', 'property'],\n ['home', 'house'],\n ['lawyer', 'attorney', 'law', 'legal'],\n ['attorney', 'lawyer', 'law', 'legal'],\n ['doctor', 'medical', 'clinic', 'physician', 'healthcare'],\n ['dentist', 'dental', 'orthodontist'],\n ['health', 'healthcare', 'wellness', 'medical'],\n ['fitness', 'gym', 'workout', 'trainer', 'exercise'],\n ['gym', 'fitness', 'workout'],\n ['yoga', 'pilates', 'meditation'],\n ['wedding', 'bridal', 'bride', 'marriage'],\n ['birthday', 'bday'],\n ['party', 'celebration', 'fiesta'],\n ['photography', 'photographer', 'photo', 'camera'],\n ['photographer', 'photography', 'photo'],\n ['beauty', 'salon', 'makeup', 'cosmetics', 'spa'],\n ['salon', 'hair', 'hairdresser', 'hairstylist', 'beauty'],\n ['barber', 'barbershop', 'hair'],\n ['technology', 'tech', 'software', 'digital'],\n ['tech', 'technology', 'software'],\n ['startup', 'venture', 'founder'],\n ['pitch', 'investor', 'funding', 'fundraising'],\n ['marketing', 'advertising', 'campaign', 'promotion'],\n ['brand', 'branding', 'identity'],\n ['sale', 'discount', 'promo', 'offer', 'deal', 'clearance'],\n ['church', 'worship', 'ministry', 'faith'],\n ['school', 'education', 'classroom', 'student', 'teacher'],\n ['education', 'school', 'learning', 'teaching', 'classroom'],\n ['music', 'band', 'concert', 'musician'],\n ['travel', 'trip', 'tourism', 'vacation', 'tour'],\n ['hotel', 'resort', 'hospitality'],\n ['cleaning', 'cleaner', 'janitorial', 'housekeeping', 'maid'],\n ['construction', 'builder', 'contractor', 'renovation'],\n ['car', 'auto', 'automotive', 'mechanic', 'garage', 'vehicle'],\n ['pet', 'dog', 'cat', 'veterinary', 'vet', 'grooming'],\n ['finance', 'financial', 'accounting', 'accountant', 'bank', 'investment'],\n ['accountant', 'accounting', 'bookkeeping', 'tax'],\n ['consulting', 'consultant', 'advisory', 'advisor'],\n ['charity', 'nonprofit', 'fundraiser', 'donation', 'volunteer'],\n ['fashion', 'clothing', 'apparel'],\n ['garden', 'gardening', 'landscaping', 'lawn'],\n ['event', 'conference', 'summit', 'meetup'],\n ['christmas', 'xmas'],\n ['kids', 'children', 'child'],\n ['report', 'review', 'summary'],\n ['webinar', 'workshop', 'seminar'],\n ['farm', 'farming', 'agriculture'],\n ['sustainability', 'sustainable', 'environment', 'eco', 'climate'],\n ['science', 'research', 'laboratory'],\n ['art', 'artist', 'gallery'],\n ['coach', 'coaching', 'mentor'],\n ['therapy', 'therapist', 'counseling', 'counselor'],\n ['massage', 'spa', 'therapist'],\n ['plumber', 'plumbing', 'handyman', 'repair'],\n ['delivery', 'courier', 'logistics', 'shipping'],\n ['bar', 'pub', 'cocktail', 'brewery'],\n ['wine', 'winery', 'vineyard'],\n ['pizza', 'pizzeria'],\n ['tea', 'teahouse'],\n];\n\n/**\n * The words a category is named by, wherever a person may type them: \"logo\n * templates\" inside Logos is just \"templates\". Keyed by the category id (the\n * gallery group key); a caller with another key passes its own words.\n */\n// prettier-ignore\nexport const TEMPLATE_CATEGORY_WORDS: Readonly<Record<string, readonly string[]>> = {\n slideDeck: ['presentation', 'slide', 'slides', 'deck', 'ppt', 'pptx', 'powerpoint', 'keynote', 'slideshow', 'google slides'],\n socialPost: ['social media post', 'social post', 'post', 'posts', 'social media'],\n carousel: ['carousel', 'carousels', 'instagram carousel'],\n flyer: ['flyer', 'flier', 'poster', 'leaflet', 'handout'],\n businessCard: ['business card', 'visiting card', 'calling card', 'card'],\n logo: ['logo', 'logos', 'logotype', 'emblem'],\n banner: ['banner'],\n brochure: ['brochure', 'pamphlet', 'trifold', 'tri fold'],\n branding: ['branding kit', 'stationery'],\n certificate: ['certificate'],\n worksheet: ['worksheet'],\n proposal: ['proposal'],\n newsletter: ['newsletter'],\n menu: ['menu'],\n infographic: ['infographic'],\n imageGeneration: ['image', 'picture', 'prompt'],\n videoGeneration: ['video', 'clip', 'reel'],\n audioGeneration: ['audio', 'sound', 'song', 'track'],\n};\n\n// ─── Text ───────────────────────────────────────────────────────────────────\n\n/** Words that end in \"s\" without being plurals (or whose plural stem collides with filler). */\n// prettier-ignore\nconst KEEP_S = new Set([\n 'news', 'series', 'species', 'physics', 'mathematics', 'economics', 'analytics', 'ethics', 'politics',\n 'athletics', 'aesthetics', 'lyrics', 'diabetes', 'canvas', 'christmas', 'xmas', 'texas', 'paris', 'atlas',\n 'gas', 'bus', 'plus', 'yes', 'its', 'this', 'thus', 'chaos', 'cosmos', 'logistics', 'graphics', 'kids',\n]);\n\n/** A word reduced to the form both sides compare in: plurals folded (\"bakeries\" -> \"bakery\"). */\nexport function stemWord(word: string): string {\n const w = word.toLowerCase();\n if (w.length <= 3 || /\\d/.test(w) || KEEP_S.has(w)) return w;\n if (w.endsWith('ies') && w.length > 4) return `${w.slice(0, -3)}y`;\n if (/(ss|us|is)$/.test(w)) return w;\n if (/(sses|ches|shes|xes|zes)$/.test(w)) return w.slice(0, -2);\n if (w.endsWith('s')) return w.slice(0, -1);\n return w;\n}\n\n/** Lower case, accents off (\"Café\" -> \"cafe\"), curly apostrophes straight, \"&\" read as \"and\". */\nfunction fold(text: string): string {\n let normalized = text;\n try {\n if (typeof text.normalize === 'function') normalized = text.normalize('NFKD');\n } catch {\n // An engine without normalization data: accents stay on.\n }\n return normalized\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[\\u2018\\u2019\\u02bc]/g, \"'\")\n .replace(/&/g, ' and ')\n .toLowerCase();\n}\n\n/**\n * Words of a text, stemmed. Single letters drop out (the \"s\" of \"women's\"); so\n * do single digits (\"5 tips\"), years and codes stay (\"2030\").\n */\nexport function searchWords(text: string): string[] {\n return fold(text)\n .split(NON_WORD)\n .filter((w) => w.length > 1)\n .map(stemWord);\n}\n\n/** Restricted Damerau-Levenshtein distance, giving up past `max`. */\nfunction editDistance(a: string, b: string, max: number): number {\n if (Math.abs(a.length - b.length) > max) return max + 1;\n const rows: number[][] = [];\n for (let i = 0; i <= a.length; i++) {\n rows.push([i]);\n }\n for (let j = 1; j <= b.length; j++) rows[0][j] = j;\n for (let i = 1; i <= a.length; i++) {\n let best = Infinity;\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n let d = Math.min(rows[i - 1][j] + 1, rows[i][j - 1] + 1, rows[i - 1][j - 1] + cost);\n if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1])\n d = Math.min(d, rows[i - 2][j - 2] + 1);\n rows[i][j] = d;\n if (d < best) best = d;\n }\n if (best > max) return max + 1;\n }\n return rows[a.length][b.length];\n}\n\n/**\n * Near words, built once: a group's first word brings the rest of its group; a\n * word that heads no group brings the heads of the groups it is in. So \"gold\"\n * brings \"golden\" (its own group), not every luxury word, while \"minimalist\"\n * brings \"clean\", \"minimal\" and \"simple\".\n */\nfunction nearMap(groups: readonly (readonly string[])[]): Map<string, string[]> {\n const own = new Map<string, string[]>();\n const heads = new Map<string, string[]>();\n const push = (map: Map<string, string[]>, key: string, value: string) => {\n const list = map.get(key) ?? [];\n if (value !== key && !list.includes(value)) list.push(value);\n map.set(key, list);\n };\n for (const group of groups) {\n const [head, ...rest] = group.map((w) => searchWords(w).join(' '));\n if (!own.has(head)) own.set(head, []);\n for (const w of rest) {\n push(own, head, w);\n push(heads, w, head);\n }\n }\n const map = new Map<string, string[]>();\n for (const [word, list] of heads) if (!own.has(word)) map.set(word, list);\n for (const [word, list] of own) map.set(word, list);\n return map;\n}\n\nconst STYLE_NEAR = nearMap(STYLE_GROUPS);\nconst SUBJECT_NEAR = nearMap(SUBJECT_GROUPS);\n\n/** Words as listed, by stem: what a fixed typo reads as. */\nconst LISTED = new Map<string, string>();\n/** Words a typo may be read as: filler, style words and category names. */\nconst TYPO_TARGETS = new Set<string>();\n/** Subject words a LONG typo may be read as (\"resturant\"): few real long words are one typo from another. */\nconst LONG_TYPO_TARGETS = new Set<string>();\n/** Every word the reader knows; a known word is never \"fixed\". */\nconst KNOWN = new Set<string>();\n{\n const add = (w: string, target: boolean) => {\n for (const part of fold(w).split(NON_WORD)) {\n if (part.length < 2) continue;\n const stem = stemWord(part);\n KNOWN.add(stem);\n if (!LISTED.has(stem)) LISTED.set(stem, part);\n if (target) TYPO_TARGETS.add(stem);\n }\n };\n FILLER.forEach((w) => add(w, true));\n for (const g of STYLE_GROUPS) g.forEach((w) => add(w, true));\n for (const words of Object.values(TEMPLATE_CATEGORY_WORDS)) words.forEach((w) => add(w, true));\n ['templates', 'business'].forEach((w) => add(w, true));\n for (const g of SUBJECT_GROUPS) g.forEach((w) => add(w, false));\n for (const g of SUBJECT_GROUPS)\n for (const w of g) if (!w.includes(' ') && w.length >= 8) LONG_TYPO_TARGETS.add(stemWord(w));\n}\n\n/**\n * A word the reader does not know, read as the filler, style or category word\n * it is a typo of (\"templtes\" -> \"templates\", \"elegent\" -> \"elegant\",\n * \"buisness\" -> \"business\"), or as the long subject word it is one typo from\n * (\"resturant\" -> \"restaurant\"). Short words are never changed, the first\n * letter must agree, and a short word never becomes a subject word: \"stone\"\n * stays \"stone\", it is not a typo of \"store\".\n */\nfunction fixTypo(stem: string): string {\n if (stem.length < 5 || /\\d/.test(stem) || KNOWN.has(stem)) return stem;\n let best = '';\n let bestDistance = Infinity;\n const consider = (targets: Set<string>, max: number) => {\n for (const known of targets) {\n if (known[0] !== stem[0] || known.length < 4) continue;\n const d = editDistance(stem, known, max);\n if (d <= max && d < bestDistance) {\n best = known;\n bestDistance = d;\n }\n }\n };\n consider(TYPO_TARGETS, stem.length >= 8 ? 2 : 1);\n if (stem.length >= 8) consider(LONG_TYPO_TARGETS, 1);\n return best || stem;\n}\n\n// ─── Query ──────────────────────────────────────────────────────────────────\n\ninterface Token {\n /** As typed (folded). */\n raw: string;\n stem: string;\n}\n\n/** Remove every run of `phrase` (stems) from `tokens`, typos of it included. */\nfunction removePhrase(tokens: Token[], phrase: string[], removed: string[]): Token[] {\n if (phrase.length === 0) return tokens;\n const out: Token[] = [];\n for (let i = 0; i < tokens.length; ) {\n const hit =\n i + phrase.length <= tokens.length &&\n phrase.every((p, k) => tokens[i + k].stem === p || fixTypo(tokens[i + k].stem) === p);\n if (hit) {\n removed.push(\n tokens\n .slice(i, i + phrase.length)\n .map((t) => t.raw)\n .join(' '),\n );\n i += phrase.length;\n } else {\n out.push(tokens[i]);\n i += 1;\n }\n }\n return out;\n}\n\n/** Every multi-word term the reader knows (\"real estate\", \"grand opening\"). */\nconst PHRASES: Set<string> = new Set(\n [...STYLE_NEAR.keys(), ...SUBJECT_NEAR.keys(), ...[...STYLE_NEAR.values(), ...SUBJECT_NEAR.values()].flat()].filter(\n (term) => term.includes(' '),\n ),\n);\n\n/** Two words that make a known phrase are read as one: \"real estate\" is one subject, not two. */\nfunction joinPhrases(tokens: Token[]): Token[] {\n const out: Token[] = [];\n for (let i = 0; i < tokens.length; i++) {\n const next = tokens[i + 1];\n if (next && PHRASES.has(`${tokens[i].stem} ${next.stem}`)) {\n out.push({ raw: `${tokens[i].raw} ${next.raw}`, stem: `${tokens[i].stem} ${next.stem}` });\n i += 1;\n } else {\n out.push(tokens[i]);\n }\n }\n return out;\n}\n\n/** Read a typed query: its subject and style words, and what was left out. */\nexport function parseTemplateQuery(text: string, options: TemplateQueryOptions = {}): TemplateQuery {\n const typed = (text ?? '').replace(/\\s+/g, ' ').trim();\n const ignored: string[] = [];\n let tokens: Token[] = fold(typed)\n .split(NON_WORD)\n .filter((w) => w.length > 1)\n .map((raw) => ({ raw, stem: stemWord(raw) }));\n // The category's own name, longest phrase first: \"business card\" before \"card\".\n const phrases = [...(options.categoryWords ?? []), 'template']\n .map((p) => searchWords(p))\n .filter((p) => p.length > 0)\n .sort((a, b) => b.length - a.length);\n for (const phrase of phrases) tokens = removePhrase(tokens, phrase, ignored);\n tokens = joinPhrases(tokens);\n // Still typing: a query that does not end in a space or punctuation has a last word in progress.\n const typing = WORD_END.test(text ?? '');\n const last = tokens[tokens.length - 1];\n\n const subjects: TemplateQueryConcept[] = [];\n const styles: TemplateQueryConcept[] = [];\n const seen = new Set<string>();\n for (const token of tokens) {\n const stem = token.stem.includes(' ') ? token.stem : fixTypo(token.stem);\n const fixed = stem !== token.stem;\n if (FILLER.has(stem) || FILLER.has(LISTED.get(stem) ?? '')) {\n ignored.push(token.raw);\n continue;\n }\n if (seen.has(stem)) continue;\n if (subjects.length + styles.length >= MAX_CONCEPTS) {\n ignored.push(token.raw);\n continue;\n }\n seen.add(stem);\n const word = fixed ? (LISTED.get(stem) ?? stem) : token.raw;\n if (STYLE_NEAR.has(stem)) {\n styles.push({ word, kind: 'style', terms: [stem, ...(STYLE_NEAR.get(stem) ?? [])] });\n } else {\n const unknown = !fixed && !KNOWN.has(stem) && !stem.includes(' ') && !/\\d/.test(stem);\n const prefix = unknown && typing && token === last && stem.length >= 3;\n const typo = unknown && stem.length >= 5;\n subjects.push({\n word,\n kind: 'subject',\n terms: [stem, ...(SUBJECT_NEAR.get(stem) ?? [])],\n ...(prefix ? { prefix } : {}),\n ...(typo ? { typo } : {}),\n });\n }\n }\n return { text: typed, subjects, styles, ignored, empty: subjects.length + styles.length === 0 };\n}\n\n/** The words that were read, as a person can be shown them: \"coffee shop modern\". */\nexport function templateQueryLabel(query: TemplateQuery): string {\n return [...query.subjects, ...query.styles].map((c) => c.word).join(' ');\n}\n\n// ─── Candidate reads ────────────────────────────────────────────────────────\n\n/** One backend read that finds candidates: rows holding every word of `words`. */\nexport interface TemplateSearchRead {\n /** The words of the read: the backend keeps rows holding every one of them (as part of any word). */\n words: string[];\n /** The query terms (stems) every row this read returns holds somewhere. */\n terms: string[];\n /** Read deep (a word of the query) or shallow (a near word). */\n wide: boolean;\n /**\n * 1: the query's own words. 2: a near word, read only when its word's own read came back thin\n * (`concept`): \"fancy\" finds no row, so \"elegant\" and \"luxury\" are read; \"shop\" finds plenty.\n */\n stage: 1 | 2;\n /** The word (its stem) a single-word read is for: its own word (stage 1) or a near word of it (stage 2). */\n concept?: string;\n}\n\n/**\n * What the backend is asked for a concept's own word. It matches substrings, so\n * a stem that is the start of the typed word (\"shop\" of \"shops\") finds both\n * forms; \"bakeries\" -> \"bakery\" is not, so the typed word goes as it is.\n */\nfunction backendWord(concept: TemplateQueryConcept): string {\n const stem = concept.terms[0];\n return concept.word.startsWith(stem) ? stem : concept.word;\n}\n\n/**\n * The backend reads that gather candidates for `query`, most telling first, at\n * most `budget` of them. Stage 1: every word together, the subject words\n * together, each subject word, the first subject word with each style word (a\n * style-only query: each style word). Stage 2: near words, one word at a time.\n */\nexport function templateSearchReads(query: TemplateQuery, budget = 10): TemplateSearchRead[] {\n const reads: TemplateSearchRead[] = [];\n const keys = new Set<string>();\n const add = (parts: Array<{ word: string; term: string }>, wide: boolean, stage: 1 | 2, concept?: string) => {\n const words = [...new Set(parts.flatMap((p) => p.word.split(' ')))];\n const key = [...words].sort().join(' ');\n if (reads.length >= budget || words.length === 0 || keys.has(key)) return;\n keys.add(key);\n reads.push({\n words,\n terms: [...new Set(parts.map((p) => p.term))],\n wide,\n stage,\n ...(concept ? { concept } : {}),\n });\n };\n const own = (c: TemplateQueryConcept) => ({ word: backendWord(c), term: c.terms[0] });\n const subjects = query.subjects.map(own);\n const styles = query.styles.map(own);\n if (subjects.length + styles.length > 1) add([...subjects, ...styles], true, 1);\n if (subjects.length > 1 && styles.length > 0) add(subjects, true, 1);\n for (const s of subjects) add([s], true, 1, s.term);\n if (subjects.length > 0) for (const y of styles) add([subjects[0], y], false, 1);\n if (subjects.length === 0) for (const y of styles) add([y], true, 1, y.term);\n // Near words, one per word in turn: store's \"shop\" before opening's second near word.\n const concepts = subjects.length > 0 ? query.subjects : query.styles;\n for (let k = 1; reads.length < budget; k++) {\n let any = false;\n for (const c of concepts) {\n const term = c.terms[k];\n if (term === undefined) continue;\n any = true;\n add([{ word: term, term }], false, 2, c.terms[0]);\n }\n if (!any) break;\n }\n return reads;\n}\n\n// ─── Scoring ────────────────────────────────────────────────────────────────\n\n/** What a template is known by, as far as the caller has it. */\nexport interface TemplateSearchFields {\n title?: string;\n /** Its visual summary (what the cover shows); absent on a light read. */\n summary?: string;\n tags?: readonly string[];\n category?: string;\n description?: string;\n}\n\n/** Tags that describe the catalog, not the template: its group, its kind, its shape. */\nconst STRUCTURAL_TAG =\n /^(canvas-[a-z-]+|video-studio|\\d+:\\d+|presentation|carousel|flyer|business-cards?|logo|banner|brochure|branding|social-post|certificate|worksheet|proposal|newsletter|menu|infographic)$/;\n\n/** A template's words, by where they appear, ready to score against any query. */\nexport interface TemplateSearchText {\n title: string[];\n tags: string[];\n summary: string[];\n /** Every visible text, lower case, for telling a whole word from part of one. */\n visible: string;\n /** False when the title may be cut short (a title read back from a row's name). */\n titleComplete: boolean;\n}\n\nexport function templateSearchText(fields: TemplateSearchFields, titleComplete = true): TemplateSearchText {\n const tags = (fields.tags ?? []).filter((t) => !STRUCTURAL_TAG.test(t.toLowerCase()));\n const tagText = [...tags, fields.category ?? ''].join(' ');\n // A tag spelled as one word (\"realestate\") also matches the two-word term.\n const joinedTags = tags.map((t) => fold(t).replace(NON_WORD_ALL, '')).filter((t) => t.length > 1);\n return {\n title: searchWords(fields.title ?? ''),\n tags: [...searchWords(tagText), ...joinedTags],\n summary: searchWords(`${fields.summary ?? ''} ${fields.description ?? ''}`),\n visible: fold(`${fields.title ?? ''} ${tagText}`),\n titleComplete,\n };\n}\n\n/** \"strategic\" and \"strategy\", \"photographer\" and \"photography\": one word in a title's sense. */\nfunction nearWord(a: string, b: string): boolean {\n const min = Math.min(a.length, b.length);\n if (min < 5 || Math.abs(a.length - b.length) > 3) return false;\n let common = 0;\n while (common < min && a[common] === b[common]) common++;\n return common >= Math.max(5, min - 2);\n}\n\ninterface FindOptions {\n /** Near forms count (\"strategy\" for \"strategic\"). */\n loose?: boolean;\n /** Words it starts count (a word still being typed). */\n prefix?: boolean;\n /** Words one typo away count (a word the reader does not know). */\n typo?: boolean;\n}\n\n/** A word one typo away (two for a long word), first letter alike. */\nfunction typoOf(term: string, word: string): boolean {\n if (word.length < 5 || word[0] !== term[0]) return false;\n const max = term.length >= 8 ? 2 : 1;\n return editDistance(term, word, max) <= max;\n}\n\n/**\n * Where `term` appears in `words`: 1 for the word itself, 0.9 for a near form, 0.85 for a word one\n * typo away, 0.8 for a word it starts; with its position.\n */\nfunction findTerm(\n term: string,\n words: string[],\n { loose = false, prefix = false, typo = false }: FindOptions = {},\n): { quality: number; at: number } | null {\n const parts = term.split(' ');\n if (parts.length > 1) {\n const joined = parts.join('');\n for (let i = 0; i < words.length; i++) {\n if (words[i] === joined) return { quality: 1, at: i };\n if (parts.every((p, k) => words[i + k] === p)) return { quality: 1, at: i };\n }\n return null;\n }\n let near: { quality: number; at: number } | null = null;\n for (let i = 0; i < words.length; i++) {\n if (words[i] === term) return { quality: 1, at: i };\n if (near?.quality === 0.9) continue; // the best a looser form gets; an exact word may still follow\n if (loose && nearWord(term, words[i])) near = { quality: 0.9, at: i };\n else if (typo && (!near || near.quality < 0.85) && typoOf(term, words[i])) near = { quality: 0.85, at: i };\n else if (prefix && !near && words[i].startsWith(term)) near = { quality: 0.8, at: i };\n }\n return near;\n}\n\ntype Field = 'title' | 'tags' | 'summary' | 'elsewhere';\n\ninterface Evidence {\n strength: number;\n field: Field | null;\n /** Position in the title, for phrases. */\n at: number;\n}\n\nconst FIELD_WEIGHT: Record<TemplateConceptKind, Record<Exclude<Field, 'elsewhere'>, number>> = {\n // A subject word in the title or tags is the template's real subject; in the visual summary\n // it is often an accident (\"an opening paragraph\").\n subject: { title: 1, tags: 0.8, summary: 0.35 },\n // A style word in the summary is what the cover looks like: good evidence.\n style: { title: 1, tags: 0.7, summary: 0.75 },\n};\n/** The backend found the word somewhere this side cannot see (a light read has no summary). */\nconst ELSEWHERE_WEIGHT = { subject: { complete: 0.3, cut: 0.45 }, style: 0.6 } as const;\n/** A near word counts a little less than the word itself. */\nconst NEAR_TERM_WEIGHT = 0.85;\n\nfunction evidenceFor(concept: TemplateQueryConcept, text: TemplateSearchText, foundBy?: ReadonlySet<string>): Evidence {\n let best: Evidence = { strength: 0, field: null, at: -1 };\n const loose = concept.kind === 'subject';\n concept.terms.forEach((term, index) => {\n const termWeight = index === 0 ? 1 : NEAR_TERM_WEIGHT;\n for (const field of ['title', 'tags', 'summary'] as const) {\n const hit = findTerm(term, text[field], {\n loose,\n prefix: index === 0 && concept.prefix === true,\n typo: index === 0 && concept.typo === true,\n });\n if (!hit) continue;\n const strength = FIELD_WEIGHT[concept.kind][field] * termWeight * hit.quality;\n if (strength > best.strength) best = { strength, field, at: field === 'title' ? hit.at : -1 };\n }\n // Found by the backend, but not as a word anywhere visible: it is in the summary (or the\n // part of a long title a row name leaves out). Part of a longer visible word (\"workshop\"\n // for \"shop\") is what the backend's substring match found, so that counts for nothing.\n if (foundBy?.has(term) && !term.split(' ').some((p) => text.visible.includes(p))) {\n const strength =\n (concept.kind === 'subject'\n ? text.titleComplete\n ? ELSEWHERE_WEIGHT.subject.complete\n : ELSEWHERE_WEIGHT.subject.cut\n : ELSEWHERE_WEIGHT.style) * termWeight;\n if (strength > best.strength) best = { strength, field: 'elsewhere', at: -1 };\n }\n });\n return best;\n}\n\nexport interface TemplateScore {\n /** Higher is better; exact matches always outrank close ones. */\n score: number;\n /** Null: nothing of the query fits. */\n match: Exclude<TemplateMatch, 'popular'> | null;\n}\n\nconst mean = (xs: number[]) => (xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : 0);\n\n/**\n * How well one template fits `query`. `foundBy` is the set of query terms the\n * backend found in it (light reads), so a word the caller cannot see still counts.\n */\nexport function scoreTemplate(\n query: TemplateQuery,\n text: TemplateSearchText,\n foundBy?: ReadonlySet<string>,\n): TemplateScore {\n if (query.empty) return { score: 0, match: null };\n const subjects = query.subjects.map((c) => evidenceFor(c, text, foundBy));\n const styles = query.styles.map((c) => evidenceFor(c, text, foundBy));\n let match: TemplateScore['match'] = null;\n if (subjects.length > 0) {\n // Every subject word is what the template is about (its title or tags): exact.\n if (subjects.every((e) => e.field === 'title' || e.field === 'tags')) match = 'exact';\n else if (subjects.some((e) => e.strength > 0)) match = 'close';\n } else {\n const present = styles.filter((e) => e.strength >= 0.5).length;\n if (present >= Math.ceil(styles.length / 2)) match = 'exact';\n else if (styles.some((e) => e.strength > 0)) match = 'close';\n }\n if (!match) return { score: 0, match: null };\n // Subject words side by side in the title read as the phrase that was typed (\"coffee shop\").\n let phrase = 0;\n for (let i = 0; i + 1 < subjects.length; i++) {\n const [a, b] = [subjects[i].at, subjects[i + 1].at];\n if (a < 0 || b < 0) continue;\n const gap = b - a;\n phrase += gap === 1 ? 1 : (gap > 1 && gap <= 3) || gap === -1 ? 0.5 : 0;\n }\n if (subjects.length > 1) phrase /= subjects.length - 1;\n const primary = subjects.length > 0 ? mean(subjects.map((e) => e.strength)) : mean(styles.map((e) => e.strength));\n const secondary = subjects.length > 0 ? mean(styles.map((e) => e.strength)) : 0;\n // A title that is mostly what was asked for (\"Birthday party celebration\") is more about it than one\n // that mentions it on the way (\"Home quiz with a birthday-party theme\").\n const words = text.title.filter((w) => !FILLER.has(w));\n const inTitle = [...subjects, ...styles].filter((e) => e.field === 'title').length;\n const focus = words.length > 0 ? Math.min(1, inTitle / words.length) : 0;\n const tier = match === 'exact' ? 2000 : 1000;\n return { score: tier + 100 * primary + 40 * secondary + 15 * phrase + 8 * focus, match };\n}\n\nexport interface RankedTemplate<T> {\n item: T;\n score: number;\n match: Exclude<TemplateMatch, 'popular'>;\n}\n\n/**\n * The items that fit `query`, best first; ties keep the order they came in (the\n * catalog's own). Items nothing of the query fits are left out.\n */\nexport function rankTemplates<T>(\n query: TemplateQuery,\n items: readonly T[],\n textOf: (item: T) => TemplateSearchText,\n foundByOf?: (item: T) => ReadonlySet<string> | undefined,\n): Array<RankedTemplate<T>> {\n const ranked: Array<RankedTemplate<T> & { order: number }> = [];\n items.forEach((item, order) => {\n const { score, match } = scoreTemplate(query, textOf(item), foundByOf?.(item));\n if (match) ranked.push({ item, score, match, order });\n });\n ranked.sort((a, b) => b.score - a.score || a.order - b.order);\n return ranked.map(({ item, score, match }) => ({ item, score, match }));\n}\n\n/**\n * A row name back to the title it was made from: `canvas-flyer-coffee-shop-grand-opening-027fdd2c`\n * -> \"coffee shop grand opening\". The publish lane slugs titles (long ones cut short) and adds a\n * code; a light read has the name and not the title.\n */\nexport function titleFromRowName(name: string, group: string): string {\n const rest = name.startsWith(`${group}-`) ? name.slice(group.length + 1) : name;\n const parts = rest.split('-');\n if (parts.length > 1) parts.pop();\n return parts.join(' ');\n}\n"],"names":["map"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"templateSearch.js","sources":["../../../src/features/canvas/templateSearch.ts"],"sourcesContent":["/**\n * Template search: what a person (or the brain) typed -> the templates that fit\n * it, best first. One implementation for every page that searches a catalog\n * (the Templates page, the chat templates card, the image and audio lanes).\n *\n * The catalog backend matches every word of a search as a substring and keeps\n * only rows that hold ALL of them, unranked. That is a fine way to FIND\n * candidates and a poor way to choose between them:\n *\n * - Style and vibe words (\"clean modern fancy\") filtered a business card search\n * down to nothing, because no row says \"fancy\".\n * - One loose word carried a whole phrase: \"store opening flyer\" fell back to\n * \"opening\" and listed \"Seven opening lines that make people stop and read\".\n *\n * So a query is read here first: filler (\"templates for my\") and the category's\n * own name (\"flyer\") are left out, typos of either are recognised, and what is\n * left splits into SUBJECT words (what the template is about: coffee shop,\n * roadmap, 2030) and STYLE words (how it looks: clean, modern, fancy). Each\n * word brings a few near words (store ~ shop, fancy ~ elegant ~ luxury).\n *\n * Then each candidate is scored on the whole query: subject words in its title\n * or tags (its real subject) count most, the same words only in its visual\n * summary count little, style words rank and never exclude, and subject words\n * that sit together in the title (\"coffee shop\") score as a phrase. A template\n * is an `exact` match when every subject word is its real subject (a style-only\n * query: at least half the looks asked for), `close` when only part of the\n * query fits, and anything else is not a match at all - the category's own\n * best templates follow the matches as `popular`, so a search never comes back\n * empty while the category has templates.\n *\n * Pure: no I/O. The catalog reads that feed it live in ./rankedCatalogSearch.\n *\n * Native port of surface-kit `templateCatalogs/templateSearch` (kit 0.43). Kept\n * Hermes-safe: no Unicode property escapes in literals (built in a try with an\n * ASCII + Latin fallback) and `normalize` guarded.\n */\n\n/** Builds a regex from a Unicode-property source, or its fallback where the engine lacks them. */\nfunction unicodeRegExp(source: string, flags: string, fallback: RegExp): RegExp {\n try {\n return new RegExp(source, `${flags}u`);\n } catch {\n return fallback;\n }\n}\n\n/** A run of anything but letters and digits. */\nexport const NON_WORD: RegExp = unicodeRegExp('[^\\\\p{L}\\\\p{N}]+', '', /[^A-Za-z0-9\\u00C0-\\u024F]+/);\nconst NON_WORD_ALL: RegExp = unicodeRegExp('[^\\\\p{L}\\\\p{N}]+', 'g', /[^A-Za-z0-9\\u00C0-\\u024F]+/g);\n/** Text that ends in a letter or digit (a word still being typed). */\nconst WORD_END: RegExp = unicodeRegExp('[\\\\p{L}\\\\p{N}]$', '', /[A-Za-z0-9\\u00C0-\\u024F]$/);\n\n/** How a listed template relates to the search. */\nexport type TemplateMatch = 'exact' | 'close' | 'popular';\n\nexport type TemplateConceptKind = 'subject' | 'style';\n\n/** One word of a query, with the near words that count for it. */\nexport interface TemplateQueryConcept {\n /** The word as read (lower case, typo fixed). */\n word: string;\n kind: TemplateConceptKind;\n /** Its stem first, then its near words' stems; a multi-word term (\"real estate\") is space-joined. */\n terms: string[];\n /**\n * The last word of a query still being typed (\"coff\"): it also matches the words it starts.\n * Only an unknown word of 3+ letters at the very end, so a finished query never matches loosely.\n */\n prefix?: boolean;\n /**\n * A word the reader does not know, perhaps misspelled (\"cofee\"): it also matches a word one\n * typo away (\"coffee\"). Known words never do, so \"wedding\" does not match \"welding\".\n */\n typo?: boolean;\n}\n\nexport interface TemplateQuery {\n /** What was typed, whitespace collapsed. */\n text: string;\n subjects: TemplateQueryConcept[];\n styles: TemplateQueryConcept[];\n /** Words left out: filler, the category's own name, and typos of either. */\n ignored: string[];\n /** Nothing searchable was typed: list the category as it is. */\n empty: boolean;\n}\n\nexport interface TemplateQueryOptions {\n /**\n * Words and phrases that name the category being searched (\"business card\",\n * \"flyer\", \"slides\"): a search inside the category says nothing by them.\n */\n categoryWords?: readonly string[];\n}\n\n/** At most this many words of one query count; the rest are ignored. */\nconst MAX_CONCEPTS = 8;\n\n// ─── Words ──────────────────────────────────────────────────────────────────\n\n/** Words that say nothing about which template: \"show me some templates for my ...\". */\nconst FILLER = new Set(\n (\n 'a an the and or of for in on at to from by with without about into onto over under as is are be ' +\n 'my our your their his her its me i we you us it this that these those some any all every each ' +\n 'one ones template templates design designs designed idea ideas example examples sample samples ' +\n 'option options show find search make create build need needs want looking look get give please ' +\n 'new best good great nice cool really very something kind type types version style styles styled ' +\n 'theme themed based using use free just also like more other etc page pages custom editable own ' +\n 'quick easy pro printable print ready can could would should will do does help thanks hi hello ' +\n 'want wanted some something someone pick choose choice list see view'\n ).split(' '),\n);\n\n/**\n * How a template looks, as people say it. A style word ranks; it never excludes.\n * Each group is a set of near words: any of them counts for any other.\n */\n// prettier-ignore\nconst STYLE_GROUPS: readonly (readonly string[])[] = [\n ['clean', 'minimal', 'minimalist', 'simple', 'crisp', 'tidy', 'uncluttered'],\n ['minimal', 'minimalist', 'simple', 'clean', 'minimalistic', 'minimalism', 'plain'],\n ['simple', 'minimal', 'minimalist', 'clean', 'basic', 'plain'],\n ['modern', 'contemporary', 'sleek', 'trendy'],\n ['fancy', 'elegant', 'luxury', 'gold', 'premium', 'luxurious', 'golden', 'sophisticated', 'classy', 'glamorous', 'chic', 'ornate', 'upscale'],\n ['elegant', 'sophisticated', 'luxury', 'classy', 'refined', 'graceful', 'chic', 'elegance', 'fancy'],\n ['luxury', 'luxurious', 'premium', 'gold', 'elegant', 'upscale', 'golden', 'fancy'],\n ['bold', 'vibrant', 'striking', 'strong', 'punchy', 'loud'],\n ['playful', 'fun', 'cute', 'colorful', 'whimsical', 'cheerful', 'quirky', 'cartoon'],\n ['fun', 'playful', 'colorful', 'cheerful', 'cute'],\n ['cute', 'playful', 'adorable', 'sweet', 'kawaii'],\n ['warm', 'cozy', 'earthy', 'beige', 'cream', 'terracotta'],\n ['professional', 'corporate', 'formal', 'businesslike'],\n ['corporate', 'professional', 'formal'],\n ['formal', 'professional', 'classic'],\n ['classic', 'timeless', 'traditional', 'vintage'],\n ['vintage', 'retro', 'antique', 'nostalgic', 'classic', 'risograph'],\n ['retro', 'vintage', 'groovy', 'nostalgic'],\n ['rustic', 'kraft', 'wooden', 'farmhouse', 'earthy'],\n ['creative', 'artistic', 'unique', 'abstract'],\n ['colorful', 'vibrant', 'bright', 'colourful', 'rainbow', 'multicolor', 'multicolored'],\n ['bright', 'vibrant', 'colorful', 'neon'],\n ['dark', 'black', 'moody'],\n ['light', 'white', 'airy'],\n ['pastel', 'soft', 'muted', 'gentle'],\n ['soft', 'pastel', 'gentle', 'muted'],\n ['floral', 'flower', 'botanical', 'blossom'],\n ['geometric', 'shapes', 'angular', 'lines'],\n ['abstract', 'shapes', 'artistic'],\n ['gradient', 'ombre'],\n ['watercolor', 'watercolour', 'painted', 'painterly'],\n ['illustrated', 'illustration', 'illustrative', 'drawn', 'handdrawn', 'doodle', 'cartoon', 'sketch'],\n ['futuristic', 'neon', 'cyber', 'scifi'],\n ['feminine', 'pink', 'girly', 'delicate'],\n ['masculine', 'rugged'],\n ['beautiful', 'elegant', 'pretty', 'stunning', 'lovely', 'aesthetic', 'gorgeous'],\n ['stylish', 'chic', 'trendy', 'fashionable'],\n ['friendly', 'approachable', 'welcoming', 'casual'],\n ['casual', 'relaxed', 'friendly'],\n ['calm', 'serene', 'peaceful', 'zen', 'tranquil'],\n ['monochrome', 'monochromatic', 'grayscale'],\n ['grunge', 'textured', 'distressed'],\n ['handwritten', 'script', 'calligraphy'],\n ['typographic', 'typography', 'lettering'],\n ['sleek', 'modern', 'smooth', 'minimal'],\n ['gray', 'grey'],\n ['gold', 'golden'],\n ['purple', 'violet', 'plum', 'lavender'],\n ['beige', 'cream', 'ivory', 'tan'],\n ['black'], ['white'], ['silver'], ['blue'], ['navy'], ['green'], ['red'], ['pink'], ['yellow'], ['orange'],\n ['brown'], ['teal'], ['turquoise'], ['mint'], ['maroon'], ['burgundy'], ['peach'], ['coral'], ['olive'],\n ['sage'], ['mustard'], ['emerald'], ['neon'],\n];\n\n/**\n * What a template is about, with the few near words that mean the same thing\n * in a catalog title (\"store\" ~ \"shop\"). Words not listed are subjects too;\n * they just bring no near words.\n */\n// prettier-ignore\nconst SUBJECT_GROUPS: readonly (readonly string[])[] = [\n ['store', 'shop', 'boutique', 'retail', 'storefront'],\n ['shop', 'store', 'boutique', 'retail', 'shopping'],\n ['opening', 'grand opening', 'launch', 'inauguration', 'reopening'],\n ['coffee', 'cafe', 'espresso', 'barista', 'coffeehouse', 'latte'],\n ['cafe', 'coffee', 'coffeehouse', 'bistro'],\n ['bakery', 'baker', 'baking', 'bakeshop', 'pastry', 'patisserie', 'bread', 'cake', 'cupcake'],\n ['cake', 'cupcake', 'bakery', 'dessert', 'pastry'],\n ['restaurant', 'dining', 'diner', 'bistro', 'eatery', 'cuisine'],\n ['food', 'culinary', 'meal', 'kitchen', 'cooking'],\n ['chef', 'cook', 'culinary', 'catering'],\n ['roadmap', 'road map', 'timeline', 'milestone'],\n ['ice cream', 'gelato', 'dessert'],\n ['social media', 'instagram', 'facebook', 'tiktok'],\n ['strategy', 'strategic', 'planning'],\n ['plan', 'planning', 'planner'],\n ['real estate', 'realtor', 'realty', 'property', 'housing'],\n ['realtor', 'real estate', 'realty', 'property'],\n ['home', 'house'],\n ['lawyer', 'attorney', 'law', 'legal'],\n ['attorney', 'lawyer', 'law', 'legal'],\n ['doctor', 'medical', 'clinic', 'physician', 'healthcare'],\n ['dentist', 'dental', 'orthodontist'],\n ['health', 'healthcare', 'wellness', 'medical'],\n ['fitness', 'gym', 'workout', 'trainer', 'exercise'],\n ['gym', 'fitness', 'workout'],\n ['yoga', 'pilates', 'meditation'],\n ['wedding', 'bridal', 'bride', 'marriage'],\n ['birthday', 'bday'],\n ['party', 'celebration', 'fiesta'],\n ['photography', 'photographer', 'photo', 'camera'],\n ['photographer', 'photography', 'photo'],\n ['beauty', 'salon', 'makeup', 'cosmetics', 'spa'],\n ['salon', 'hair', 'hairdresser', 'hairstylist', 'beauty'],\n ['barber', 'barbershop', 'hair'],\n ['technology', 'tech', 'software', 'digital'],\n ['tech', 'technology', 'software'],\n ['startup', 'venture', 'founder'],\n ['pitch', 'investor', 'funding', 'fundraising'],\n ['marketing', 'advertising', 'campaign', 'promotion'],\n ['brand', 'branding', 'identity'],\n ['sale', 'discount', 'promo', 'offer', 'deal', 'clearance'],\n ['church', 'worship', 'ministry', 'faith'],\n ['school', 'education', 'classroom', 'student', 'teacher'],\n ['education', 'school', 'learning', 'teaching', 'classroom'],\n ['music', 'band', 'concert', 'musician'],\n ['travel', 'trip', 'tourism', 'vacation', 'tour'],\n ['hotel', 'resort', 'hospitality'],\n ['cleaning', 'cleaner', 'janitorial', 'housekeeping', 'maid'],\n ['construction', 'builder', 'contractor', 'renovation'],\n ['car', 'auto', 'automotive', 'mechanic', 'garage', 'vehicle'],\n ['pet', 'dog', 'cat', 'veterinary', 'vet', 'grooming'],\n ['finance', 'financial', 'accounting', 'accountant', 'bank', 'investment'],\n ['accountant', 'accounting', 'bookkeeping', 'tax'],\n ['consulting', 'consultant', 'advisory', 'advisor'],\n ['charity', 'nonprofit', 'fundraiser', 'donation', 'volunteer'],\n ['fashion', 'clothing', 'apparel'],\n ['garden', 'gardening', 'landscaping', 'lawn'],\n ['event', 'conference', 'summit', 'meetup'],\n ['christmas', 'xmas'],\n ['kids', 'children', 'child'],\n ['report', 'review', 'summary'],\n ['webinar', 'workshop', 'seminar'],\n ['farm', 'farming', 'agriculture'],\n ['sustainability', 'sustainable', 'environment', 'eco', 'climate'],\n ['science', 'research', 'laboratory'],\n ['art', 'artist', 'gallery'],\n ['coach', 'coaching', 'mentor'],\n ['therapy', 'therapist', 'counseling', 'counselor'],\n ['massage', 'spa', 'therapist'],\n ['plumber', 'plumbing', 'handyman', 'repair'],\n ['delivery', 'courier', 'logistics', 'shipping'],\n ['bar', 'pub', 'cocktail', 'brewery'],\n ['wine', 'winery', 'vineyard'],\n ['pizza', 'pizzeria'],\n ['tea', 'teahouse'],\n];\n\n/**\n * The words a category is named by, wherever a person may type them: \"logo\n * templates\" inside Logos is just \"templates\". Keyed by the category id (the\n * gallery group key); a caller with another key passes its own words.\n */\n// prettier-ignore\nexport const TEMPLATE_CATEGORY_WORDS: Readonly<Record<string, readonly string[]>> = {\n slideDeck: ['presentation', 'slide', 'slides', 'deck', 'ppt', 'pptx', 'powerpoint', 'keynote', 'slideshow', 'google slides'],\n socialPost: ['social media post', 'social post', 'post', 'posts', 'social media'],\n carousel: ['carousel', 'carousels', 'instagram carousel'],\n flyer: ['flyer', 'flier', 'poster', 'leaflet', 'handout'],\n businessCard: ['business card', 'visiting card', 'calling card', 'card'],\n logo: ['logo', 'logos', 'logotype', 'emblem'],\n banner: ['banner'],\n brochure: ['brochure', 'pamphlet', 'trifold', 'tri fold'],\n branding: ['branding kit', 'stationery'],\n certificate: ['certificate'],\n worksheet: ['worksheet'],\n proposal: ['proposal'],\n newsletter: ['newsletter'],\n menu: ['menu'],\n infographic: ['infographic'],\n document: ['document', 'doc'],\n report: ['report'],\n letter: ['letter', 'cover letter'],\n resume: ['resume', 'cv', 'curriculum vitae'],\n imageGeneration: ['image', 'picture', 'prompt'],\n videoGeneration: ['video', 'clip', 'reel'],\n audioGeneration: ['audio', 'sound', 'song', 'track'],\n};\n\n// ─── Text ───────────────────────────────────────────────────────────────────\n\n/** Words that end in \"s\" without being plurals (or whose plural stem collides with filler). */\n// prettier-ignore\nconst KEEP_S = new Set([\n 'news', 'series', 'species', 'physics', 'mathematics', 'economics', 'analytics', 'ethics', 'politics',\n 'athletics', 'aesthetics', 'lyrics', 'diabetes', 'canvas', 'christmas', 'xmas', 'texas', 'paris', 'atlas',\n 'gas', 'bus', 'plus', 'yes', 'its', 'this', 'thus', 'chaos', 'cosmos', 'logistics', 'graphics', 'kids',\n]);\n\n/** A word reduced to the form both sides compare in: plurals folded (\"bakeries\" -> \"bakery\"). */\nexport function stemWord(word: string): string {\n const w = word.toLowerCase();\n if (w.length <= 3 || /\\d/.test(w) || KEEP_S.has(w)) return w;\n if (w.endsWith('ies') && w.length > 4) return `${w.slice(0, -3)}y`;\n if (/(ss|us|is)$/.test(w)) return w;\n if (/(sses|ches|shes|xes|zes)$/.test(w)) return w.slice(0, -2);\n if (w.endsWith('s')) return w.slice(0, -1);\n return w;\n}\n\n/** Lower case, accents off (\"Café\" -> \"cafe\"), curly apostrophes straight, \"&\" read as \"and\". */\nfunction fold(text: string): string {\n let normalized = text;\n try {\n if (typeof text.normalize === 'function') normalized = text.normalize('NFKD');\n } catch {\n // An engine without normalization data: accents stay on.\n }\n return normalized\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[\\u2018\\u2019\\u02bc]/g, \"'\")\n .replace(/&/g, ' and ')\n .toLowerCase();\n}\n\n/**\n * Words of a text, stemmed. Single letters drop out (the \"s\" of \"women's\"); so\n * do single digits (\"5 tips\"), years and codes stay (\"2030\").\n */\nexport function searchWords(text: string): string[] {\n return fold(text)\n .split(NON_WORD)\n .filter((w) => w.length > 1)\n .map(stemWord);\n}\n\n/** Restricted Damerau-Levenshtein distance, giving up past `max`. */\nfunction editDistance(a: string, b: string, max: number): number {\n if (Math.abs(a.length - b.length) > max) return max + 1;\n const rows: number[][] = [];\n for (let i = 0; i <= a.length; i++) {\n rows.push([i]);\n }\n for (let j = 1; j <= b.length; j++) rows[0][j] = j;\n for (let i = 1; i <= a.length; i++) {\n let best = Infinity;\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n let d = Math.min(rows[i - 1][j] + 1, rows[i][j - 1] + 1, rows[i - 1][j - 1] + cost);\n if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1])\n d = Math.min(d, rows[i - 2][j - 2] + 1);\n rows[i][j] = d;\n if (d < best) best = d;\n }\n if (best > max) return max + 1;\n }\n return rows[a.length][b.length];\n}\n\n/**\n * Near words, built once: a group's first word brings the rest of its group; a\n * word that heads no group brings the heads of the groups it is in. So \"gold\"\n * brings \"golden\" (its own group), not every luxury word, while \"minimalist\"\n * brings \"clean\", \"minimal\" and \"simple\".\n */\nfunction nearMap(groups: readonly (readonly string[])[]): Map<string, string[]> {\n const own = new Map<string, string[]>();\n const heads = new Map<string, string[]>();\n const push = (map: Map<string, string[]>, key: string, value: string) => {\n const list = map.get(key) ?? [];\n if (value !== key && !list.includes(value)) list.push(value);\n map.set(key, list);\n };\n for (const group of groups) {\n const [head, ...rest] = group.map((w) => searchWords(w).join(' '));\n if (!own.has(head)) own.set(head, []);\n for (const w of rest) {\n push(own, head, w);\n push(heads, w, head);\n }\n }\n const map = new Map<string, string[]>();\n for (const [word, list] of heads) if (!own.has(word)) map.set(word, list);\n for (const [word, list] of own) map.set(word, list);\n return map;\n}\n\nconst STYLE_NEAR = nearMap(STYLE_GROUPS);\nconst SUBJECT_NEAR = nearMap(SUBJECT_GROUPS);\n\n/** Words as listed, by stem: what a fixed typo reads as. */\nconst LISTED = new Map<string, string>();\n/** Words a typo may be read as: filler, style words and category names. */\nconst TYPO_TARGETS = new Set<string>();\n/** Subject words a LONG typo may be read as (\"resturant\"): few real long words are one typo from another. */\nconst LONG_TYPO_TARGETS = new Set<string>();\n/** Every word the reader knows; a known word is never \"fixed\". */\nconst KNOWN = new Set<string>();\n{\n const add = (w: string, target: boolean) => {\n for (const part of fold(w).split(NON_WORD)) {\n if (part.length < 2) continue;\n const stem = stemWord(part);\n KNOWN.add(stem);\n if (!LISTED.has(stem)) LISTED.set(stem, part);\n if (target) TYPO_TARGETS.add(stem);\n }\n };\n FILLER.forEach((w) => add(w, true));\n for (const g of STYLE_GROUPS) g.forEach((w) => add(w, true));\n for (const words of Object.values(TEMPLATE_CATEGORY_WORDS)) words.forEach((w) => add(w, true));\n ['templates', 'business'].forEach((w) => add(w, true));\n for (const g of SUBJECT_GROUPS) g.forEach((w) => add(w, false));\n for (const g of SUBJECT_GROUPS)\n for (const w of g) if (!w.includes(' ') && w.length >= 8) LONG_TYPO_TARGETS.add(stemWord(w));\n}\n\n/**\n * A word the reader does not know, read as the filler, style or category word\n * it is a typo of (\"templtes\" -> \"templates\", \"elegent\" -> \"elegant\",\n * \"buisness\" -> \"business\"), or as the long subject word it is one typo from\n * (\"resturant\" -> \"restaurant\"). Short words are never changed, the first\n * letter must agree, and a short word never becomes a subject word: \"stone\"\n * stays \"stone\", it is not a typo of \"store\".\n */\nfunction fixTypo(stem: string): string {\n if (stem.length < 5 || /\\d/.test(stem) || KNOWN.has(stem)) return stem;\n let best = '';\n let bestDistance = Infinity;\n const consider = (targets: Set<string>, max: number) => {\n for (const known of targets) {\n if (known[0] !== stem[0] || known.length < 4) continue;\n const d = editDistance(stem, known, max);\n if (d <= max && d < bestDistance) {\n best = known;\n bestDistance = d;\n }\n }\n };\n consider(TYPO_TARGETS, stem.length >= 8 ? 2 : 1);\n if (stem.length >= 8) consider(LONG_TYPO_TARGETS, 1);\n return best || stem;\n}\n\n// ─── Query ──────────────────────────────────────────────────────────────────\n\ninterface Token {\n /** As typed (folded). */\n raw: string;\n stem: string;\n}\n\n/** Remove every run of `phrase` (stems) from `tokens`, typos of it included. */\nfunction removePhrase(tokens: Token[], phrase: string[], removed: string[]): Token[] {\n if (phrase.length === 0) return tokens;\n const out: Token[] = [];\n for (let i = 0; i < tokens.length; ) {\n const hit =\n i + phrase.length <= tokens.length &&\n phrase.every((p, k) => tokens[i + k].stem === p || fixTypo(tokens[i + k].stem) === p);\n if (hit) {\n removed.push(\n tokens\n .slice(i, i + phrase.length)\n .map((t) => t.raw)\n .join(' '),\n );\n i += phrase.length;\n } else {\n out.push(tokens[i]);\n i += 1;\n }\n }\n return out;\n}\n\n/** Every multi-word term the reader knows (\"real estate\", \"grand opening\"). */\nconst PHRASES: Set<string> = new Set(\n [...STYLE_NEAR.keys(), ...SUBJECT_NEAR.keys(), ...[...STYLE_NEAR.values(), ...SUBJECT_NEAR.values()].flat()].filter(\n (term) => term.includes(' '),\n ),\n);\n\n/** Two words that make a known phrase are read as one: \"real estate\" is one subject, not two. */\nfunction joinPhrases(tokens: Token[]): Token[] {\n const out: Token[] = [];\n for (let i = 0; i < tokens.length; i++) {\n const next = tokens[i + 1];\n if (next && PHRASES.has(`${tokens[i].stem} ${next.stem}`)) {\n out.push({ raw: `${tokens[i].raw} ${next.raw}`, stem: `${tokens[i].stem} ${next.stem}` });\n i += 1;\n } else {\n out.push(tokens[i]);\n }\n }\n return out;\n}\n\n/** Read a typed query: its subject and style words, and what was left out. */\nexport function parseTemplateQuery(text: string, options: TemplateQueryOptions = {}): TemplateQuery {\n const typed = (text ?? '').replace(/\\s+/g, ' ').trim();\n const ignored: string[] = [];\n let tokens: Token[] = fold(typed)\n .split(NON_WORD)\n .filter((w) => w.length > 1)\n .map((raw) => ({ raw, stem: stemWord(raw) }));\n // The category's own name, longest phrase first: \"business card\" before \"card\".\n const phrases = [...(options.categoryWords ?? []), 'template']\n .map((p) => searchWords(p))\n .filter((p) => p.length > 0)\n .sort((a, b) => b.length - a.length);\n for (const phrase of phrases) tokens = removePhrase(tokens, phrase, ignored);\n tokens = joinPhrases(tokens);\n // Still typing: a query that does not end in a space or punctuation has a last word in progress.\n const typing = WORD_END.test(text ?? '');\n const last = tokens[tokens.length - 1];\n\n const subjects: TemplateQueryConcept[] = [];\n const styles: TemplateQueryConcept[] = [];\n const seen = new Set<string>();\n for (const token of tokens) {\n const stem = token.stem.includes(' ') ? token.stem : fixTypo(token.stem);\n const fixed = stem !== token.stem;\n if (FILLER.has(stem) || FILLER.has(LISTED.get(stem) ?? '')) {\n ignored.push(token.raw);\n continue;\n }\n if (seen.has(stem)) continue;\n if (subjects.length + styles.length >= MAX_CONCEPTS) {\n ignored.push(token.raw);\n continue;\n }\n seen.add(stem);\n const word = fixed ? (LISTED.get(stem) ?? stem) : token.raw;\n if (STYLE_NEAR.has(stem)) {\n styles.push({ word, kind: 'style', terms: [stem, ...(STYLE_NEAR.get(stem) ?? [])] });\n } else {\n const unknown = !fixed && !KNOWN.has(stem) && !stem.includes(' ') && !/\\d/.test(stem);\n const prefix = unknown && typing && token === last && stem.length >= 3;\n const typo = unknown && stem.length >= 5;\n subjects.push({\n word,\n kind: 'subject',\n terms: [stem, ...(SUBJECT_NEAR.get(stem) ?? [])],\n ...(prefix ? { prefix } : {}),\n ...(typo ? { typo } : {}),\n });\n }\n }\n return { text: typed, subjects, styles, ignored, empty: subjects.length + styles.length === 0 };\n}\n\n/** The words that were read, as a person can be shown them: \"coffee shop modern\". */\nexport function templateQueryLabel(query: TemplateQuery): string {\n return [...query.subjects, ...query.styles].map((c) => c.word).join(' ');\n}\n\n// ─── Candidate reads ────────────────────────────────────────────────────────\n\n/** One backend read that finds candidates: rows holding every word of `words`. */\nexport interface TemplateSearchRead {\n /** The words of the read: the backend keeps rows holding every one of them (as part of any word). */\n words: string[];\n /** The query terms (stems) every row this read returns holds somewhere. */\n terms: string[];\n /** Read deep (a word of the query) or shallow (a near word). */\n wide: boolean;\n /**\n * 1: the query's own words. 2: a near word, read only when its word's own read came back thin\n * (`concept`): \"fancy\" finds no row, so \"elegant\" and \"luxury\" are read; \"shop\" finds plenty.\n */\n stage: 1 | 2;\n /** The word (its stem) a single-word read is for: its own word (stage 1) or a near word of it (stage 2). */\n concept?: string;\n}\n\n/**\n * What the backend is asked for a concept's own word. It matches substrings, so\n * a stem that is the start of the typed word (\"shop\" of \"shops\") finds both\n * forms; \"bakeries\" -> \"bakery\" is not, so the typed word goes as it is.\n */\nfunction backendWord(concept: TemplateQueryConcept): string {\n const stem = concept.terms[0];\n return concept.word.startsWith(stem) ? stem : concept.word;\n}\n\n/**\n * The backend reads that gather candidates for `query`, most telling first, at\n * most `budget` of them. Stage 1: every word together, the subject words\n * together, each subject word, the first subject word with each style word (a\n * style-only query: each style word). Stage 2: near words, one word at a time.\n */\nexport function templateSearchReads(query: TemplateQuery, budget = 10): TemplateSearchRead[] {\n const reads: TemplateSearchRead[] = [];\n const keys = new Set<string>();\n const add = (parts: Array<{ word: string; term: string }>, wide: boolean, stage: 1 | 2, concept?: string) => {\n const words = [...new Set(parts.flatMap((p) => p.word.split(' ')))];\n const key = [...words].sort().join(' ');\n if (reads.length >= budget || words.length === 0 || keys.has(key)) return;\n keys.add(key);\n reads.push({\n words,\n terms: [...new Set(parts.map((p) => p.term))],\n wide,\n stage,\n ...(concept ? { concept } : {}),\n });\n };\n const own = (c: TemplateQueryConcept) => ({ word: backendWord(c), term: c.terms[0] });\n const subjects = query.subjects.map(own);\n const styles = query.styles.map(own);\n if (subjects.length + styles.length > 1) add([...subjects, ...styles], true, 1);\n if (subjects.length > 1 && styles.length > 0) add(subjects, true, 1);\n for (const s of subjects) add([s], true, 1, s.term);\n if (subjects.length > 0) for (const y of styles) add([subjects[0], y], false, 1);\n if (subjects.length === 0) for (const y of styles) add([y], true, 1, y.term);\n // Near words, one per word in turn: store's \"shop\" before opening's second near word.\n const concepts = subjects.length > 0 ? query.subjects : query.styles;\n for (let k = 1; reads.length < budget; k++) {\n let any = false;\n for (const c of concepts) {\n const term = c.terms[k];\n if (term === undefined) continue;\n any = true;\n add([{ word: term, term }], false, 2, c.terms[0]);\n }\n if (!any) break;\n }\n return reads;\n}\n\n// ─── Scoring ────────────────────────────────────────────────────────────────\n\n/** What a template is known by, as far as the caller has it. */\nexport interface TemplateSearchFields {\n title?: string;\n /** Its visual summary (what the cover shows); absent on a light read. */\n summary?: string;\n tags?: readonly string[];\n category?: string;\n description?: string;\n}\n\n/**\n * A catalog title as a card shows it (surface-kit `templateDisplayTitle`): a quote the source\n * escaped loses its backslash (\"Women\\'s\" -> \"Women's\") and runs of spaces collapse.\n */\nexport function templateDisplayTitle(title: string | null | undefined): string {\n return (title ?? '')\n .replace(/\\\\(['\"])/g, '$1')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/** Tags that describe the catalog, not the template: its group, its kind, its shape. */\nconst STRUCTURAL_TAG =\n /^(canvas-[a-z-]+|video-studio|\\d+:\\d+|presentation|carousel|flyer|business-cards?|logo|banner|brochure|branding|social-post|certificate|worksheet|proposal|newsletter|menu|infographic)$/;\n\n/** A template's words, by where they appear, ready to score against any query. */\nexport interface TemplateSearchText {\n title: string[];\n tags: string[];\n summary: string[];\n /** Every visible text, lower case, for telling a whole word from part of one. */\n visible: string;\n /** False when the title may be cut short (a title read back from a row's name). */\n titleComplete: boolean;\n}\n\nexport function templateSearchText(fields: TemplateSearchFields, titleComplete = true): TemplateSearchText {\n const tags = (fields.tags ?? []).filter((t) => !STRUCTURAL_TAG.test(t.toLowerCase()));\n const tagText = [...tags, fields.category ?? ''].join(' ');\n // A tag spelled as one word (\"realestate\") also matches the two-word term.\n const joinedTags = tags.map((t) => fold(t).replace(NON_WORD_ALL, '')).filter((t) => t.length > 1);\n return {\n title: searchWords(fields.title ?? ''),\n tags: [...searchWords(tagText), ...joinedTags],\n summary: searchWords(`${fields.summary ?? ''} ${fields.description ?? ''}`),\n visible: fold(`${fields.title ?? ''} ${tagText}`),\n titleComplete,\n };\n}\n\n/** \"strategic\" and \"strategy\", \"photographer\" and \"photography\": one word in a title's sense. */\nfunction nearWord(a: string, b: string): boolean {\n const min = Math.min(a.length, b.length);\n if (min < 5 || Math.abs(a.length - b.length) > 3) return false;\n let common = 0;\n while (common < min && a[common] === b[common]) common++;\n return common >= Math.max(5, min - 2);\n}\n\ninterface FindOptions {\n /** Near forms count (\"strategy\" for \"strategic\"). */\n loose?: boolean;\n /** Words it starts count (a word still being typed). */\n prefix?: boolean;\n /** Words one typo away count (a word the reader does not know). */\n typo?: boolean;\n}\n\n/** A word one typo away (two for a long word), first letter alike. */\nfunction typoOf(term: string, word: string): boolean {\n if (word.length < 5 || word[0] !== term[0]) return false;\n const max = term.length >= 8 ? 2 : 1;\n return editDistance(term, word, max) <= max;\n}\n\n/**\n * Where `term` appears in `words`: 1 for the word itself, 0.9 for a near form, 0.85 for a word one\n * typo away, 0.8 for a word it starts; with its position.\n */\nfunction findTerm(\n term: string,\n words: string[],\n { loose = false, prefix = false, typo = false }: FindOptions = {},\n): { quality: number; at: number } | null {\n const parts = term.split(' ');\n if (parts.length > 1) {\n const joined = parts.join('');\n for (let i = 0; i < words.length; i++) {\n if (words[i] === joined) return { quality: 1, at: i };\n if (parts.every((p, k) => words[i + k] === p)) return { quality: 1, at: i };\n }\n return null;\n }\n let near: { quality: number; at: number } | null = null;\n for (let i = 0; i < words.length; i++) {\n if (words[i] === term) return { quality: 1, at: i };\n if (near?.quality === 0.9) continue; // the best a looser form gets; an exact word may still follow\n if (loose && nearWord(term, words[i])) near = { quality: 0.9, at: i };\n else if (typo && (!near || near.quality < 0.85) && typoOf(term, words[i])) near = { quality: 0.85, at: i };\n else if (prefix && !near && words[i].startsWith(term)) near = { quality: 0.8, at: i };\n }\n return near;\n}\n\ntype Field = 'title' | 'tags' | 'summary' | 'elsewhere';\n\ninterface Evidence {\n strength: number;\n field: Field | null;\n /** Position in the title, for phrases. */\n at: number;\n}\n\nconst FIELD_WEIGHT: Record<TemplateConceptKind, Record<Exclude<Field, 'elsewhere'>, number>> = {\n // A subject word in the title or tags is the template's real subject; in the visual summary\n // it is often an accident (\"an opening paragraph\").\n subject: { title: 1, tags: 0.8, summary: 0.35 },\n // A style word in the summary is what the cover looks like: good evidence.\n style: { title: 1, tags: 0.7, summary: 0.75 },\n};\n/** The backend found the word somewhere this side cannot see (a light read has no summary). */\nconst ELSEWHERE_WEIGHT = { subject: { complete: 0.3, cut: 0.45 }, style: 0.6 } as const;\n/** A near word counts a little less than the word itself. */\nconst NEAR_TERM_WEIGHT = 0.85;\n\nfunction evidenceFor(concept: TemplateQueryConcept, text: TemplateSearchText, foundBy?: ReadonlySet<string>): Evidence {\n let best: Evidence = { strength: 0, field: null, at: -1 };\n const loose = concept.kind === 'subject';\n concept.terms.forEach((term, index) => {\n const termWeight = index === 0 ? 1 : NEAR_TERM_WEIGHT;\n for (const field of ['title', 'tags', 'summary'] as const) {\n const hit = findTerm(term, text[field], {\n loose,\n prefix: index === 0 && concept.prefix === true,\n typo: index === 0 && concept.typo === true,\n });\n if (!hit) continue;\n const strength = FIELD_WEIGHT[concept.kind][field] * termWeight * hit.quality;\n if (strength > best.strength) best = { strength, field, at: field === 'title' ? hit.at : -1 };\n }\n // Found by the backend, but not as a word anywhere visible: it is in the summary (or the\n // part of a long title a row name leaves out). Part of a longer visible word (\"workshop\"\n // for \"shop\") is what the backend's substring match found, so that counts for nothing.\n if (foundBy?.has(term) && !term.split(' ').some((p) => text.visible.includes(p))) {\n const strength =\n (concept.kind === 'subject'\n ? text.titleComplete\n ? ELSEWHERE_WEIGHT.subject.complete\n : ELSEWHERE_WEIGHT.subject.cut\n : ELSEWHERE_WEIGHT.style) * termWeight;\n if (strength > best.strength) best = { strength, field: 'elsewhere', at: -1 };\n }\n });\n return best;\n}\n\nexport interface TemplateScore {\n /** Higher is better; exact matches always outrank close ones. */\n score: number;\n /** Null: nothing of the query fits. */\n match: Exclude<TemplateMatch, 'popular'> | null;\n}\n\nconst mean = (xs: number[]) => (xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : 0);\n\n/**\n * How well one template fits `query`. `foundBy` is the set of query terms the\n * backend found in it (light reads), so a word the caller cannot see still counts.\n */\nexport function scoreTemplate(\n query: TemplateQuery,\n text: TemplateSearchText,\n foundBy?: ReadonlySet<string>,\n): TemplateScore {\n if (query.empty) return { score: 0, match: null };\n const subjects = query.subjects.map((c) => evidenceFor(c, text, foundBy));\n const styles = query.styles.map((c) => evidenceFor(c, text, foundBy));\n let match: TemplateScore['match'] = null;\n if (subjects.length > 0) {\n // Every subject word is what the template is about (its title or tags): exact.\n if (subjects.every((e) => e.field === 'title' || e.field === 'tags')) match = 'exact';\n else if (subjects.some((e) => e.strength > 0)) match = 'close';\n } else {\n const present = styles.filter((e) => e.strength >= 0.5).length;\n if (present >= Math.ceil(styles.length / 2)) match = 'exact';\n else if (styles.some((e) => e.strength > 0)) match = 'close';\n }\n if (!match) return { score: 0, match: null };\n // Subject words side by side in the title read as the phrase that was typed (\"coffee shop\").\n let phrase = 0;\n for (let i = 0; i + 1 < subjects.length; i++) {\n const [a, b] = [subjects[i].at, subjects[i + 1].at];\n if (a < 0 || b < 0) continue;\n const gap = b - a;\n phrase += gap === 1 ? 1 : (gap > 1 && gap <= 3) || gap === -1 ? 0.5 : 0;\n }\n if (subjects.length > 1) phrase /= subjects.length - 1;\n const primary = subjects.length > 0 ? mean(subjects.map((e) => e.strength)) : mean(styles.map((e) => e.strength));\n const secondary = subjects.length > 0 ? mean(styles.map((e) => e.strength)) : 0;\n // A title that is mostly what was asked for (\"Birthday party celebration\") is more about it than one\n // that mentions it on the way (\"Home quiz with a birthday-party theme\").\n const words = text.title.filter((w) => !FILLER.has(w));\n const inTitle = [...subjects, ...styles].filter((e) => e.field === 'title').length;\n const focus = words.length > 0 ? Math.min(1, inTitle / words.length) : 0;\n const tier = match === 'exact' ? 2000 : 1000;\n return { score: tier + 100 * primary + 40 * secondary + 15 * phrase + 8 * focus, match };\n}\n\nexport interface RankedTemplate<T> {\n item: T;\n score: number;\n match: Exclude<TemplateMatch, 'popular'>;\n}\n\n/**\n * The items that fit `query`, best first; ties keep the order they came in (the\n * catalog's own). Items nothing of the query fits are left out.\n */\nexport function rankTemplates<T>(\n query: TemplateQuery,\n items: readonly T[],\n textOf: (item: T) => TemplateSearchText,\n foundByOf?: (item: T) => ReadonlySet<string> | undefined,\n): Array<RankedTemplate<T>> {\n const ranked: Array<RankedTemplate<T> & { order: number }> = [];\n items.forEach((item, order) => {\n const { score, match } = scoreTemplate(query, textOf(item), foundByOf?.(item));\n if (match) ranked.push({ item, score, match, order });\n });\n ranked.sort((a, b) => b.score - a.score || a.order - b.order);\n return ranked.map(({ item, score, match }) => ({ item, score, match }));\n}\n\n/**\n * A row name back to the title it was made from: `canvas-flyer-coffee-shop-grand-opening-027fdd2c`\n * -> \"coffee shop grand opening\". The publish lane slugs titles (long ones cut short) and adds a\n * code; a light read has the name and not the title.\n */\nexport function titleFromRowName(name: string, group: string): string {\n const rest = name.startsWith(`${group}-`) ? name.slice(group.length + 1) : name;\n const parts = rest.split('-');\n if (parts.length > 1) parts.pop();\n return parts.join(' ');\n}\n"],"names":["map"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsx}from'react/jsx-runtime';import {useRef}from'react';import {StyleSheet
|
|
1
|
+
import {jsx}from'react/jsx-runtime';import {useRef}from'react';import {View,StyleSheet}from'react-native';import {GestureDetector,Gesture}from'react-native-gesture-handler';import {dragBlurBox}from'./blurBox.js';function BlurBoxOverlay({
|
|
2
2
|
box,
|
|
3
3
|
onChange
|
|
4
4
|
}) {
|