@aglyn/plugins-ai 1.0.0-beta.269 → 1.0.0-beta.271
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/package.json +17 -17
- package/src/lib/activity/ai-activity-actions.d.ts +1 -1
- package/src/lib/activity/ai-activity-actions.js +1 -0
- package/src/lib/activity/ai-activity-actions.js.map +1 -1
- package/src/lib/assets/site-styles/beauty.webp +0 -0
- package/src/lib/assets/site-styles/blog.webp +0 -0
- package/src/lib/assets/site-styles/business.webp +0 -0
- package/src/lib/assets/site-styles/coming-soon.webp +0 -0
- package/src/lib/assets/site-styles/education.webp +0 -0
- package/src/lib/assets/site-styles/events.webp +0 -0
- package/src/lib/assets/site-styles/fitness.webp +0 -0
- package/src/lib/assets/site-styles/landing.webp +0 -0
- package/src/lib/assets/site-styles/music.webp +0 -0
- package/src/lib/assets/site-styles/nonprofit.webp +0 -0
- package/src/lib/assets/site-styles/personal.webp +0 -0
- package/src/lib/assets/site-styles/photography.webp +0 -0
- package/src/lib/assets/site-styles/portfolio.webp +0 -0
- package/src/lib/assets/site-styles/professional.webp +0 -0
- package/src/lib/assets/site-styles/realestate.webp +0 -0
- package/src/lib/assets/site-styles/restaurant.webp +0 -0
- package/src/lib/assets/site-styles/store.webp +0 -0
- package/src/lib/assets/site-styles/studio.webp +0 -0
- package/src/lib/assets/site-styles/trades.webp +0 -0
- package/src/lib/assets/site-styles/wellness.webp +0 -0
- package/src/lib/assets/site-styles/yoga.webp +0 -0
- package/src/lib/components/ai-credits-card.component.d.ts +8 -6
- package/src/lib/components/ai-credits-card.component.js +39 -22
- package/src/lib/components/ai-credits-card.component.js.map +1 -1
- package/src/lib/components/ai-job-input-form.component.d.ts +36 -0
- package/src/lib/components/ai-job-input-form.component.js +100 -0
- package/src/lib/components/ai-job-input-form.component.js.map +1 -0
- package/src/lib/components/ai-job-links.d.ts +6 -0
- package/src/lib/components/ai-job-links.js +9 -0
- package/src/lib/components/ai-job-links.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +4 -0
- package/src/lib/components/ai-job-requests.js +4 -0
- package/src/lib/components/ai-job-requests.js.map +1 -1
- package/src/lib/components/ai-products-hub-card.component.d.ts +6 -0
- package/src/lib/components/ai-products-hub-card.component.js +21 -6
- package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
- package/src/lib/components/ai-site-build-page.component.js +3 -2
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
- package/src/lib/components/ai-site-start-card.component.js +99 -31
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/components/ai-site-start-steps.component.d.ts +43 -2
- package/src/lib/components/ai-site-start-steps.component.js +651 -15
- package/src/lib/components/ai-site-start-steps.component.js.map +1 -1
- package/src/lib/components/ai-site-start-tracking.d.ts +10 -0
- package/src/lib/components/ai-site-start-tracking.js +14 -0
- package/src/lib/components/ai-site-start-tracking.js.map +1 -1
- package/src/lib/components/ai-site-style-previews.js +26 -22
- package/src/lib/components/ai-site-style-previews.js.map +1 -1
- package/src/lib/components/ai-store-finish-card.component.d.ts +14 -3
- package/src/lib/components/ai-store-finish-card.component.js +67 -9
- package/src/lib/components/ai-store-finish-card.component.js.map +1 -1
- package/src/lib/components/ai-upsell-dialog.component.d.ts +7 -5
- package/src/lib/components/ai-upsell-dialog.component.js +8 -6
- package/src/lib/components/ai-upsell-dialog.component.js.map +1 -1
- package/src/lib/components/assist-build-card.component.js +14 -3
- package/src/lib/components/assist-build-card.component.js.map +1 -1
- package/src/lib/components/assist-jobs-drawer.component.js +9 -1
- package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.js +8 -4
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/components/staff-org-ai-card.component.js +4 -7
- package/src/lib/components/staff-org-ai-card.component.js.map +1 -1
- package/src/lib/declarations.d.ts +2 -2
- package/src/lib/declarations.js +9 -5
- package/src/lib/declarations.js.map +1 -1
- package/src/lib/jobs/ai-build-capabilities.js +3 -1
- package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
- package/src/lib/jobs/ai-business-profile-prefill.d.ts +1 -1
- package/src/lib/jobs/ai-business-profile-prefill.js +14 -3
- package/src/lib/jobs/ai-business-profile-prefill.js.map +1 -1
- package/src/lib/jobs/ai-job-build-step.d.ts +3 -0
- package/src/lib/jobs/ai-job-build-step.js +13 -5
- package/src/lib/jobs/ai-job-build-step.js.map +1 -1
- package/src/lib/jobs/ai-job-form-step.d.ts +24 -1
- package/src/lib/jobs/ai-job-form-step.js +93 -7
- package/src/lib/jobs/ai-job-form-step.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +35 -11
- package/src/lib/jobs/ai-job-page-language.js +68 -2
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.d.ts +17 -0
- package/src/lib/jobs/ai-job-page-step.js +40 -17
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +25 -2
- package/src/lib/jobs/ai-job-plan-step.js +103 -29
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-settings-step.js +4 -3
- package/src/lib/jobs/ai-job-settings-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-datasets.d.ts +27 -0
- package/src/lib/jobs/ai-job-site-datasets.js +140 -14
- package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
- package/src/lib/jobs/ai-job-site-look.js +18 -5
- package/src/lib/jobs/ai-job-site-look.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.d.ts +16 -1
- package/src/lib/jobs/ai-job-site-step.js +95 -22
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-text-step.d.ts +8 -1
- package/src/lib/jobs/ai-job-text-step.js.map +1 -1
- package/src/lib/jobs/ai-job-tracking-step.d.ts +14 -3
- package/src/lib/jobs/ai-job-tracking-step.js +28 -5
- package/src/lib/jobs/ai-job-tracking-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs.d.ts +8 -1
- package/src/lib/jobs/ai-jobs.js +63 -8
- package/src/lib/jobs/ai-jobs.js.map +1 -1
- package/src/lib/jobs/ai-layout-owner-photos.d.ts +57 -0
- package/src/lib/jobs/ai-layout-owner-photos.js +110 -0
- package/src/lib/jobs/ai-layout-owner-photos.js.map +1 -0
- package/src/lib/jobs/ai-layout-stock-photos.d.ts +62 -4
- package/src/lib/jobs/ai-layout-stock-photos.js +523 -72
- package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
- package/src/lib/jobs/ai-site-inspiration-signals.d.ts +98 -0
- package/src/lib/jobs/ai-site-inspiration-signals.js +585 -0
- package/src/lib/jobs/ai-site-inspiration-signals.js.map +1 -0
- package/src/lib/jobs/ai-site-inspiration.d.ts +157 -0
- package/src/lib/jobs/ai-site-inspiration.js +346 -0
- package/src/lib/jobs/ai-site-inspiration.js.map +1 -0
- package/src/lib/jobs/ai-site-publish.d.ts +26 -1
- package/src/lib/jobs/ai-site-publish.js +162 -13
- package/src/lib/jobs/ai-site-publish.js.map +1 -1
- package/src/lib/jobs/ai-theme-brand-inputs.d.ts +16 -0
- package/src/lib/jobs/ai-theme-brand-inputs.js +18 -4
- package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
- package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.d.ts +97 -0
- package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.js +137 -0
- package/src/lib/jobs/fixtures/ai-candle-shop-free-plan-recording.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-site-inspiration-pages.d.ts +38 -0
- package/src/lib/jobs/fixtures/ai-site-inspiration-pages.js +103 -0
- package/src/lib/jobs/fixtures/ai-site-inspiration-pages.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3942-recordings.d.ts +29 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3942-recordings.js +291 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3942-recordings.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.d.ts +25 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.js +174 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl3988-recordings.js.map +1 -0
- package/src/lib/layout-language/ai-layout-compiler.d.ts +1 -1
- package/src/lib/layout-language/ai-layout-compiler.js +438 -25
- package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
- package/src/lib/layout-language/ai-layout-contact.d.ts +57 -0
- package/src/lib/layout-language/ai-layout-contact.js +137 -0
- package/src/lib/layout-language/ai-layout-contact.js.map +1 -0
- package/src/lib/layout-language/ai-layout-copy.d.ts +12 -0
- package/src/lib/layout-language/ai-layout-copy.js +34 -2
- package/src/lib/layout-language/ai-layout-copy.js.map +1 -1
- package/src/lib/layout-language/ai-layout-design.d.ts +65 -8
- package/src/lib/layout-language/ai-layout-design.js +411 -97
- package/src/lib/layout-language/ai-layout-design.js.map +1 -1
- package/src/lib/layout-language/ai-layout-frame.js +23 -0
- package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
- package/src/lib/layout-language/ai-layout-labels.d.ts +2 -0
- package/src/lib/layout-language/ai-layout-labels.js +12 -6
- package/src/lib/layout-language/ai-layout-labels.js.map +1 -1
- package/src/lib/layout-language/ai-layout-language.d.ts +3 -2
- package/src/lib/layout-language/ai-layout-language.js +4 -3
- package/src/lib/layout-language/ai-layout-language.js.map +1 -1
- package/src/lib/layout-language/ai-layout-links.d.ts +13 -0
- package/src/lib/layout-language/ai-layout-links.js +30 -0
- package/src/lib/layout-language/ai-layout-links.js.map +1 -1
- package/src/lib/layout-language/ai-layout-pictures.d.ts +49 -6
- package/src/lib/layout-language/ai-layout-pictures.js +145 -22
- package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
- package/src/lib/model/ai-build-job.d.ts +16 -1
- package/src/lib/model/ai-build-job.js +40 -0
- package/src/lib/model/ai-build-job.js.map +1 -1
- package/src/lib/model/ai-job-input.d.ts +33 -0
- package/src/lib/model/ai-job-input.js +59 -0
- package/src/lib/model/ai-job-input.js.map +1 -0
- package/src/lib/model/ai-job-notice.d.ts +4 -0
- package/src/lib/model/ai-job-notice.js +11 -1
- package/src/lib/model/ai-job-notice.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +40 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-site-details.d.ts +122 -0
- package/src/lib/model/ai-site-details.js +300 -0
- package/src/lib/model/ai-site-details.js.map +1 -0
- package/src/lib/model/ai-site-entity.d.ts +181 -0
- package/src/lib/model/ai-site-entity.js +390 -0
- package/src/lib/model/ai-site-entity.js.map +1 -0
- package/src/lib/model/ai-site-inspiration.d.ts +72 -0
- package/src/lib/model/ai-site-inspiration.js +109 -0
- package/src/lib/model/ai-site-inspiration.js.map +1 -0
- package/src/lib/model/ai-site-job.d.ts +13 -1
- package/src/lib/model/ai-site-job.js +15 -2
- package/src/lib/model/ai-site-job.js.map +1 -1
- package/src/lib/model/ai-site-kinds.js +109 -21
- package/src/lib/model/ai-site-kinds.js.map +1 -1
- package/src/lib/model/ai-site-look.d.ts +10 -0
- package/src/lib/model/ai-site-look.js +24 -0
- package/src/lib/model/ai-site-look.js.map +1 -1
- package/src/lib/model/ai-site-start-seo.d.ts +19 -5
- package/src/lib/model/ai-site-start-seo.js +25 -7
- package/src/lib/model/ai-site-start-seo.js.map +1 -1
- package/src/lib/model/ai-site-start-steps.d.ts +9 -3
- package/src/lib/model/ai-site-start-steps.js +67 -5
- package/src/lib/model/ai-site-start-steps.js.map +1 -1
- package/src/lib/model/ai-site-start.d.ts +68 -4
- package/src/lib/model/ai-site-start.js +166 -13
- package/src/lib/model/ai-site-start.js.map +1 -1
- package/src/lib/model/ai-upsell-copy.js +4 -1
- package/src/lib/model/ai-upsell-copy.js.map +1 -1
- package/src/lib/native-nav.d.ts +26 -0
- package/src/lib/native-nav.js +58 -0
- package/src/lib/native-nav.js.map +1 -0
- package/src/lib/plan-entitlements.d.ts +4 -3
- package/src/lib/plan-entitlements.js +3 -8
- package/src/lib/plan-entitlements.js.map +1 -1
- package/src/lib/runtime/ai-dataset-generation.d.ts +8 -1
- package/src/lib/runtime/ai-dataset-generation.js +12 -2
- package/src/lib/runtime/ai-dataset-generation.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +26 -33
- package/src/lib/runtime/ai-doctrine-validators.js +54 -44
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +1 -1
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/ai-node-tree.d.ts +7 -0
- package/src/lib/runtime/ai-node-tree.js +9 -1
- package/src/lib/runtime/ai-node-tree.js.map +1 -1
- package/src/lib/server/ai-create-route.d.ts +1 -1
- package/src/lib/server/ai-create-route.js +3 -4
- package/src/lib/server/ai-create-route.js.map +1 -1
- package/src/lib/server/ai-jobs-resume.js +27 -3
- package/src/lib/server/ai-jobs-resume.js.map +1 -1
- package/src/lib/server/ai-jobs-route.js +7 -0
- package/src/lib/server/ai-jobs-route.js.map +1 -1
- package/src/lib/usage/assist-credits.d.ts +4 -4
- package/src/lib/usage/assist-credits.js +4 -4
- package/src/lib/usage/assist-credits.js.map +1 -1
- package/src/lib/usage/staff-org-ai-view.js +6 -3
- package/src/lib/usage/staff-org-ai-view.js.map +1 -1
- package/src/lib/usage/staff-org-ai.d.ts +4 -2
- package/src/lib/usage/staff-org-ai.js +7 -7
- package/src/lib/usage/staff-org-ai.js.map +1 -1
- package/src/lib/usage/staff-org-usage-ai.js +2 -2
- package/src/lib/usage/staff-org-usage-ai.js.map +1 -1
|
@@ -178,6 +178,31 @@ import { aiStockBusinessNoun } from "./ai-stock-business-nouns.js";
|
|
|
178
178
|
* part of the job already shows outside its pages — a dataset's records
|
|
179
179
|
* (AGL-3616) — which a page does not place again.
|
|
180
180
|
*/ export const AI_STOCK_PHOTO_AVOID_INPUT = 'stockPhotoAvoid';
|
|
181
|
+
/**
|
|
182
|
+
* The unit job input holding the photos another part of the job placed
|
|
183
|
+
* outside its pages — a dataset's records — with their size and words
|
|
184
|
+
* (AGL-3988): what a picture the library failed takes before any starter.
|
|
185
|
+
*/ export const AI_STOCK_PHOTO_JOB_PHOTOS_INPUT = 'stockPhotoJobPhotos';
|
|
186
|
+
/** The job photos a unit input holds ({@link AI_STOCK_PHOTO_JOB_PHOTOS_INPUT}): library photos with a size; anything else is dropped. */ export function aiStockJobPhotosOf(value) {
|
|
187
|
+
if (!Array.isArray(value)) return [];
|
|
188
|
+
return value.flatMap((entry)=>{
|
|
189
|
+
const photo = entry;
|
|
190
|
+
const src = typeof (photo == null ? void 0 : photo.src) === 'string' ? photo.src : '';
|
|
191
|
+
const width = Number(photo == null ? void 0 : photo.width);
|
|
192
|
+
const height = Number(photo == null ? void 0 : photo.height);
|
|
193
|
+
if (!src.startsWith('media:') || !(width > 0) || !(height > 0)) return [];
|
|
194
|
+
const alt = typeof (photo == null ? void 0 : photo.alt) === 'string' ? photo.alt.trim() : '';
|
|
195
|
+
return [
|
|
196
|
+
_extends({
|
|
197
|
+
src,
|
|
198
|
+
width,
|
|
199
|
+
height
|
|
200
|
+
}, alt ? {
|
|
201
|
+
alt
|
|
202
|
+
} : {})
|
|
203
|
+
];
|
|
204
|
+
});
|
|
205
|
+
}
|
|
181
206
|
const words = (list)=>new Set(list.trim().split(/\s+/));
|
|
182
207
|
/** Words that carry no subject. */ const STOPWORDS = words('a an the and or of in on at to for with from by into onto over under near our your their my his her its ' + 'this that these those is are be being was were who whom which where while as about than then very just ' + 'small local best new top quality premium family-owned family owned independent professional ' + 'business company services service page photo picture image showing shows show ' + 'someone people person one two three some many several');
|
|
183
208
|
/**
|
|
@@ -1985,7 +2010,56 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
1985
2010
|
const said = texts.filter(Boolean).join(' . ');
|
|
1986
2011
|
return ADULT_AUDIENCE.test(said) && !YOUNG_AUDIENCE.test(said);
|
|
1987
2012
|
}
|
|
1988
|
-
/**
|
|
2013
|
+
/**
|
|
2014
|
+
* Words a photo by the sea is tagged with: never one set in the mountains, a
|
|
2015
|
+
* forest or a city (AGL-3942). Never "palm" or "wave", a hand's as often.
|
|
2016
|
+
*/ const SEASIDE = [
|
|
2017
|
+
'beach',
|
|
2018
|
+
'beaches',
|
|
2019
|
+
'sea',
|
|
2020
|
+
'seaside',
|
|
2021
|
+
'seashore',
|
|
2022
|
+
'ocean',
|
|
2023
|
+
'coast',
|
|
2024
|
+
'coastal',
|
|
2025
|
+
'shore',
|
|
2026
|
+
'shoreline',
|
|
2027
|
+
'surf',
|
|
2028
|
+
'waves',
|
|
2029
|
+
'caribbean',
|
|
2030
|
+
'tropical',
|
|
2031
|
+
'island',
|
|
2032
|
+
'lagoon',
|
|
2033
|
+
'bay',
|
|
2034
|
+
'pier'
|
|
2035
|
+
];
|
|
2036
|
+
/** Words a photo of a desert is tagged with. */ const DESERT = [
|
|
2037
|
+
'desert',
|
|
2038
|
+
'dune',
|
|
2039
|
+
'dunes',
|
|
2040
|
+
'cactus',
|
|
2041
|
+
'sahara'
|
|
2042
|
+
];
|
|
2043
|
+
/** Words a photo of a city is tagged with. */ const CITYSCAPE = [
|
|
2044
|
+
'city',
|
|
2045
|
+
'urban',
|
|
2046
|
+
'downtown',
|
|
2047
|
+
'street',
|
|
2048
|
+
'skyline',
|
|
2049
|
+
'skyscraper',
|
|
2050
|
+
'skyscrapers',
|
|
2051
|
+
'subway',
|
|
2052
|
+
'metro'
|
|
2053
|
+
];
|
|
2054
|
+
/**
|
|
2055
|
+
* Where a picture of a moment is set, by the words that name it, the word a
|
|
2056
|
+
* search and a photo say it with, whether it is a place a photo can show on
|
|
2057
|
+
* its own (a landscape, not a season), and the words of the places it is
|
|
2058
|
+
* not, which none of a photo's first tags may name (AGL-3942): the beta.267
|
|
2059
|
+
* Copper Hollow Film & Portrait galleries, a Blue Ridge photographer's,
|
|
2060
|
+
* showed two couples on a beach, tagged "beach, couple, nature, mountain"
|
|
2061
|
+
* and "romantic wedding couple, the beach".
|
|
2062
|
+
*/ const SCENE_SETTINGS = [
|
|
1989
2063
|
{
|
|
1990
2064
|
words: [
|
|
1991
2065
|
'mountain',
|
|
@@ -1998,7 +2072,13 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
1998
2072
|
'overlook',
|
|
1999
2073
|
'parkway'
|
|
2000
2074
|
],
|
|
2001
|
-
said: 'mountains'
|
|
2075
|
+
said: 'mountains',
|
|
2076
|
+
landscape: true,
|
|
2077
|
+
away: [
|
|
2078
|
+
...SEASIDE,
|
|
2079
|
+
...DESERT,
|
|
2080
|
+
...CITYSCAPE
|
|
2081
|
+
]
|
|
2002
2082
|
},
|
|
2003
2083
|
{
|
|
2004
2084
|
words: [
|
|
@@ -2006,7 +2086,14 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2006
2086
|
'autumn',
|
|
2007
2087
|
'foliage'
|
|
2008
2088
|
],
|
|
2009
|
-
said: 'autumn'
|
|
2089
|
+
said: 'autumn',
|
|
2090
|
+
away: [
|
|
2091
|
+
'winter',
|
|
2092
|
+
'snow',
|
|
2093
|
+
'snowy',
|
|
2094
|
+
'spring',
|
|
2095
|
+
'blossom'
|
|
2096
|
+
]
|
|
2010
2097
|
},
|
|
2011
2098
|
{
|
|
2012
2099
|
words: [
|
|
@@ -2014,7 +2101,12 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2014
2101
|
'snow',
|
|
2015
2102
|
'snowy'
|
|
2016
2103
|
],
|
|
2017
|
-
said: 'winter'
|
|
2104
|
+
said: 'winter',
|
|
2105
|
+
away: [
|
|
2106
|
+
...SEASIDE,
|
|
2107
|
+
'summer',
|
|
2108
|
+
'tropical'
|
|
2109
|
+
]
|
|
2018
2110
|
},
|
|
2019
2111
|
{
|
|
2020
2112
|
words: [
|
|
@@ -2024,7 +2116,15 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2024
2116
|
'shore',
|
|
2025
2117
|
'ocean'
|
|
2026
2118
|
],
|
|
2027
|
-
said: 'beach'
|
|
2119
|
+
said: 'beach',
|
|
2120
|
+
landscape: true,
|
|
2121
|
+
away: [
|
|
2122
|
+
'snow',
|
|
2123
|
+
'snowy',
|
|
2124
|
+
'ski',
|
|
2125
|
+
'skiing',
|
|
2126
|
+
...CITYSCAPE
|
|
2127
|
+
]
|
|
2028
2128
|
},
|
|
2029
2129
|
{
|
|
2030
2130
|
words: [
|
|
@@ -2032,7 +2132,13 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2032
2132
|
'woods',
|
|
2033
2133
|
'woodland'
|
|
2034
2134
|
],
|
|
2035
|
-
said: 'forest'
|
|
2135
|
+
said: 'forest',
|
|
2136
|
+
landscape: true,
|
|
2137
|
+
away: [
|
|
2138
|
+
...SEASIDE,
|
|
2139
|
+
...DESERT,
|
|
2140
|
+
...CITYSCAPE
|
|
2141
|
+
]
|
|
2036
2142
|
},
|
|
2037
2143
|
{
|
|
2038
2144
|
words: [
|
|
@@ -2040,7 +2146,14 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2040
2146
|
'blossom',
|
|
2041
2147
|
'blossoms'
|
|
2042
2148
|
],
|
|
2043
|
-
said: 'spring'
|
|
2149
|
+
said: 'spring',
|
|
2150
|
+
away: [
|
|
2151
|
+
'winter',
|
|
2152
|
+
'snow',
|
|
2153
|
+
'snowy',
|
|
2154
|
+
'autumn',
|
|
2155
|
+
'fall'
|
|
2156
|
+
]
|
|
2044
2157
|
},
|
|
2045
2158
|
{
|
|
2046
2159
|
words: [
|
|
@@ -2048,16 +2161,27 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2048
2161
|
'urban',
|
|
2049
2162
|
'downtown'
|
|
2050
2163
|
],
|
|
2051
|
-
said: 'city'
|
|
2164
|
+
said: 'city',
|
|
2165
|
+
landscape: true,
|
|
2166
|
+
away: [
|
|
2167
|
+
...SEASIDE,
|
|
2168
|
+
...DESERT
|
|
2169
|
+
]
|
|
2052
2170
|
}
|
|
2053
2171
|
];
|
|
2172
|
+
/** The stems of the places a setting is not ({@link SCENE_SETTINGS}); none for no setting. */ export function aiStockSettingAway(setting) {
|
|
2173
|
+
const entry = SCENE_SETTINGS.find((candidate)=>candidate.said === setting);
|
|
2174
|
+
return (entry == null ? void 0 : entry.away) ? [
|
|
2175
|
+
...new Set(entry.away.map(aiStockStem))
|
|
2176
|
+
] : [];
|
|
2177
|
+
}
|
|
2054
2178
|
/**
|
|
2055
2179
|
* The scene a picture's words name (AGL-3856): the people at a moment, and
|
|
2056
2180
|
* where — "Ridgetop Elopement" a couple in the mountains, "Mountain Wedding
|
|
2057
2181
|
* Day" a wedding couple in the mountains, "Family Session in the Fall" a
|
|
2058
2182
|
* family in autumn — read from every word, never only the first clause.
|
|
2059
2183
|
* `null` where it names no people.
|
|
2060
|
-
*/ export function aiStockScene(text) {
|
|
2184
|
+
*/ export function aiStockScene(text, siteSetting = '') {
|
|
2061
2185
|
const named = sceneWords(text);
|
|
2062
2186
|
const scene = PEOPLE_SCENES.find((entry)=>entry.words.some((word)=>named.has(word)));
|
|
2063
2187
|
if (!scene) return null;
|
|
@@ -2080,7 +2204,9 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2080
2204
|
shun: scene.shun.filter((word)=>!named.has(word)).map(aiStockStem),
|
|
2081
2205
|
named: [
|
|
2082
2206
|
...new Set(stemList(text))
|
|
2083
|
-
]
|
|
2207
|
+
],
|
|
2208
|
+
// Searched where its own words set it; never shown anywhere the site is not.
|
|
2209
|
+
away: aiStockSettingAway(setting || siteSetting)
|
|
2084
2210
|
};
|
|
2085
2211
|
}
|
|
2086
2212
|
/** A text's lowercase words, letters only. */ const sceneWords = (text)=>new Set(text.toLowerCase().split(/[^a-zÀ-ɏ]+/).filter(Boolean));
|
|
@@ -2131,9 +2257,53 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2131
2257
|
shun: scene.shun.filter((word)=>!all.has(word)).map(aiStockStem),
|
|
2132
2258
|
named: [
|
|
2133
2259
|
...new Set(stemList(texts.join(' ')))
|
|
2134
|
-
]
|
|
2260
|
+
],
|
|
2261
|
+
away: aiStockSettingAway(setting)
|
|
2135
2262
|
};
|
|
2136
2263
|
}
|
|
2264
|
+
/**
|
|
2265
|
+
* The work a craft whose pictures are people at a moment shows (AGL-3942):
|
|
2266
|
+
* the scenes its site's own words name, in the order they name them, each
|
|
2267
|
+
* set where the site is — a wedding photographer "for couples planning
|
|
2268
|
+
* mountain weddings, and families" shows a wedding couple in the mountains
|
|
2269
|
+
* and a family in the mountains. A family session still never shows a
|
|
2270
|
+
* bride, whatever else the site names. Empty where its words name no people.
|
|
2271
|
+
*/ export function aiStockWorkScenes(text, setting = '') {
|
|
2272
|
+
const list = text.toLowerCase().split(/[^a-zÀ-ɏ]+/).filter(Boolean);
|
|
2273
|
+
const found = PEOPLE_SCENES.map((scene)=>({
|
|
2274
|
+
scene,
|
|
2275
|
+
at: list.findIndex((word)=>scene.words.includes(word))
|
|
2276
|
+
})).filter((entry)=>entry.at >= 0).sort((a, b)=>a.at - b.at);
|
|
2277
|
+
return found.map(({ scene })=>{
|
|
2278
|
+
const named = new Set(list.filter((word)=>scene.words.includes(word)));
|
|
2279
|
+
const query = scene.query(named);
|
|
2280
|
+
return {
|
|
2281
|
+
queries: [
|
|
2282
|
+
...new Set([
|
|
2283
|
+
setting ? `${query} ${setting}` : '',
|
|
2284
|
+
query
|
|
2285
|
+
].filter(Boolean))
|
|
2286
|
+
],
|
|
2287
|
+
subject: [
|
|
2288
|
+
scene.subject,
|
|
2289
|
+
setting
|
|
2290
|
+
].filter(Boolean).join(' '),
|
|
2291
|
+
object: scene.subject,
|
|
2292
|
+
lead: scene.lead.filter((phrase)=>!RECORD_SCENE_UNPEOPLED.has(phrase)).map((phrase)=>stemList(phrase).join(' ')),
|
|
2293
|
+
people: scene.people.map(aiStockStem),
|
|
2294
|
+
shun: scene.shun.map(aiStockStem),
|
|
2295
|
+
named: [
|
|
2296
|
+
...new Set([
|
|
2297
|
+
...named
|
|
2298
|
+
].map(aiStockStem))
|
|
2299
|
+
],
|
|
2300
|
+
away: aiStockSettingAway(setting)
|
|
2301
|
+
};
|
|
2302
|
+
});
|
|
2303
|
+
}
|
|
2304
|
+
/** Whether a setting is a place a photo shows on its own, a landscape searched by its name: "mountains", never "autumn". */ export function aiStockSettingIsLandscape(setting) {
|
|
2305
|
+
return SCENE_SETTINGS.some((entry)=>entry.said === setting && entry.landscape === true);
|
|
2306
|
+
}
|
|
2137
2307
|
/**
|
|
2138
2308
|
* A scene's lead words a record's cover never leads with alone
|
|
2139
2309
|
* ({@link aiStockRecordScene}): the moment with no one in it (a wedding's table
|
|
@@ -2373,7 +2543,7 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2373
2543
|
* asks first for the role its words or its list's name (`sectionName`) say,
|
|
2374
2544
|
* in the site's world: "teacher classroom" for a "Math instructor" (AGL-3856).
|
|
2375
2545
|
*/ export function aiStockSearchesFor(slot, terms, subject, part, sectionName = '') {
|
|
2376
|
-
var _terms_core, _terms_making, _ref, _ref1, _terms_setting, _ref2, _terms_maker, _ref3;
|
|
2546
|
+
var _terms_core, _terms_making, _ref, _ref1, _terms_setting, _terms_setting1, _ref2, _terms_maker, _terms_maker1, _ref3;
|
|
2377
2547
|
var _aiStockPeopleRole, _slot_record, _slot_record1;
|
|
2378
2548
|
const orientation = aiStockOrientation(slot.aspect);
|
|
2379
2549
|
const size = slot.role === 'hero' ? {
|
|
@@ -2389,6 +2559,21 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2389
2559
|
// searched "photographer mountain elopements" and placed a press
|
|
2390
2560
|
// photographer, a toy frog with a camera and a cat (AGL-3856).
|
|
2391
2561
|
const work = aiStockShowsTheWork(slot, terms);
|
|
2562
|
+
// Every other picture of such a craft's site shows its work where a page
|
|
2563
|
+
// would show the maker (AGL-3942): the beta.267 Copper Hollow Film &
|
|
2564
|
+
// Portrait about page searched "photographer at work" and "photographer
|
|
2565
|
+
// camera", and every picture on it was a stock photographer.
|
|
2566
|
+
const itsWork = !work && aiStockShowsItsWork(slot, terms);
|
|
2567
|
+
/** Whether a query names the craft by its own name, the profession's noun: "wedding photographer". */ const namesCraft = (query)=>stemList(query).some((stem)=>{
|
|
2568
|
+
var _terms_core;
|
|
2569
|
+
return ((_terms_core = terms.core) != null ? _terms_core : []).includes(stem);
|
|
2570
|
+
});
|
|
2571
|
+
/** Whether a query names the maker, their tools or the craft: "photographer at work", "photographer camera". */ const namesMaker = (query)=>namesCraft(query) || stemList(query).some((stem)=>{
|
|
2572
|
+
var _terms_maker;
|
|
2573
|
+
return ((_terms_maker = terms.maker) != null ? _terms_maker : []).includes(stem);
|
|
2574
|
+
});
|
|
2575
|
+
/** A rung of the maker's own photos, left out on a site that shows its work. */ const shown = (query)=>!itsWork || !namesMaker(query);
|
|
2576
|
+
/** A search of the slot's own words, left out on such a site only where they name the profession. */ const said = (query)=>!itsWork || !namesCraft(query);
|
|
2392
2577
|
const object = aiStockObjectWord(subject);
|
|
2393
2578
|
const subjectStems = stemList(subject);
|
|
2394
2579
|
const kin = object ? objectKin(object, [
|
|
@@ -2409,13 +2594,13 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2409
2594
|
// own object among the first tags, and searched by its object's kin, never
|
|
2410
2595
|
// the category's world alone (AGL-3660).
|
|
2411
2596
|
const collection = part === 'collection' && Boolean(terms.craft) && !work;
|
|
2412
|
-
const broad = kin && collection || work ? [] : terms.broad.map((query)=>({
|
|
2597
|
+
const broad = kin && collection || work ? [] : terms.broad.filter(shown).map((query)=>({
|
|
2413
2598
|
query,
|
|
2414
2599
|
broad: true,
|
|
2415
2600
|
category: collection
|
|
2416
2601
|
}));
|
|
2417
2602
|
// The maker at work, held to the craft: never "hands" (AGL-3660).
|
|
2418
|
-
const
|
|
2603
|
+
const makers = (work ? [] : (_terms_making = terms.making) != null ? _terms_making : []).filter(shown).map((query)=>({
|
|
2419
2604
|
query,
|
|
2420
2605
|
broad: true,
|
|
2421
2606
|
category: true
|
|
@@ -2424,10 +2609,18 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2424
2609
|
const roleWord = slot.people ? (_ref = (_aiStockPeopleRole = aiStockPeopleRole(slot.alt, sectionName)) == null ? void 0 : _aiStockPeopleRole.query) != null ? _ref : '' : '';
|
|
2425
2610
|
const role = roleWord ? stemList(terms.business).includes(roleWord) ? terms.business : `${roleWord} ${terms.business}`.trim() : '';
|
|
2426
2611
|
// A scene's people are read from every word of the picture's, never its first clause alone.
|
|
2427
|
-
const scene = work ? aiStockRecordScene(slot.alt, (_ref1 = (_slot_record = slot.record) == null ? void 0 : _slot_record.category) != null ? _ref1 : '', (_terms_setting = terms.setting) != null ? _terms_setting : '') : terms.scenes && slot.role !== 'hero' && part !== 'collection' ? aiStockScene(slot.alt) : null;
|
|
2612
|
+
const scene = work ? aiStockRecordScene(slot.alt, (_ref1 = (_slot_record = slot.record) == null ? void 0 : _slot_record.category) != null ? _ref1 : '', (_terms_setting = terms.setting) != null ? _terms_setting : '') : terms.scenes && slot.role !== 'hero' && part !== 'collection' ? aiStockScene(slot.alt, (_terms_setting1 = terms.setting) != null ? _terms_setting1 : '') : null;
|
|
2613
|
+
// The site's own scenes, turned per slot so a page's pictures show each of them.
|
|
2614
|
+
const sceneList = [];
|
|
2615
|
+
if (itsWork) {
|
|
2616
|
+
var _terms_work;
|
|
2617
|
+
const own = (_terms_work = terms.work) != null ? _terms_work : [];
|
|
2618
|
+
const turn = own.length ? aiLayoutSeedNumber(`${sectionName}|${slot.alt}`) % own.length : 0;
|
|
2619
|
+
sceneList.push(...own.slice(turn), ...own.slice(0, turn));
|
|
2620
|
+
}
|
|
2428
2621
|
// The work's own subject is never qualified by the craft: "getting ready", never "photographer getting ready".
|
|
2429
2622
|
const own = work ? (phrase)=>phrase : qualify;
|
|
2430
|
-
const thing = subject ? [
|
|
2623
|
+
const thing = (subject ? [
|
|
2431
2624
|
{
|
|
2432
2625
|
query: own(subject),
|
|
2433
2626
|
held: true
|
|
@@ -2441,7 +2634,7 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2441
2634
|
held: true
|
|
2442
2635
|
}
|
|
2443
2636
|
]
|
|
2444
|
-
] : [];
|
|
2637
|
+
] : []).filter((query)=>said(query.query));
|
|
2445
2638
|
// Never the maker, the camera, an animal or a toy, unless the record names it.
|
|
2446
2639
|
const recordNamed = work ? new Set(stemList(`${slot.alt} ${(_ref2 = (_slot_record1 = slot.record) == null ? void 0 : _slot_record1.category) != null ? _ref2 : ''}`)) : null;
|
|
2447
2640
|
const refuseLead = recordNamed ? [
|
|
@@ -2452,12 +2645,23 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2452
2645
|
].map(aiStockStem)
|
|
2453
2646
|
])
|
|
2454
2647
|
].filter((stem)=>!recordNamed.has(stem)) : [];
|
|
2648
|
+
// Where the maker's rungs were, a site that shows its work searches its work.
|
|
2649
|
+
const shows = {
|
|
2650
|
+
query: '',
|
|
2651
|
+
work: true
|
|
2652
|
+
};
|
|
2653
|
+
const making = itsWork ? [
|
|
2654
|
+
shows
|
|
2655
|
+
] : makers;
|
|
2455
2656
|
const queries = slot.role === 'hero' ? [
|
|
2456
2657
|
{
|
|
2457
2658
|
query: terms.business,
|
|
2458
2659
|
broad: true
|
|
2459
2660
|
},
|
|
2460
|
-
...broad
|
|
2661
|
+
...broad,
|
|
2662
|
+
...itsWork ? [
|
|
2663
|
+
shows
|
|
2664
|
+
] : []
|
|
2461
2665
|
] : slot.role === 'about' ? [
|
|
2462
2666
|
...role ? [
|
|
2463
2667
|
{
|
|
@@ -2467,50 +2671,109 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2467
2671
|
}
|
|
2468
2672
|
] : [],
|
|
2469
2673
|
...part === 'story' ? making : [],
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2674
|
+
...[
|
|
2675
|
+
{
|
|
2676
|
+
query: `${terms.business} ${subject}`,
|
|
2677
|
+
broad: true,
|
|
2678
|
+
people: true
|
|
2679
|
+
},
|
|
2680
|
+
{
|
|
2681
|
+
query: terms.business,
|
|
2682
|
+
broad: true,
|
|
2683
|
+
people: true
|
|
2684
|
+
}
|
|
2685
|
+
].filter((query)=>said(query.query)),
|
|
2480
2686
|
...part === 'story' ? [] : making,
|
|
2481
2687
|
...broad
|
|
2482
2688
|
] : [
|
|
2483
2689
|
...part === 'story' ? making : [],
|
|
2484
2690
|
...scene ? [] : thing,
|
|
2691
|
+
...itsWork ? [
|
|
2692
|
+
shows
|
|
2693
|
+
] : [],
|
|
2485
2694
|
...broad
|
|
2486
2695
|
];
|
|
2487
2696
|
const seen = new Set();
|
|
2488
2697
|
const searches = [];
|
|
2489
2698
|
// A picture of people at a moment asks for them, and where, before anything
|
|
2490
2699
|
// else, and takes only a photo leading with them (AGL-3856): never the
|
|
2491
|
-
// roses of a "Mountain Wedding Day", nor a bride for a family session.
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2700
|
+
// roses of a "Mountain Wedding Day", nor a bride for a family session. A
|
|
2701
|
+
// picture of the work never leads with the maker or a camera (AGL-3942).
|
|
2702
|
+
const workLead = itsWork ? (_terms_maker1 = terms.maker) != null ? _terms_maker1 : [] : [];
|
|
2703
|
+
// The site's work is held to its own scene, never to the craft's world.
|
|
2704
|
+
const sceneSearch = (one, query, ofWork)=>{
|
|
2705
|
+
const refused = [
|
|
2706
|
+
...new Set([
|
|
2707
|
+
...refuseLead,
|
|
2708
|
+
...workLead.filter((stem)=>!one.named.includes(stem))
|
|
2709
|
+
])
|
|
2710
|
+
];
|
|
2711
|
+
return _extends({
|
|
2495
2712
|
query,
|
|
2496
2713
|
orientation
|
|
2497
2714
|
}, size, {
|
|
2498
2715
|
strict: true,
|
|
2499
|
-
subject:
|
|
2500
|
-
object:
|
|
2501
|
-
kin:
|
|
2716
|
+
subject: one.subject,
|
|
2717
|
+
object: one.object,
|
|
2718
|
+
kin: one.lead,
|
|
2502
2719
|
lead: true,
|
|
2503
|
-
needs:
|
|
2504
|
-
allow:
|
|
2505
|
-
},
|
|
2506
|
-
refuse:
|
|
2507
|
-
} : {},
|
|
2508
|
-
refuseLead
|
|
2509
|
-
} : {},
|
|
2720
|
+
needs: one.people,
|
|
2721
|
+
allow: one.named
|
|
2722
|
+
}, one.shun.length ? {
|
|
2723
|
+
refuse: one.shun
|
|
2724
|
+
} : {}, refused.length ? {
|
|
2725
|
+
refuseLead: refused
|
|
2726
|
+
} : {}, one.away.length ? {
|
|
2727
|
+
away: one.away
|
|
2728
|
+
} : {}, work || ofWork ? {
|
|
2510
2729
|
worldless: true
|
|
2511
|
-
} : {})
|
|
2730
|
+
} : {});
|
|
2731
|
+
};
|
|
2732
|
+
for (const query of (_ref3 = scene == null ? void 0 : scene.queries) != null ? _ref3 : []){
|
|
2733
|
+
seen.add(`${query}|false`);
|
|
2734
|
+
searches.push(sceneSearch(scene, query, false));
|
|
2512
2735
|
}
|
|
2736
|
+
/** The site's own scenes, then the place itself where it is a landscape: "mountains". */ const workSearches = ()=>{
|
|
2737
|
+
var _ref;
|
|
2738
|
+
var _SCENE_SETTINGS_find;
|
|
2739
|
+
const found = [];
|
|
2740
|
+
for (const one of sceneList)for (const query of one.queries){
|
|
2741
|
+
if (seen.has(`${query}|false`)) continue;
|
|
2742
|
+
seen.add(`${query}|false`);
|
|
2743
|
+
found.push(sceneSearch(one, query, true));
|
|
2744
|
+
}
|
|
2745
|
+
const place = terms.setting && aiStockSettingIsLandscape(terms.setting) ? terms.setting : '';
|
|
2746
|
+
if (!place || seen.has(`${place}|false`)) return found;
|
|
2747
|
+
seen.add(`${place}|false`);
|
|
2748
|
+
const away = aiStockSettingAway(place);
|
|
2749
|
+
const stems = (_ref = (_SCENE_SETTINGS_find = SCENE_SETTINGS.find((entry)=>entry.said === place)) == null ? void 0 : _SCENE_SETTINGS_find.words.map(aiStockStem)) != null ? _ref : [];
|
|
2750
|
+
found.push(_extends({
|
|
2751
|
+
query: place,
|
|
2752
|
+
orientation
|
|
2753
|
+
}, size, {
|
|
2754
|
+
strict: true,
|
|
2755
|
+
subject: place,
|
|
2756
|
+
object: aiStockStem(place),
|
|
2757
|
+
kin: [
|
|
2758
|
+
...new Set(stems)
|
|
2759
|
+
],
|
|
2760
|
+
lead: true
|
|
2761
|
+
}, workLead.length ? {
|
|
2762
|
+
refuseLead: [
|
|
2763
|
+
...workLead
|
|
2764
|
+
]
|
|
2765
|
+
} : {}, away.length ? {
|
|
2766
|
+
away
|
|
2767
|
+
} : {}, {
|
|
2768
|
+
worldless: true
|
|
2769
|
+
}));
|
|
2770
|
+
return found;
|
|
2771
|
+
};
|
|
2513
2772
|
for (const raw of queries){
|
|
2773
|
+
if (raw.work) {
|
|
2774
|
+
searches.push(...workSearches());
|
|
2775
|
+
continue;
|
|
2776
|
+
}
|
|
2514
2777
|
const query = clip(raw.query);
|
|
2515
2778
|
const key = `${query}|${raw.people === true}`;
|
|
2516
2779
|
if (!query || seen.has(key)) continue;
|
|
@@ -2546,6 +2809,17 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2546
2809
|
}
|
|
2547
2810
|
return searches;
|
|
2548
2811
|
}
|
|
2812
|
+
/**
|
|
2813
|
+
* Whether a picture of a craft's site whose pictures are people at a moment
|
|
2814
|
+
* shows that work wherever a page would show the maker (AGL-3942): an about
|
|
2815
|
+
* picture, a story of the craft, an intro's cover. Not a record (which shows
|
|
2816
|
+
* its own moment, {@link aiStockShowsTheWork}), a portrait of the business's
|
|
2817
|
+
* people, nor a product; and only where the site's words name the work.
|
|
2818
|
+
*/ export function aiStockShowsItsWork(slot, terms) {
|
|
2819
|
+
var _ref;
|
|
2820
|
+
var _terms_work;
|
|
2821
|
+
return Boolean(terms.scenes) && ((_ref = (_terms_work = terms.work) == null ? void 0 : _terms_work.length) != null ? _ref : 0) > 0 && !slot.record && !slot.people && !slot.product;
|
|
2822
|
+
}
|
|
2549
2823
|
/**
|
|
2550
2824
|
* Whether a slot is a portfolio's record of a craft whose work is people at a
|
|
2551
2825
|
* moment (AGL-3856): a photographer's "Mountain Elopements" shows an
|
|
@@ -2628,7 +2902,7 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2628
2902
|
* site's world 1, plus a quarter when it is among the first tags.
|
|
2629
2903
|
*/ export function aiStockRelevance(photo, judgement) {
|
|
2630
2904
|
var _judgement_rivals, _judgement_subject, _judgement_named, _judgement_shun, _judgement_refuse, _judgement_refuseLead, _judgement_needs, _judgement_shunLead, _judgement_leadAny, _judgement_kin, _judgement_requires, _judgement_category, _judgement_object, _judgement_domain, _judgement_roles;
|
|
2631
|
-
var _judgement_roleScene, _judgement_roleRefuse;
|
|
2905
|
+
var _judgement_roleScene, _judgement_roleRefuse, _judgement_away;
|
|
2632
2906
|
const hit = hitWords(photo);
|
|
2633
2907
|
if (hit.rejected) return 0;
|
|
2634
2908
|
if (aiStockSensitive(photo, judgement.named)) return 0;
|
|
@@ -2656,6 +2930,12 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2656
2930
|
const read = new Set(stemList(((_photo_tags1 = photo.tags) != null ? _photo_tags1 : []).slice(0, ALT_TAGS_READ).join(' ')));
|
|
2657
2931
|
if (((_judgement_roleRefuse1 = judgement.roleRefuse) != null ? _judgement_roleRefuse1 : []).some((stem)=>read.has(stem))) return 0;
|
|
2658
2932
|
}
|
|
2933
|
+
// A Blue Ridge couple is never on a beach, however its later tags name a mountain (AGL-3942).
|
|
2934
|
+
if ((_judgement_away = judgement.away) == null ? void 0 : _judgement_away.length) {
|
|
2935
|
+
var _photo_tags2;
|
|
2936
|
+
const read = new Set(stemList(((_photo_tags2 = photo.tags) != null ? _photo_tags2 : []).slice(0, ALT_TAGS_READ).join(' ')));
|
|
2937
|
+
if (judgement.away.some((stem)=>read.has(stem))) return 0;
|
|
2938
|
+
}
|
|
2659
2939
|
// A wedding day shows its people: a close-up of roses tagged "wedding" never fills it.
|
|
2660
2940
|
const needs = (_judgement_needs = judgement.needs) != null ? _judgement_needs : [];
|
|
2661
2941
|
if (needs.length && !needs.some((word)=>hit.all.has(word))) return 0;
|
|
@@ -2823,6 +3103,35 @@ const clip = (query)=>query.replace(/\s+/g, ' ').trim().slice(0, STOCK_PHOTO_QUE
|
|
|
2823
3103
|
}
|
|
2824
3104
|
return out;
|
|
2825
3105
|
}
|
|
3106
|
+
/**
|
|
3107
|
+
* The library photos a stored page shows, each as a slot takes it (AGL-3988):
|
|
3108
|
+
* its source, its size and what it shows. A photo the job placed on another
|
|
3109
|
+
* page is what a slot the library failed takes before any starter
|
|
3110
|
+
* (`aiLayoutJobPhotoPicks`). Each photo once; one without a size is left out.
|
|
3111
|
+
*/ export function aiStockPlacedPhotos(nodes) {
|
|
3112
|
+
const map = nodes != null ? nodes : {};
|
|
3113
|
+
const out = new Map();
|
|
3114
|
+
for (const node of Object.values(map)){
|
|
3115
|
+
var _node_props, _node_props1, _node_props2, _node_props3;
|
|
3116
|
+
if ((node == null ? void 0 : node.componentId) !== 'image') continue;
|
|
3117
|
+
const src = (_node_props = node.props) == null ? void 0 : _node_props['src'];
|
|
3118
|
+
const width = Number((_node_props1 = node.props) == null ? void 0 : _node_props1['intrinsicWidth']);
|
|
3119
|
+
const height = Number((_node_props2 = node.props) == null ? void 0 : _node_props2['intrinsicHeight']);
|
|
3120
|
+
if (typeof src !== 'string' || !src.startsWith('media:') || out.has(src)) continue;
|
|
3121
|
+
if (!(width > 0) || !(height > 0)) continue;
|
|
3122
|
+
const alt = typeof ((_node_props3 = node.props) == null ? void 0 : _node_props3['alt']) === 'string' ? node.props['alt'].trim() : '';
|
|
3123
|
+
out.set(src, _extends({
|
|
3124
|
+
src,
|
|
3125
|
+
width,
|
|
3126
|
+
height
|
|
3127
|
+
}, alt ? {
|
|
3128
|
+
alt
|
|
3129
|
+
} : {}));
|
|
3130
|
+
}
|
|
3131
|
+
return [
|
|
3132
|
+
...out.values()
|
|
3133
|
+
];
|
|
3134
|
+
}
|
|
2826
3135
|
/**
|
|
2827
3136
|
* What this process has placed for each job, by source key and asset src,
|
|
2828
3137
|
* with the scope (the page's seed) that placed it (AGL-3660). It spans the
|
|
@@ -2854,16 +3163,39 @@ function jobPhotos(key) {
|
|
|
2854
3163
|
* Words a tag uses for how a photo looks or feels, never a thing it shows
|
|
2855
3164
|
* (AGL-3856): "extravagant" of "wedding dress, bride, extravagant", "moody"
|
|
2856
3165
|
* of "forest, human, photographer", a season or a people's name.
|
|
2857
|
-
*/ const DESCRIBING = words('love romance romantic luxury luxurious fancy extravagant happiness happy beauty emotion emotions mood lifestyle ' + 'concept aesthetic wallpaper background retro vintage antique old young cute sexy fun funny sad positive negative healthy fit ' + 'strong powerful homemade tasty yummy sweet sweetness nice dark bw monochrome macro sporty active married bridal ' + 'female male adult good bad poc bipoc moody sunny rainy foggy misty snowy cloudy stormy dreamy shiny trendy messy ' + 'casual blonde blond brunette muscular athletic clever intelligent concentrated curious lonely sleepy heavy ' + 'nature outdoors outdoor indoors indoor scenery scenic autumn fall winter spring summer ' + 'physical teenage traveling ' + //
|
|
3166
|
+
*/ const DESCRIBING = words('love romance romantic luxury luxurious fancy extravagant happiness happy beauty emotion emotions mood lifestyle ' + 'concept aesthetic wallpaper background retro vintage antique old young cute sexy fun funny sad positive negative healthy fit ' + 'strong powerful homemade tasty yummy sweet sweetness nice dark bw monochrome macro sporty active married bridal ' + 'female male adult good bad poc bipoc moody sunny rainy foggy misty snowy cloudy stormy dreamy shiny trendy messy ' + 'casual blonde blond brunette muscular athletic clever intelligent concentrated curious lonely sleepy heavy ' + 'nature outdoors outdoor indoors indoor scenery scenic autumn fall winter spring summer ' + 'physical teenage traveling ' + // How a photo is laid out, never a thing it shows: "car wallpapers" is a car (AGL-3942).
|
|
3167
|
+
'wallpaper wallpapers background backgrounds backdrop backdrops texture textures ' + // Words a tag gives that are no noun at all: "family, together" is a family (AGL-3942).
|
|
3168
|
+
'together alone apart away abroad ahead nearby outside inside upstairs downstairs ' + // Adjectives a tag gives alone, never a thing: "students, multicultural" (AGL-3856).
|
|
2858
3169
|
'multicultural multiethnic multiracial diverse international cultural traditional modern classic classical ' + 'domestic wild tropical rural urban ' + // How the photo was made, never what it shows: "cutout, perspective", "men, silhouettes".
|
|
2859
3170
|
'silhouette silhouettes cutout perspective bokeh closeup ' + // A holiday names when, never a thing: "tet market" is a market.
|
|
2860
|
-
'tet christmas easter halloween diwali ramadan hanukkah thanksgiving ' + 'indian asian african american european caucasian vietnamese japanese chinese korean thai latino latina hispanic ' + 'japan vietnam viet nam thailand india china korea germany france italy spain england britain uk usa america ' + 'canada mexico brazil australia africa europe asia')
|
|
3171
|
+
'tet christmas easter halloween diwali ramadan hanukkah thanksgiving ' + 'indian asian african american european caucasian vietnamese japanese chinese korean thai latino latina hispanic ' + 'japan vietnam viet nam thailand india china korea germany france italy spain england britain uk usa america ' + 'canada mexico brazil australia africa europe asia ' + // How a scene feels or looks, never a thing in it (AGL-3988): "mountain,
|
|
3172
|
+
// snow, winter, cold, couple, color, landscape" is a couple in the snow.
|
|
3173
|
+
'cold warm hot chilly freezing frozen icy color colors colour colours landscape landscapes ' + 'panorama panoramic vista scene scenes');
|
|
3174
|
+
/**
|
|
3175
|
+
* The sky and the light over a scene, never a thing in it (AGL-3988): "A
|
|
3176
|
+
* couple with a sky at sunset" and "A child with clouds by a lake" were a
|
|
3177
|
+
* couple at sunset and a child by a lake.
|
|
3178
|
+
*/ const SCENERY = words('sky skies cloud clouds sun sunshine sunlight daylight light shadow shadows horizon');
|
|
3179
|
+
/**
|
|
3180
|
+
* The weather a scene is in, said as where (AGL-3988): "A couple with a fog
|
|
3181
|
+
* at a wedding" was a couple in the fog, "A snow in the mountains" a couple
|
|
3182
|
+
* in the snow.
|
|
3183
|
+
*/ const WEATHER = {
|
|
3184
|
+
fog: 'in the fog',
|
|
3185
|
+
mist: 'in the mist',
|
|
3186
|
+
haze: 'in the haze',
|
|
3187
|
+
rain: 'in the rain',
|
|
3188
|
+
snow: 'in the snow',
|
|
3189
|
+
snowfall: 'in the snow',
|
|
3190
|
+
snowflakes: 'in the snow',
|
|
3191
|
+
wind: 'in the wind'
|
|
3192
|
+
};
|
|
2861
3193
|
/**
|
|
2862
3194
|
* Words a tag uses for what a person or a thing is like, said before it
|
|
2863
3195
|
* rather than as a thing of its own (AGL-3856): "a confident lawyer", "an
|
|
2864
3196
|
* elderly couple", "an analog camera", never "a lawyer, law and a confident".
|
|
2865
3197
|
*/ const QUALITIES = words('confident professional successful serious smart busy creative proud skilled experienced determined focused ' + 'senior junior expert friendly cheerful smiling elderly analog analogue digital mirrorless');
|
|
2866
|
-
/** What a tag names that takes no article: "chalk" of "board, chalk". */ const MASS_NOUNS = words('food coffee tea bread wood water wax soap clay money fabric yarn wool furniture jewelry jewellery ' + 'pottery glass paper music art hair makeup chalk paint ink dust stone marble concrete steel metal ' + 'skincare equipment decor
|
|
3198
|
+
/** What a tag names that takes no article: "chalk" of "board, chalk". */ const MASS_NOUNS = words('food coffee tea bread wood water wax soap clay money fabric yarn wool furniture jewelry jewellery ' + 'pottery glass paper music art hair makeup chalk paint ink dust stone marble concrete steel metal ' + 'skincare equipment decor wildlife weather traffic wine beer chocolate rice sugar flour milk ' + 'cheese honey oil ice fire light sunlight dough sourdough pastry dessert people foliage greenery faculty staff ' + 'clothing bedding frosting icing flooring');
|
|
2867
3199
|
/** Nouns plural without an "-s": said without an article, "women in a classroom". */ const PLURAL_NOUNS = words('men women people children feet teeth mice geese sheep fish');
|
|
2868
3200
|
/**
|
|
2869
3201
|
* What a tag names that no photo shows as a thing of its own (AGL-3856): an
|
|
@@ -2871,7 +3203,8 @@ function jobPhotos(key) {
|
|
|
2871
3203
|
* doing ("read", "lift", "fitness", "a workout"), a word for the photo itself
|
|
2872
3204
|
* ("photo", "spot"). Left out, never said with an article: "A bookwork and a
|
|
2873
3205
|
* read", "A kettlebell and fitness", "A board and training" said nothing.
|
|
2874
|
-
*/ const ABSTRACT_NOUNS = words('law justice advocacy business feedback review news return communication communicate discussion dialog conversation ' + 'success career work job satisfaction quality concept idea strategy marketing education technology health support ' + 'confirmation opinion rating evaluation planning project presentation optimization information internet finance ' + 'management leadership teamwork motivation growth strength service services help advice consulting consultation ' + 'marriage photography architecture travel transport transportation industry company corporate social e-business ' + 'fitness workout workouts exercise exercises crossfit sport sports skill skills knowledge exam exams lecture ' + 'session lesson course hobby leisure power energy wellness talent formation participation ' + 'press show day days night year years time holiday month months week weeks morning evening afternoon ' + 'kiss hug embrace ' +
|
|
3206
|
+
*/ const ABSTRACT_NOUNS = words('law justice advocacy business feedback review news return communication communicate discussion dialog conversation ' + 'success career work job satisfaction quality concept idea strategy marketing education technology health support ' + 'confirmation opinion rating evaluation planning project presentation optimization information internet finance ' + 'management leadership teamwork motivation growth strength service services help advice consulting consultation ' + 'marriage photography architecture travel transport transportation industry company corporate social e-business ' + 'fitness workout workouts exercise exercises crossfit sport sports skill skills knowledge exam exams lecture ' + 'session lesson course hobby leisure power energy wellness talent formation participation ' + 'press show day days night year years time holiday month months week weeks morning evening afternoon season seasons ' + 'kiss hug embrace ' + // A feeling, never a thing anyone holds (AGL-3988): "A father with a care".
|
|
3207
|
+
'care worry trust hope joy peace fear faith grief pride comfort safety bliss delight passion desire feeling feelings ' + 'moment moments memory memories fashion style ' + 'photo photos picture pictures image images shot shots shoot shoots spot spots ' + 'read write learn study lift move remove focus relax think sit smile laugh eat swim teach enjoy celebrate explore ' + 'hike can');
|
|
2875
3208
|
/** Words ending as an idea does that are things: "a station", "a city", "a ship". */ const CONCRETE_ABSTRACT_ENDINGS = words('station mansion lotion potion ornament instrument apartment monument pavement basement garment compartment ' + 'equipment cement city university facility ship warship spaceship airship');
|
|
2876
3209
|
/** Whether a word is an idea or a doing by how it ends: "participation", "unity", "empowerment". */ const saysAnIdea = (word)=>/(?:tion|sion|ment|ness|ity|ship|ism)s?$/.test(word) && !CONCRETE_ABSTRACT_ENDINGS.has(aiStockStem(word));
|
|
2877
3210
|
/**
|
|
@@ -2881,8 +3214,20 @@ function jobPhotos(key) {
|
|
|
2881
3214
|
/** Stopwords a description still says, as the people a photo shows: "a family", "a person". */ const SAID_PEOPLE = words('people person family');
|
|
2882
3215
|
/** Words ending in "-ing" that are things, and take an article: "a wedding", "a ring". */ const COUNTED_ING = words('wedding ring earring building painting drawing ceiling string swing king sibling wing dumpling pudding sapling');
|
|
2883
3216
|
/** "-ing" words that are things, and take no article: "clothing". */ const UNCOUNTED_ING = words('clothing bedding frosting icing flooring stuffing seasoning filling');
|
|
2884
|
-
/** People a photo shows; the generic ones give way to a role ("man" to "businessman"). */ const PEOPLE_NOUNS = words('man men woman women person people human humans boy boys girl girls guy guys lady ladies child children kid kids ' + 'baby family couple bride groom schoolgirl schoolboy teen teenager student students graduate athlete athletes ' + 'businessman businesswoman businessmen lawyer attorney doctor dentist nurse chef cook baker barista ' + 'trainer coach teacher teachers instructor lecturer professor tutor worker workers entrepreneur model ' + 'photographer potter artist florist mother father parent parents grandmother grandfather grandparents ' + 'faculty staff team participants volunteer volunteers musician dancer leader manager owner founder ' + 'journalist journalists reporter reporters master masters lovers newlywed newlyweds husband wife fiance fiancee spouse')
|
|
2885
|
-
|
|
3217
|
+
/** People a photo shows; the generic ones give way to a role ("man" to "businessman"). */ const PEOPLE_NOUNS = words('man men woman women person people human humans boy boys girl girls guy guys lady ladies child children kid kids ' + 'baby family couple bride groom schoolgirl schoolboy teen teenager student students graduate athlete athletes ' + 'businessman businesswoman businessmen lawyer attorney doctor dentist nurse chef cook baker barista ' + 'trainer coach teacher teachers instructor lecturer professor tutor worker workers entrepreneur model ' + 'photographer potter artist florist mother father parent parents grandmother grandfather grandparents ' + 'faculty staff team participants volunteer volunteers musician dancer leader manager owner founder ' + 'journalist journalists reporter reporters master masters lovers newlywed newlyweds husband wife fiance fiancee spouse ' + // Whoever else is about (AGL-3988): "A family with tourists" was a family.
|
|
3218
|
+
'tourist tourists traveler travelers traveller travellers hiker hikers visitor visitors friend friends crowd ' + // A family's people, said as a parent with a child (AGL-3988).
|
|
3219
|
+
'dad dads mom moms mum mums son sons daughter daughters toddler toddlers');
|
|
3220
|
+
/** People said by no role: a model is whoever posed (AGL-3856), "a woman" of "woman, model, show, teacher". */ const GENERIC_PEOPLE = words('man men woman women person people human humans guy guys lady ladies adult boy boys girl girls model models ' + 'tourist tourists traveler travelers traveller travellers hiker hikers visitor visitors friend friends crowd');
|
|
3221
|
+
/** A parent a photo shows, said with the child beside them: "A father with a girl" (AGL-3988). */ const PARENTS = words('father mother dad mom mum parent parents grandfather grandmother grandparent grandparents');
|
|
3222
|
+
/** A child a photo shows beside a parent (AGL-3988). */ const CHILDREN = words('child children kid kids baby babies toddler toddlers girl girls boy boys son sons daughter daughters');
|
|
3223
|
+
/** How a family's word is said: "a dad" is a father (AGL-3988). */ const SAID_AS = {
|
|
3224
|
+
dad: 'father',
|
|
3225
|
+
dads: 'fathers',
|
|
3226
|
+
mom: 'mother',
|
|
3227
|
+
moms: 'mothers',
|
|
3228
|
+
mum: 'mother',
|
|
3229
|
+
mums: 'mothers'
|
|
3230
|
+
};
|
|
2886
3231
|
/**
|
|
2887
3232
|
* A body's parts, never a thing a photo is described by (AGL-3856): "A girl
|
|
2888
3233
|
* with a hand" said nothing, and "A body in a gym" is a gym.
|
|
@@ -2952,13 +3297,46 @@ function jobPhotos(key) {
|
|
|
2952
3297
|
cliff: 'on',
|
|
2953
3298
|
river: 'by',
|
|
2954
3299
|
lake: 'by',
|
|
3300
|
+
lakeside: 'by',
|
|
3301
|
+
lakeshore: 'by',
|
|
3302
|
+
sea: 'by',
|
|
3303
|
+
ocean: 'by',
|
|
3304
|
+
seaside: 'by',
|
|
3305
|
+
coast: 'on',
|
|
3306
|
+
shore: 'on',
|
|
3307
|
+
sundown: 'at',
|
|
2955
3308
|
waterfall: 'at'
|
|
2956
3309
|
};
|
|
2957
3310
|
/** Places that are things too, a photo's subject where nothing else is: "a desk in a classroom". */ const OBJECT_PLACES = words('desk table counter bridge bed sofa couch bench');
|
|
2958
|
-
/** Places said without an article: "in court", "at sunset". */ const BARE_PLACES = words('court sunset sunrise dusk dawn');
|
|
3311
|
+
/** Places said without an article: "in court", "at sunset". */ const BARE_PLACES = words('court sunset sunrise sundown dusk dawn');
|
|
2959
3312
|
/** Places said in words of their own: a mountain tag is "in the mountains". */ const PLACES_SAID = {
|
|
2960
|
-
mountain: 'the mountains'
|
|
3313
|
+
mountain: 'the mountains',
|
|
3314
|
+
lakeside: 'the lake',
|
|
3315
|
+
lakeshore: 'the lake',
|
|
3316
|
+
sea: 'the sea',
|
|
3317
|
+
ocean: 'the ocean',
|
|
3318
|
+
seaside: 'the sea',
|
|
3319
|
+
coast: 'the coast',
|
|
3320
|
+
shore: 'the shore'
|
|
2961
3321
|
};
|
|
3322
|
+
/** Places that say when, said after where: "a couple in the mountains at sunset" (AGL-3988). */ const TIME_PLACES = words('sunset sunrise sundown dusk dawn');
|
|
3323
|
+
/** Places out of doors, said after a thing to sit on: "a couple on a bench by the lake" (AGL-3988). */ const OUTDOORS = words('forest field meadow valley mountain hill cliff river lake lakeside lakeshore waterfall beach park garden trail sea ocean seaside coast shore');
|
|
3324
|
+
/** Words inside a tag that say one thing is where another is: "couple on bench" (AGL-3988). */ const TAG_PREPOSITIONS = words('on in at by with under near beside');
|
|
3325
|
+
/**
|
|
3326
|
+
* A tag that is a phrase of its own, read as its parts (AGL-3988): "couple
|
|
3327
|
+
* on bench" is a couple, and a bench they are on. The beta.270 Sugar Hollow
|
|
3328
|
+
* About page read it whole, as a place, and said "A lakeside on a couple on
|
|
3329
|
+
* bench".
|
|
3330
|
+
*/ function tagParts(tag) {
|
|
3331
|
+
const list = tag.toLowerCase().trim().split(/\s+/);
|
|
3332
|
+
const at = list.findIndex((word, index)=>index > 0 && index < list.length - 1 && TAG_PREPOSITIONS.has(word));
|
|
3333
|
+
return at > 0 ? [
|
|
3334
|
+
list.slice(0, at).join(' '),
|
|
3335
|
+
list.slice(at + 1).join(' ')
|
|
3336
|
+
] : [
|
|
3337
|
+
tag
|
|
3338
|
+
];
|
|
3339
|
+
}
|
|
2962
3340
|
/** How many of a photo's first tags its description reads: the things and people it is OF. */ const ALT_TAGS_READ = 8;
|
|
2963
3341
|
/** How far a photo's tags are read for where it is set, said last: "in a gym" of a kettlebell's seventh tag. */ const ALT_PLACE_TAGS_READ = 10;
|
|
2964
3342
|
/** A tag's words, a word for the photo itself taken off a compound: "photo-camera" is a camera. */ function tagWords(tag) {
|
|
@@ -2983,6 +3361,8 @@ function jobPhotos(key) {
|
|
|
2983
3361
|
if (/^(?:out|up|off|down|away|on|in)$/.test(list[list.length - 1])) return null;
|
|
2984
3362
|
if (list.some((word)=>BRANDS.has(word))) return null;
|
|
2985
3363
|
if (list.every((word)=>proper.has(word))) return list.map((word)=>`${word.charAt(0).toUpperCase()}${word.slice(1)}`).join(' ');
|
|
3364
|
+
// Two people named side by side are both shown: "bride groom" is a bride and groom (AGL-3942).
|
|
3365
|
+
if (list.length === 2 && list.every((word)=>PEOPLE_NOUNS.has(word)) && list[0] !== list[1]) return `${articleFor(list[0])} ${list[0]} and ${list[1]}`;
|
|
2986
3366
|
const last = list[list.length - 1];
|
|
2987
3367
|
// An idea or a doing, never a thing: "law", "feedback", "customer satisfaction", "participation", "weightlifting".
|
|
2988
3368
|
if (ABSTRACT_NOUNS.has(last) || ABSTRACT_NOUNS.has(aiStockStem(last)) || saysAnIdea(last)) return null;
|
|
@@ -2990,10 +3370,18 @@ function jobPhotos(key) {
|
|
|
2990
3370
|
if (doing) return null;
|
|
2991
3371
|
const phrase = list.join(' ');
|
|
2992
3372
|
const plural = PLURAL_NOUNS.has(last) || aiStockStem(last) !== last && !/^(?:lens|canvas|atlas|gas|bus)$/.test(last);
|
|
2993
|
-
if (plural || MASS_NOUNS.has(last) || STOPWORDS.has(list[0]) && !SAID_PEOPLE.has(list[0])) return phrase;
|
|
2994
|
-
return `${articleFor(phrase)} ${phrase}`;
|
|
3373
|
+
if (plural || MASS_NOUNS.has(last) || STOPWORDS.has(list[0]) && !SAID_PEOPLE.has(list[0])) return spelled(phrase);
|
|
3374
|
+
return `${articleFor(phrase)} ${spelled(phrase)}`;
|
|
2995
3375
|
}
|
|
2996
|
-
/**
|
|
3376
|
+
/** Letters said one by one, written in capitals: "an SLR camera", "a DSLR" (AGL-3942). */ const INITIALISMS = words('slr dslr tv dj diy bbq suv atv uv vr');
|
|
3377
|
+
/** A phrase as a description writes it, its initialisms in capitals. */ const spelled = (phrase)=>phrase.split(' ').map((word)=>INITIALISMS.has(word) ? word.toUpperCase() : word).join(' ');
|
|
3378
|
+
/** "a" or "an" before a phrase, an initialism by how its first letter is said: "an SLR", "a DSLR". */ const articleFor = (phrase)=>{
|
|
3379
|
+
var _phrase_split_;
|
|
3380
|
+
const first = (_phrase_split_ = phrase.split(' ')[0]) != null ? _phrase_split_ : '';
|
|
3381
|
+
if (INITIALISMS.has(first)) return /^[aefhilmnorsx]/.test(first) ? 'an' : 'a';
|
|
3382
|
+
return /^(?:[aeio]|u(?!ni|s[eu]))/.test(phrase) ? 'an' : 'a';
|
|
3383
|
+
};
|
|
3384
|
+
/** Words a description never ends on: an article, a preposition, a conjunction. */ const DANGLING_END = /(?:\s+(?:a|an|the|and|or|with|in|on|at|by|of|for|to|from|into|onto))+$/i;
|
|
2997
3385
|
/** Whether two words name one thing, one inside the other: "law" and "lawyer", "cam" and "camera". */ function nearSynonyms(a, b) {
|
|
2998
3386
|
const [short, long] = a.length <= b.length ? [
|
|
2999
3387
|
a,
|
|
@@ -3023,15 +3411,31 @@ function jobPhotos(key) {
|
|
|
3023
3411
|
* - a second thing comes only from the first two tags and where no place is
|
|
3024
3412
|
* said, what a person holds only from the first three, where it is set
|
|
3025
3413
|
* from the first ten;
|
|
3026
|
-
* - no word is said twice: never "an elderly couple and an elderly"
|
|
3414
|
+
* - no word is said twice: never "an elderly couple and an elderly";
|
|
3415
|
+
* - the sky, the clouds and the light are no thing anyone holds, and the
|
|
3416
|
+
* weather is said as where it is: "a couple in the fog at a wedding",
|
|
3417
|
+
* "a couple in the snow in the mountains", never "a couple with a sky at
|
|
3418
|
+
* sunset" or "a snow in the mountains"; a feeling ("care", "worry") is no
|
|
3419
|
+
* thing either; whoever else is about ("tourists") is never said beside a
|
|
3420
|
+
* family; a parent beside a child is said with them ("a father with a
|
|
3421
|
+
* girl"); a tag that is a phrase of its own ("couple on bench") is read as
|
|
3422
|
+
* its parts; a time of day comes after where ("in the mountains at
|
|
3423
|
+
* sunset"), and a bench out of doors says where it stands ("on a bench by
|
|
3424
|
+
* the lake") (AGL-3988).
|
|
3027
3425
|
*
|
|
3028
3426
|
* `null` where no tag names a thing.
|
|
3029
3427
|
*/ export function aiStockTagsAlt(tags, proper = new Set()) {
|
|
3428
|
+
var _ref;
|
|
3030
3429
|
const parts = [];
|
|
3031
3430
|
let quality = '';
|
|
3032
3431
|
let portrait = false;
|
|
3033
|
-
|
|
3034
|
-
|
|
3432
|
+
/** The weather it is in, said as where ({@link WEATHER}). */ let weather = '';
|
|
3433
|
+
const read = tags.slice(0, ALT_PLACE_TAGS_READ).flatMap((tag, index)=>tagParts(tag).map((part)=>({
|
|
3434
|
+
tag: part,
|
|
3435
|
+
index
|
|
3436
|
+
})));
|
|
3437
|
+
for (const { tag, index } of read){
|
|
3438
|
+
var _ref1;
|
|
3035
3439
|
var _bare_split_pop;
|
|
3036
3440
|
const lower = tag.toLowerCase().trim();
|
|
3037
3441
|
const reading = index < ALT_TAGS_READ;
|
|
@@ -3043,11 +3447,18 @@ function jobPhotos(key) {
|
|
|
3043
3447
|
if (reading) quality || (quality = lower);
|
|
3044
3448
|
continue;
|
|
3045
3449
|
}
|
|
3046
|
-
|
|
3450
|
+
// The sky is never a thing a photo is described by; the weather is where it is.
|
|
3451
|
+
if (SCENERY.has(lower)) continue;
|
|
3452
|
+
if (WEATHER[lower]) {
|
|
3453
|
+
if (reading) weather || (weather = WEATHER[lower]);
|
|
3454
|
+
continue;
|
|
3455
|
+
}
|
|
3456
|
+
const family = SAID_AS[lower];
|
|
3457
|
+
const said = family ? `${articleFor(family)} ${family}`.replace(/^an? (?=\S+s$)/, '') : describedTag(tag, proper);
|
|
3047
3458
|
if (!said) continue;
|
|
3048
3459
|
const bare = said.replace(/^an?\s+/, '');
|
|
3049
3460
|
const stems = stemList(bare);
|
|
3050
|
-
const head = (
|
|
3461
|
+
const head = (_ref1 = (_bare_split_pop = bare.split(/\s+/).pop()) == null ? void 0 : _bare_split_pop.toLowerCase()) != null ? _ref1 : '';
|
|
3051
3462
|
if (!head) continue;
|
|
3052
3463
|
const headStem = aiStockStem(head);
|
|
3053
3464
|
const kind = PEOPLE_NOUNS.has(head) || PEOPLE_NOUNS.has(headStem) ? 'person' : PLACES[headStem] ? 'place' : 'thing';
|
|
@@ -3091,7 +3502,12 @@ function jobPhotos(key) {
|
|
|
3091
3502
|
// silhouettes, camera, nature, photographer" men with a camera.
|
|
3092
3503
|
const leads = (part)=>portrait || part.index < ALT_PERSON_TAGS_READ || !things.length;
|
|
3093
3504
|
const role = posed ? undefined : people.find((part)=>!GENERIC_PEOPLE.has(part.head) && part.index < ALT_ROLE_TAGS_READ && leads(part));
|
|
3094
|
-
|
|
3505
|
+
// A parent beside a child is said with them (AGL-3988): "A father with a
|
|
3506
|
+
// girl", never "a child with clouds" of "child, clouds, dad, dock, father".
|
|
3507
|
+
const parent = people.find((part)=>PARENTS.has(part.head) && part.index < ALT_ROLE_TAGS_READ);
|
|
3508
|
+
const child = people.find((part)=>CHILDREN.has(part.head) && part.index < ALT_ROLE_TAGS_READ);
|
|
3509
|
+
const family = parent && child && (!role || role === parent || role === child) ? parent : undefined;
|
|
3510
|
+
const person = (_ref = family != null ? family : role) != null ? _ref : people.find(leads);
|
|
3095
3511
|
// Nothing but places: a desk is the thing in a classroom; "a school in a classroom" says one place.
|
|
3096
3512
|
if (!person && !things.length && places.length > 1) {
|
|
3097
3513
|
const object = places.find((part)=>OBJECT_PLACES.has(part.head));
|
|
@@ -3103,7 +3519,7 @@ function jobPhotos(key) {
|
|
|
3103
3519
|
} else places = places.slice(0, 1);
|
|
3104
3520
|
}
|
|
3105
3521
|
const place = places[0];
|
|
3106
|
-
if (!person && !things.length && !place) return null;
|
|
3522
|
+
if (!person && !things.length && !place && !weather) return null;
|
|
3107
3523
|
/** Every word said so far, so none is said twice. */ const said = new Set();
|
|
3108
3524
|
const fresh = (part)=>{
|
|
3109
3525
|
const list = stemList(part.said.replace(/^an?\s+/, ''));
|
|
@@ -3115,20 +3531,44 @@ function jobPhotos(key) {
|
|
|
3115
3531
|
let phrase = '';
|
|
3116
3532
|
if (person && fresh(person)) {
|
|
3117
3533
|
phrase = portrait ? `a portrait of ${person.said}` : qualified(person);
|
|
3118
|
-
const held = things.find((part)=>part.index <= 2);
|
|
3534
|
+
const held = family && child && child !== person ? child : things.find((part)=>part.index <= 2);
|
|
3119
3535
|
if (!portrait && held && fresh(held)) phrase += ` ${CLOTHING.has(held.head) ? 'in' : 'with'} ${held.said}`;
|
|
3120
3536
|
} else if (things[0] && fresh(things[0])) {
|
|
3121
3537
|
phrase = qualified(things[0]);
|
|
3122
3538
|
const second = things[1];
|
|
3123
3539
|
if (second && second.index <= 1 && !place && fresh(second)) phrase += ` and ${second.said}`;
|
|
3124
3540
|
}
|
|
3541
|
+
/** A place as it is said alone: "a classroom", "the mountains", "sunset". */ const placeOf = (part)=>{
|
|
3542
|
+
var _PLACES_SAID_part_head;
|
|
3543
|
+
return (_PLACES_SAID_part_head = PLACES_SAID[part.head]) != null ? _PLACES_SAID_part_head : BARE_PLACES.has(part.head) && /^an? \S+$/.test(part.said) ? part.head : part.said;
|
|
3544
|
+
};
|
|
3545
|
+
/** A place as it is said after what is there: "in the mountains", "at sunset", "on a bench". */ const whereOf = (part)=>{
|
|
3546
|
+
var _PLACES_part_head;
|
|
3547
|
+
return `${(_PLACES_part_head = PLACES[part.head]) != null ? _PLACES_part_head : 'in'} ${placeOf(part)}`;
|
|
3548
|
+
};
|
|
3549
|
+
// The weather is said before where (AGL-3988): "a couple in the fog at a
|
|
3550
|
+
// wedding"; alone, it is what the photo shows: "snow in the mountains".
|
|
3551
|
+
if (weather && phrase) phrase += ` ${weather}`;
|
|
3552
|
+
else if (weather) phrase = weather.replace(/^in the /, '');
|
|
3125
3553
|
if (place && fresh(place)) {
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3554
|
+
// A second place where the first is a time of day or a bench out of
|
|
3555
|
+
// doors: "a couple in the mountains at sunset", "a couple on a bench by
|
|
3556
|
+
// the lake"; never a bed in a room.
|
|
3557
|
+
const second = places.find((part)=>part !== place && !OBJECT_PLACES.has(part.head) && !TIME_PLACES.has(part.head) && (TIME_PLACES.has(place.head) || place.head === 'bench' && OUTDOORS.has(part.head)));
|
|
3558
|
+
const after = second && fresh(second) ? second : null;
|
|
3559
|
+
const [first, last] = after && TIME_PLACES.has(place.head) ? [
|
|
3560
|
+
after,
|
|
3561
|
+
place
|
|
3562
|
+
] : [
|
|
3563
|
+
place,
|
|
3564
|
+
after
|
|
3565
|
+
];
|
|
3566
|
+
const tail = last ? ` ${whereOf(last)}` : '';
|
|
3567
|
+
phrase = phrase ? `${phrase} ${whereOf(first)}${tail}` : `${placeOf(first)}${tail}`;
|
|
3130
3568
|
}
|
|
3131
|
-
|
|
3569
|
+
// Never a dangling article or preposition, whatever a tag left behind.
|
|
3570
|
+
phrase = phrase.replace(DANGLING_END, '').trim();
|
|
3571
|
+
if (!phrase || /^(?:a|an|the)$/i.test(phrase)) return null;
|
|
3132
3572
|
const out = `${phrase.charAt(0).toUpperCase()}${phrase.slice(1)}`;
|
|
3133
3573
|
return out.length > AI_STOCK_ALT_MAX ? out.slice(0, AI_STOCK_ALT_MAX).replace(/[\s,]+\S*$/, '') : out;
|
|
3134
3574
|
}
|
|
@@ -3260,13 +3700,18 @@ const EXTENSIONS = {
|
|
|
3260
3700
|
* post — so no slot searches by words another slot is held against. A site for
|
|
3261
3701
|
* adults alone ({@link aiStockAdultsOnly}) is told so, whatever its world.
|
|
3262
3702
|
*/ export function aiStockSourceTerms(input) {
|
|
3263
|
-
var _input_audience;
|
|
3703
|
+
var _input_audience, _input_audience1;
|
|
3264
3704
|
const terms = sourceWorldTerms(input);
|
|
3265
3705
|
// Where the site's own words set it: a photographer "in the Blue Ridge" for "mountain weddings" (AGL-3856).
|
|
3266
3706
|
const setting = aiStockSetting([
|
|
3267
3707
|
input.business,
|
|
3268
3708
|
(_input_audience = input.audience) != null ? _input_audience : ''
|
|
3269
3709
|
].join(' . '));
|
|
3710
|
+
// A craft whose pictures are people at a moment shows the moments its site names (AGL-3942).
|
|
3711
|
+
const work = terms.scenes ? aiStockWorkScenes([
|
|
3712
|
+
input.business,
|
|
3713
|
+
(_input_audience1 = input.audience) != null ? _input_audience1 : ''
|
|
3714
|
+
].join(' . '), setting) : [];
|
|
3270
3715
|
return _extends({}, terms, aiStockAdultsOnly([
|
|
3271
3716
|
input.audience,
|
|
3272
3717
|
input.name,
|
|
@@ -3275,6 +3720,8 @@ const EXTENSIONS = {
|
|
|
3275
3720
|
adults: true
|
|
3276
3721
|
} : {}, setting ? {
|
|
3277
3722
|
setting
|
|
3723
|
+
} : {}, work.length ? {
|
|
3724
|
+
work
|
|
3278
3725
|
} : {});
|
|
3279
3726
|
}
|
|
3280
3727
|
/** What a source's photos are searched by: its world, as {@link aiStockSourceTerms} reads it. */ function sourceWorldTerms(input) {
|
|
@@ -4484,6 +4931,7 @@ const WORKSPACE = {
|
|
|
4484
4931
|
delete request.allow;
|
|
4485
4932
|
delete request.refuseLead;
|
|
4486
4933
|
delete request.worldless;
|
|
4934
|
+
delete request.away;
|
|
4487
4935
|
const key = JSON.stringify([
|
|
4488
4936
|
request.query,
|
|
4489
4937
|
request.orientation,
|
|
@@ -4653,7 +5101,7 @@ const WORKSPACE = {
|
|
|
4653
5101
|
* (AGL-3923). What lets a sensitive topic in is always the site's own words.
|
|
4654
5102
|
*/ const judgementOf = (slot, request, subject, world)=>{
|
|
4655
5103
|
var _request_subject, _request_shun;
|
|
4656
|
-
var _request_allow, _request_shun1, _request_leadAny, _request_refuse, _request_needs, _request_refuseLead;
|
|
5104
|
+
var _request_allow, _request_shun1, _request_leadAny, _request_refuse, _request_needs, _request_refuseLead, _request_away;
|
|
4657
5105
|
return _extends({
|
|
4658
5106
|
subject: (_request_subject = request.subject) != null ? _request_subject : request.broad ? '' : subject,
|
|
4659
5107
|
domain: world.domain,
|
|
@@ -4698,6 +5146,8 @@ const WORKSPACE = {
|
|
|
4698
5146
|
needs: request.needs
|
|
4699
5147
|
} : {}, ((_request_refuseLead = request.refuseLead) == null ? void 0 : _request_refuseLead.length) ? {
|
|
4700
5148
|
refuseLead: request.refuseLead
|
|
5149
|
+
} : {}, ((_request_away = request.away) == null ? void 0 : _request_away.length) ? {
|
|
5150
|
+
away: request.away
|
|
4701
5151
|
} : {}, request.worldless ? {
|
|
4702
5152
|
domain: [],
|
|
4703
5153
|
rivals: []
|
|
@@ -4708,8 +5158,9 @@ const WORKSPACE = {
|
|
|
4708
5158
|
* filled from (AGL-3660): its broad searches, any hit naming the craft
|
|
4709
5159
|
* itself. Never a desk, a laptop or a living room for a soap shop.
|
|
4710
5160
|
*/ const craftSearches = (slot, world = terms)=>{
|
|
4711
|
-
// A portfolio's record of the work is never filled by the craft's own
|
|
4712
|
-
|
|
5161
|
+
// A portfolio's record of the work is never filled by the craft's own
|
|
5162
|
+
// photos (AGL-3856), nor is any picture of a site that shows its work (AGL-3942).
|
|
5163
|
+
if (!world.core.length || aiStockShowsTheWork(slot, world) || aiStockShowsItsWork(slot, world)) return [];
|
|
4713
5164
|
const orientation = aiStockOrientation(slot.aspect);
|
|
4714
5165
|
const size = slot.role === 'hero' ? {
|
|
4715
5166
|
minWidth: 1600
|