vidspotai-shared 1.0.82-dev.0 → 1.0.83
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/globals/aiModels/enums.d.ts +11 -1
- package/lib/globals/aiModels/enums.d.ts.map +1 -1
- package/lib/globals/aiModels/enums.js +24 -1
- package/lib/globals/aiModels/index.d.ts.map +1 -1
- package/lib/globals/aiModels/index.js +2 -0
- package/lib/globals/aiModels/providers/anthropic.d.ts +12 -0
- package/lib/globals/aiModels/providers/anthropic.d.ts.map +1 -0
- package/lib/globals/aiModels/providers/anthropic.js +88 -0
- package/lib/globals/aiModels/providers/google.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/google.js +115 -10
- package/lib/globals/aiModels/providers/openai.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/openai.js +63 -4
- package/lib/globals/aiModels/tierHelpers.d.ts +12 -0
- package/lib/globals/aiModels/tierHelpers.d.ts.map +1 -1
- package/lib/globals/aiModels/tierHelpers.js +83 -0
- package/lib/globals/aiModels/types.d.ts +19 -0
- package/lib/globals/aiModels/types.d.ts.map +1 -1
- package/lib/globals/types.d.ts +120 -1
- package/lib/globals/types.d.ts.map +1 -1
- package/lib/globals/types.js +135 -1
- package/lib/models/agent.model.d.ts +41 -1
- package/lib/models/agent.model.d.ts.map +1 -1
- package/lib/models/index.d.ts +1 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +1 -0
- package/lib/models/social.model.d.ts +180 -0
- package/lib/models/social.model.d.ts.map +1 -0
- package/lib/models/social.model.js +2 -0
- package/lib/models/user.model.d.ts +10 -0
- package/lib/models/user.model.d.ts.map +1 -1
- package/lib/models/video.model.d.ts +6 -0
- package/lib/models/video.model.d.ts.map +1 -1
- package/lib/schemas/brief.schema.d.ts +46 -0
- package/lib/schemas/brief.schema.d.ts.map +1 -1
- package/lib/schemas/brief.schema.js +72 -1
- package/lib/schemas/index.d.ts +1 -0
- package/lib/schemas/index.d.ts.map +1 -1
- package/lib/schemas/index.js +1 -0
- package/lib/schemas/project.schema.d.ts +70 -3
- package/lib/schemas/project.schema.d.ts.map +1 -1
- package/lib/schemas/project.schema.js +12 -0
- package/lib/schemas/social.schema.d.ts +91 -0
- package/lib/schemas/social.schema.d.ts.map +1 -0
- package/lib/schemas/social.schema.js +114 -0
- package/lib/schemas/videoPlan.schema.d.ts +117 -3
- package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
- package/lib/schemas/videoPlan.schema.js +141 -1
- package/lib/services/agent/chatAgent.d.ts +25 -1
- package/lib/services/agent/chatAgent.d.ts.map +1 -1
- package/lib/services/agent/chatAgent.js +145 -9
- package/lib/services/agent/costPreflight.d.ts +11 -1
- package/lib/services/agent/costPreflight.d.ts.map +1 -1
- package/lib/services/agent/costPreflight.js +18 -1
- package/lib/services/agent/covers/coverPlanner.d.ts +41 -0
- package/lib/services/agent/covers/coverPlanner.d.ts.map +1 -0
- package/lib/services/agent/covers/coverPlanner.js +278 -0
- package/lib/services/agent/covers/covers.schema.d.ts +158 -0
- package/lib/services/agent/covers/covers.schema.d.ts.map +1 -0
- package/lib/services/agent/covers/covers.schema.js +166 -0
- package/lib/services/agent/covers/index.d.ts +3 -0
- package/lib/services/agent/covers/index.d.ts.map +1 -0
- package/lib/services/agent/covers/index.js +18 -0
- package/lib/services/agent/critic.d.ts +10 -0
- package/lib/services/agent/critic.d.ts.map +1 -1
- package/lib/services/agent/critic.js +37 -1
- package/lib/services/agent/editClassifier.d.ts +4 -4
- package/lib/services/agent/editClassifier.js +2 -2
- package/lib/services/agent/editExisting/editAssembler.d.ts +78 -0
- package/lib/services/agent/editExisting/editAssembler.d.ts.map +1 -0
- package/lib/services/agent/editExisting/editAssembler.js +172 -0
- package/lib/services/agent/editExisting/editExisting.schema.d.ts +119 -0
- package/lib/services/agent/editExisting/editExisting.schema.d.ts.map +1 -0
- package/lib/services/agent/editExisting/editExisting.schema.js +157 -0
- package/lib/services/agent/editExisting/highlightPicker.d.ts +48 -0
- package/lib/services/agent/editExisting/highlightPicker.d.ts.map +1 -0
- package/lib/services/agent/editExisting/highlightPicker.js +199 -0
- package/lib/services/agent/editExisting/index.d.ts +4 -0
- package/lib/services/agent/editExisting/index.d.ts.map +1 -0
- package/lib/services/agent/editExisting/index.js +19 -0
- package/lib/services/agent/eval/recorder.d.ts +13 -1
- package/lib/services/agent/eval/recorder.d.ts.map +1 -1
- package/lib/services/agent/eval/recorder.js +59 -0
- package/lib/services/agent/eval/seedBriefs.d.ts +4 -3
- package/lib/services/agent/eval/seedBriefs.d.ts.map +1 -1
- package/lib/services/agent/eval/seedBriefs.js +283 -3
- package/lib/services/agent/eval/types.d.ts +10 -0
- package/lib/services/agent/eval/types.d.ts.map +1 -1
- package/lib/services/agent/executor/core.d.ts +70 -0
- package/lib/services/agent/executor/core.d.ts.map +1 -0
- package/lib/services/agent/executor/core.js +250 -0
- package/lib/services/agent/executor/duration.d.ts +20 -0
- package/lib/services/agent/executor/duration.d.ts.map +1 -0
- package/lib/services/agent/executor/duration.js +46 -0
- package/lib/services/agent/executor/index.d.ts +15 -0
- package/lib/services/agent/executor/index.d.ts.map +1 -0
- package/lib/services/agent/executor/index.js +32 -0
- package/lib/services/agent/executor/types.d.ts +183 -0
- package/lib/services/agent/executor/types.d.ts.map +1 -0
- package/lib/services/agent/executor/types.js +29 -0
- package/lib/services/agent/executor/visual.d.ts +32 -0
- package/lib/services/agent/executor/visual.d.ts.map +1 -0
- package/lib/services/agent/executor/visual.js +400 -0
- package/lib/services/agent/executor/voice.d.ts +17 -0
- package/lib/services/agent/executor/voice.d.ts.map +1 -0
- package/lib/services/agent/executor/voice.js +119 -0
- package/lib/services/agent/extendChain.d.ts +101 -0
- package/lib/services/agent/extendChain.d.ts.map +1 -0
- package/lib/services/agent/extendChain.js +177 -0
- package/lib/services/agent/index.d.ts +11 -1
- package/lib/services/agent/index.d.ts.map +1 -1
- package/lib/services/agent/index.js +11 -1
- package/lib/services/agent/llmCaller.d.ts +7 -8
- package/lib/services/agent/llmCaller.d.ts.map +1 -1
- package/lib/services/agent/llmCallerAnthropic.d.ts +44 -31
- package/lib/services/agent/llmCallerAnthropic.d.ts.map +1 -1
- package/lib/services/agent/llmCallerAnthropic.js +135 -60
- package/lib/services/agent/llmCallerFactory.d.ts +34 -0
- package/lib/services/agent/llmCallerFactory.d.ts.map +1 -0
- package/lib/services/agent/llmCallerFactory.js +31 -0
- package/lib/services/agent/llmCallerGemini.d.ts +62 -0
- package/lib/services/agent/llmCallerGemini.d.ts.map +1 -0
- package/lib/services/agent/llmCallerGemini.js +235 -0
- package/lib/services/agent/llmCallerOpenai.d.ts +56 -0
- package/lib/services/agent/llmCallerOpenai.d.ts.map +1 -0
- package/lib/services/agent/llmCallerOpenai.js +230 -0
- package/lib/services/agent/llmCallerRegistry.d.ts.map +1 -1
- package/lib/services/agent/llmCallerRegistry.js +7 -7
- package/lib/services/agent/llmCallerRouting.d.ts +63 -0
- package/lib/services/agent/llmCallerRouting.d.ts.map +1 -0
- package/lib/services/agent/llmCallerRouting.js +124 -0
- package/lib/services/agent/llmModelRegistry.d.ts +59 -0
- package/lib/services/agent/llmModelRegistry.d.ts.map +1 -0
- package/lib/services/agent/llmModelRegistry.js +168 -0
- package/lib/services/agent/llmRetry.d.ts +57 -0
- package/lib/services/agent/llmRetry.d.ts.map +1 -0
- package/lib/services/agent/llmRetry.js +102 -0
- package/lib/services/agent/modelRouter.d.ts +3 -3
- package/lib/services/agent/modelRouter.d.ts.map +1 -1
- package/lib/services/agent/modelRouter.js +27 -13
- package/lib/services/agent/planMutations.d.ts +54 -1
- package/lib/services/agent/planMutations.d.ts.map +1 -1
- package/lib/services/agent/planMutations.js +78 -0
- package/lib/services/agent/planner/Planner.d.ts +0 -17
- package/lib/services/agent/planner/Planner.d.ts.map +1 -1
- package/lib/services/agent/planner/Planner.js +67 -303
- package/lib/services/agent/planner/overlayRegen.d.ts +38 -0
- package/lib/services/agent/planner/overlayRegen.d.ts.map +1 -0
- package/lib/services/agent/planner/overlayRegen.js +145 -0
- package/lib/services/agent/planner/plannerMessages.d.ts +34 -0
- package/lib/services/agent/planner/plannerMessages.d.ts.map +1 -0
- package/lib/services/agent/planner/plannerMessages.js +185 -0
- package/lib/services/agent/planner/promptSections.d.ts +12 -0
- package/lib/services/agent/planner/promptSections.d.ts.map +1 -1
- package/lib/services/agent/planner/promptSections.js +57 -0
- package/lib/services/agent/planner/scriptFirstPlanner.d.ts +35 -0
- package/lib/services/agent/planner/scriptFirstPlanner.d.ts.map +1 -0
- package/lib/services/agent/planner/scriptFirstPlanner.js +140 -0
- package/lib/services/agent/planner/structuralRules.d.ts +10 -0
- package/lib/services/agent/planner/structuralRules.d.ts.map +1 -1
- package/lib/services/agent/planner/structuralRules.js +92 -9
- package/lib/services/agent/planner/validators.d.ts +18 -0
- package/lib/services/agent/planner/validators.d.ts.map +1 -1
- package/lib/services/agent/planner/validators.js +97 -0
- package/lib/services/agent/planner.d.ts +2 -1
- package/lib/services/agent/planner.d.ts.map +1 -1
- package/lib/services/agent/planner.js +5 -1
- package/lib/services/agent/priorProject.d.ts +26 -0
- package/lib/services/agent/priorProject.d.ts.map +1 -0
- package/lib/services/agent/priorProject.js +51 -0
- package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
- package/lib/services/agent/providerFallback/chains.js +27 -15
- package/lib/services/agent/repurpose/index.d.ts +3 -0
- package/lib/services/agent/repurpose/index.d.ts.map +1 -0
- package/lib/services/agent/repurpose/index.js +18 -0
- package/lib/services/agent/repurpose/repurpose.schema.d.ts +132 -0
- package/lib/services/agent/repurpose/repurpose.schema.d.ts.map +1 -0
- package/lib/services/agent/repurpose/repurpose.schema.js +144 -0
- package/lib/services/agent/repurpose/shortsPicker.d.ts +25 -0
- package/lib/services/agent/repurpose/shortsPicker.d.ts.map +1 -0
- package/lib/services/agent/repurpose/shortsPicker.js +218 -0
- package/lib/services/agent/runHelpers.d.ts +21 -2
- package/lib/services/agent/runHelpers.d.ts.map +1 -1
- package/lib/services/agent/runHelpers.js +71 -2
- package/lib/services/agent/tools/animateImage.tool.d.ts +1 -0
- package/lib/services/agent/tools/animateImage.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/animateImage.tool.js +12 -0
- package/lib/services/agent/tools/chapterOutline.tool.d.ts +42 -0
- package/lib/services/agent/tools/chapterOutline.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/chapterOutline.tool.js +115 -0
- package/lib/services/agent/tools/composeScene.tool.d.ts +65 -2
- package/lib/services/agent/tools/composeScene.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/estimateCost.tool.d.ts +28 -1
- package/lib/services/agent/tools/estimateCost.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/estimateCost.tool.js +55 -7
- package/lib/services/agent/tools/extendVideo.tool.d.ts +26 -0
- package/lib/services/agent/tools/extendVideo.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/extendVideo.tool.js +149 -0
- package/lib/services/agent/tools/generateScript.tool.d.ts +184 -0
- package/lib/services/agent/tools/generateScript.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/generateScript.tool.js +123 -0
- package/lib/services/agent/tools/generateVideo.tool.d.ts +1 -0
- package/lib/services/agent/tools/generateVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/generateVideo.tool.js +20 -1
- package/lib/services/agent/tools/index.d.ts +4 -0
- package/lib/services/agent/tools/index.d.ts.map +1 -1
- package/lib/services/agent/tools/index.js +4 -0
- package/lib/services/agent/tools/matchBrollToScript.tool.d.ts +50 -0
- package/lib/services/agent/tools/matchBrollToScript.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/matchBrollToScript.tool.js +139 -0
- package/lib/services/agent/tools/planVideo.tool.d.ts +57 -1
- package/lib/services/agent/tools/planVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/planVideo.tool.js +3 -3
- package/lib/services/agent/tools/render.tool.d.ts +22 -1
- package/lib/services/agent/tools/render.tool.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.js +18 -3
- package/lib/services/aiGen/helpers.d.ts +8 -0
- package/lib/services/aiGen/helpers.d.ts.map +1 -1
- package/lib/services/aiGen/helpers.js +12 -0
- package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts +26 -0
- package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/anthropic/anthropic.service.js +95 -0
- package/lib/services/aiGen/providers/google/google.service.d.ts +25 -1
- package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/google.service.js +136 -237
- package/lib/services/aiGen/providers/google/googleApiKeys.d.ts +71 -0
- package/lib/services/aiGen/providers/google/googleApiKeys.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleApiKeys.js +137 -0
- package/lib/services/aiGen/providers/google/googleErrors.d.ts +13 -0
- package/lib/services/aiGen/providers/google/googleErrors.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleErrors.js +102 -0
- package/lib/services/aiGen/providers/google/googleFetch.d.ts +8 -0
- package/lib/services/aiGen/providers/google/googleFetch.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleFetch.js +96 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.d.ts +52 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.js +129 -0
- package/lib/services/aiGen/providers/google/googleMusic.d.ts +15 -0
- package/lib/services/aiGen/providers/google/googleMusic.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleMusic.js +77 -0
- package/lib/services/aiGen/providers/kling/kling.service.d.ts +7 -3
- package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/kling.service.js +23 -367
- package/lib/services/aiGen/providers/kling/klingCredits.d.ts +9 -0
- package/lib/services/aiGen/providers/kling/klingCredits.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingCredits.js +63 -0
- package/lib/services/aiGen/providers/kling/klingRequests.d.ts +32 -0
- package/lib/services/aiGen/providers/kling/klingRequests.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingRequests.js +194 -0
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts +16 -0
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingStatus.js +173 -0
- package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/pixverse/pixverse.service.js +7 -1
- package/lib/services/bullmq.service.d.ts +61 -0
- package/lib/services/bullmq.service.d.ts.map +1 -1
- package/lib/services/bullmq.service.js +124 -2
- package/lib/services/crypto/index.d.ts +2 -0
- package/lib/services/crypto/index.d.ts.map +1 -0
- package/lib/services/crypto/index.js +17 -0
- package/lib/services/crypto/tokenVault.d.ts +47 -0
- package/lib/services/crypto/tokenVault.d.ts.map +1 -0
- package/lib/services/crypto/tokenVault.js +179 -0
- package/lib/services/editor/captionStyleHint.d.ts +3 -0
- package/lib/services/editor/captionStyleHint.d.ts.map +1 -0
- package/lib/services/editor/captionStyleHint.js +112 -0
- package/lib/services/editor/planToProject.d.ts +7 -66
- package/lib/services/editor/planToProject.d.ts.map +1 -1
- package/lib/services/editor/planToProject.helpers.d.ts +40 -0
- package/lib/services/editor/planToProject.helpers.d.ts.map +1 -0
- package/lib/services/editor/planToProject.helpers.js +177 -0
- package/lib/services/editor/planToProject.js +197 -180
- package/lib/services/editor/planToProject.types.d.ts +94 -0
- package/lib/services/editor/planToProject.types.d.ts.map +1 -0
- package/lib/services/editor/planToProject.types.js +2 -0
- package/lib/services/firestore.service.d.ts +5 -0
- package/lib/services/firestore.service.d.ts.map +1 -1
- package/lib/services/firestore.service.js +13 -0
- package/lib/services/index.d.ts +13 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +13 -0
- package/lib/services/promptEnhancer/index.d.ts +18 -0
- package/lib/services/promptEnhancer/index.d.ts.map +1 -0
- package/lib/services/promptEnhancer/index.js +33 -0
- package/lib/services/promptEnhancer/models.d.ts +54 -0
- package/lib/services/promptEnhancer/models.d.ts.map +1 -0
- package/lib/services/promptEnhancer/models.js +37 -0
- package/lib/services/promptEnhancer/profiles/agent.profile.d.ts +14 -0
- package/lib/services/promptEnhancer/profiles/agent.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/agent.profile.js +40 -0
- package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts +13 -0
- package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/avatar.profile.js +40 -0
- package/lib/services/promptEnhancer/profiles/base.d.ts +28 -0
- package/lib/services/promptEnhancer/profiles/base.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/base.js +35 -0
- package/lib/services/promptEnhancer/profiles/image.profile.d.ts +11 -0
- package/lib/services/promptEnhancer/profiles/image.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/image.profile.js +42 -0
- package/lib/services/promptEnhancer/profiles/index.d.ts +12 -0
- package/lib/services/promptEnhancer/profiles/index.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/index.js +33 -0
- package/lib/services/promptEnhancer/profiles/video.profile.d.ts +15 -0
- package/lib/services/promptEnhancer/profiles/video.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/video.profile.js +81 -0
- package/lib/services/promptEnhancer/promptEnhancer.service.d.ts +45 -0
- package/lib/services/promptEnhancer/promptEnhancer.service.d.ts.map +1 -0
- package/lib/services/promptEnhancer/promptEnhancer.service.js +157 -0
- package/lib/services/promptEnhancer/schema.d.ts +19 -0
- package/lib/services/promptEnhancer/schema.d.ts.map +1 -0
- package/lib/services/promptEnhancer/schema.js +43 -0
- package/lib/services/promptEnhancer/types.d.ts +112 -0
- package/lib/services/promptEnhancer/types.d.ts.map +1 -0
- package/lib/services/promptEnhancer/types.js +2 -0
- package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts +60 -5
- package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts.map +1 -1
- package/lib/services/rateLimiter/distributedRateLimiter.service.js +184 -16
- package/lib/services/socialAI/captionGen.d.ts +81 -0
- package/lib/services/socialAI/captionGen.d.ts.map +1 -0
- package/lib/services/socialAI/captionGen.js +206 -0
- package/lib/services/socialAI/hookScore.d.ts +85 -0
- package/lib/services/socialAI/hookScore.d.ts.map +1 -0
- package/lib/services/socialAI/hookScore.js +170 -0
- package/lib/services/socialAI/index.d.ts +3 -0
- package/lib/services/socialAI/index.d.ts.map +1 -0
- package/lib/services/socialAI/index.js +18 -0
- package/lib/services/socialAccounts/index.d.ts +2 -0
- package/lib/services/socialAccounts/index.d.ts.map +1 -0
- package/lib/services/socialAccounts/index.js +17 -0
- package/lib/services/socialAccounts/socialAccountService.d.ts +25 -0
- package/lib/services/socialAccounts/socialAccountService.d.ts.map +1 -0
- package/lib/services/socialAccounts/socialAccountService.js +105 -0
- package/lib/services/socialEngage/factory.d.ts +7 -0
- package/lib/services/socialEngage/factory.d.ts.map +1 -0
- package/lib/services/socialEngage/factory.js +25 -0
- package/lib/services/socialEngage/index.d.ts +6 -0
- package/lib/services/socialEngage/index.d.ts.map +1 -0
- package/lib/services/socialEngage/index.js +21 -0
- package/lib/services/socialEngage/meta.engage.d.ts +17 -0
- package/lib/services/socialEngage/meta.engage.d.ts.map +1 -0
- package/lib/services/socialEngage/meta.engage.js +128 -0
- package/lib/services/socialEngage/metaWebhook.d.ts +50 -0
- package/lib/services/socialEngage/metaWebhook.d.ts.map +1 -0
- package/lib/services/socialEngage/metaWebhook.js +93 -0
- package/lib/services/socialEngage/types.d.ts +72 -0
- package/lib/services/socialEngage/types.d.ts.map +1 -0
- package/lib/services/socialEngage/types.js +10 -0
- package/lib/services/socialEngage/youtube.engage.d.ts +9 -0
- package/lib/services/socialEngage/youtube.engage.d.ts.map +1 -0
- package/lib/services/socialEngage/youtube.engage.js +87 -0
- package/lib/services/socialFormat/aspectGeometry.d.ts +74 -0
- package/lib/services/socialFormat/aspectGeometry.d.ts.map +1 -0
- package/lib/services/socialFormat/aspectGeometry.js +135 -0
- package/lib/services/socialFormat/index.d.ts +2 -0
- package/lib/services/socialFormat/index.d.ts.map +1 -0
- package/lib/services/socialFormat/index.js +19 -0
- package/lib/services/socialInsights/index.d.ts +3 -0
- package/lib/services/socialInsights/index.d.ts.map +1 -0
- package/lib/services/socialInsights/index.js +18 -0
- package/lib/services/socialInsights/recommendations.d.ts +131 -0
- package/lib/services/socialInsights/recommendations.d.ts.map +1 -0
- package/lib/services/socialInsights/recommendations.js +277 -0
- package/lib/services/socialInsights/timeBuckets.d.ts +35 -0
- package/lib/services/socialInsights/timeBuckets.d.ts.map +1 -0
- package/lib/services/socialInsights/timeBuckets.js +78 -0
- package/lib/services/socialMetrics/factory.d.ts +5 -0
- package/lib/services/socialMetrics/factory.d.ts.map +1 -0
- package/lib/services/socialMetrics/factory.js +24 -0
- package/lib/services/socialMetrics/index.d.ts +6 -0
- package/lib/services/socialMetrics/index.d.ts.map +1 -0
- package/lib/services/socialMetrics/index.js +21 -0
- package/lib/services/socialMetrics/meta.metrics.d.ts +22 -0
- package/lib/services/socialMetrics/meta.metrics.d.ts.map +1 -0
- package/lib/services/socialMetrics/meta.metrics.js +137 -0
- package/lib/services/socialMetrics/tiktok.metrics.d.ts +8 -0
- package/lib/services/socialMetrics/tiktok.metrics.d.ts.map +1 -0
- package/lib/services/socialMetrics/tiktok.metrics.js +43 -0
- package/lib/services/socialMetrics/types.d.ts +54 -0
- package/lib/services/socialMetrics/types.d.ts.map +1 -0
- package/lib/services/socialMetrics/types.js +2 -0
- package/lib/services/socialMetrics/youtube.metrics.d.ts +8 -0
- package/lib/services/socialMetrics/youtube.metrics.d.ts.map +1 -0
- package/lib/services/socialMetrics/youtube.metrics.js +43 -0
- package/lib/services/socialOAuth/factory.d.ts +7 -0
- package/lib/services/socialOAuth/factory.d.ts.map +1 -0
- package/lib/services/socialOAuth/factory.js +42 -0
- package/lib/services/socialOAuth/index.d.ts +11 -0
- package/lib/services/socialOAuth/index.d.ts.map +1 -0
- package/lib/services/socialOAuth/index.js +26 -0
- package/lib/services/socialOAuth/linkedin.oauth.d.ts +14 -0
- package/lib/services/socialOAuth/linkedin.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/linkedin.oauth.js +127 -0
- package/lib/services/socialOAuth/meta.oauth.d.ts +31 -0
- package/lib/services/socialOAuth/meta.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/meta.oauth.js +214 -0
- package/lib/services/socialOAuth/oauthState.d.ts +14 -0
- package/lib/services/socialOAuth/oauthState.d.ts.map +1 -0
- package/lib/services/socialOAuth/oauthState.js +66 -0
- package/lib/services/socialOAuth/pinterest.oauth.d.ts +15 -0
- package/lib/services/socialOAuth/pinterest.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/pinterest.oauth.js +126 -0
- package/lib/services/socialOAuth/threads.oauth.d.ts +14 -0
- package/lib/services/socialOAuth/threads.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/threads.oauth.js +129 -0
- package/lib/services/socialOAuth/tiktok.oauth.d.ts +15 -0
- package/lib/services/socialOAuth/tiktok.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/tiktok.oauth.js +151 -0
- package/lib/services/socialOAuth/types.d.ts +67 -0
- package/lib/services/socialOAuth/types.d.ts.map +1 -0
- package/lib/services/socialOAuth/types.js +2 -0
- package/lib/services/socialOAuth/x.oauth.d.ts +17 -0
- package/lib/services/socialOAuth/x.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/x.oauth.js +134 -0
- package/lib/services/socialOAuth/youtube.oauth.d.ts +15 -0
- package/lib/services/socialOAuth/youtube.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/youtube.oauth.js +156 -0
- package/lib/services/socialPublish/factory.d.ts +5 -0
- package/lib/services/socialPublish/factory.d.ts.map +1 -0
- package/lib/services/socialPublish/factory.js +32 -0
- package/lib/services/socialPublish/index.d.ts +10 -0
- package/lib/services/socialPublish/index.d.ts.map +1 -0
- package/lib/services/socialPublish/index.js +25 -0
- package/lib/services/socialPublish/linkedin.publish.d.ts +9 -0
- package/lib/services/socialPublish/linkedin.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/linkedin.publish.js +143 -0
- package/lib/services/socialPublish/meta.publish.d.ts +28 -0
- package/lib/services/socialPublish/meta.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/meta.publish.js +149 -0
- package/lib/services/socialPublish/pinterest.publish.d.ts +13 -0
- package/lib/services/socialPublish/pinterest.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/pinterest.publish.js +130 -0
- package/lib/services/socialPublish/threads.publish.d.ts +12 -0
- package/lib/services/socialPublish/threads.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/threads.publish.js +96 -0
- package/lib/services/socialPublish/tiktok.publish.d.ts +13 -0
- package/lib/services/socialPublish/tiktok.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/tiktok.publish.js +118 -0
- package/lib/services/socialPublish/types.d.ts +47 -0
- package/lib/services/socialPublish/types.d.ts.map +1 -0
- package/lib/services/socialPublish/types.js +2 -0
- package/lib/services/socialPublish/x.publish.d.ts +12 -0
- package/lib/services/socialPublish/x.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/x.publish.js +147 -0
- package/lib/services/socialPublish/youtube.publish.d.ts +9 -0
- package/lib/services/socialPublish/youtube.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/youtube.publish.js +107 -0
- package/lib/services/stock/index.d.ts +2 -0
- package/lib/services/stock/index.d.ts.map +1 -0
- package/lib/services/stock/index.js +17 -0
- package/lib/services/stock/realPersonSafety.d.ts +99 -0
- package/lib/services/stock/realPersonSafety.d.ts.map +1 -0
- package/lib/services/stock/realPersonSafety.js +248 -0
- package/lib/services/translation/index.d.ts +2 -0
- package/lib/services/translation/index.d.ts.map +1 -0
- package/lib/services/translation/index.js +9 -0
- package/lib/services/translation/translation.service.d.ts +50 -0
- package/lib/services/translation/translation.service.d.ts.map +1 -0
- package/lib/services/translation/translation.service.js +211 -0
- package/lib/utils/helpers.d.ts +2 -4
- package/lib/utils/helpers.d.ts.map +1 -1
- package/lib/utils/helpers.js +9 -63
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/index.js +1 -0
- package/lib/utils/renderTier.d.ts +26 -0
- package/lib/utils/renderTier.d.ts.map +1 -0
- package/lib/utils/renderTier.js +34 -0
- package/package.json +1 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TikTokPublisher = void 0;
|
|
4
|
+
const types_1 = require("../../globals/types");
|
|
5
|
+
const logger_1 = require("../../utils/logger");
|
|
6
|
+
/**
|
|
7
|
+
* TikTok publisher — Content Posting API, PULL_FROM_URL direct post. Phase 6.
|
|
8
|
+
*
|
|
9
|
+
* Flow (plan §G, TikTok Content Posting API):
|
|
10
|
+
* 1. POST /v2/post/publish/video/init/ with source=PULL_FROM_URL + video_url
|
|
11
|
+
* → { publish_id }
|
|
12
|
+
* 2. Poll /v2/post/publish/status/fetch/ until PUBLISH_COMPLETE / FAILED.
|
|
13
|
+
*
|
|
14
|
+
* Gates:
|
|
15
|
+
* - PULL_FROM_URL requires the media domain (our CDN) verified in the dev portal.
|
|
16
|
+
* - Until the Content Posting audit passes, `privacy_level` is forced to
|
|
17
|
+
* SELF_ONLY (private) and the app can only post for test users. We map the
|
|
18
|
+
* generic `privacy` to TikTok's enum and default to SELF_ONLY (safe pre-audit).
|
|
19
|
+
* - TikTok has NO native scheduling — the worker schedules via BullMQ delay.
|
|
20
|
+
*/
|
|
21
|
+
const INIT_ENDPOINT = "https://open.tiktokapis.com/v2/post/publish/video/init/";
|
|
22
|
+
const STATUS_ENDPOINT = "https://open.tiktokapis.com/v2/post/publish/status/fetch/";
|
|
23
|
+
const PRIVACY_VALUES = new Set([
|
|
24
|
+
"PUBLIC_TO_EVERYONE",
|
|
25
|
+
"MUTUAL_FOLLOW_FRIENDS",
|
|
26
|
+
"FOLLOWER_OF_CREATOR",
|
|
27
|
+
"SELF_ONLY",
|
|
28
|
+
]);
|
|
29
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
30
|
+
class TikTokPublisher {
|
|
31
|
+
constructor() {
|
|
32
|
+
this.provider = types_1.ESocialProvider.TIKTOK;
|
|
33
|
+
this.maxPolls = 30;
|
|
34
|
+
this.pollDelayMs = 5000;
|
|
35
|
+
}
|
|
36
|
+
async publish(input) {
|
|
37
|
+
const title = this.buildTitle(input);
|
|
38
|
+
const privacyLevel = this.resolvePrivacy(input);
|
|
39
|
+
// 1. Init the direct post with PULL_FROM_URL.
|
|
40
|
+
const initResp = await fetch(INIT_ENDPOINT, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: {
|
|
43
|
+
Authorization: `Bearer ${input.accessToken}`,
|
|
44
|
+
"Content-Type": "application/json; charset=UTF-8",
|
|
45
|
+
},
|
|
46
|
+
body: JSON.stringify({
|
|
47
|
+
post_info: {
|
|
48
|
+
title,
|
|
49
|
+
privacy_level: privacyLevel,
|
|
50
|
+
disable_duet: false,
|
|
51
|
+
disable_comment: false,
|
|
52
|
+
disable_stitch: false,
|
|
53
|
+
},
|
|
54
|
+
source_info: {
|
|
55
|
+
source: "PULL_FROM_URL",
|
|
56
|
+
video_url: input.mediaUrl,
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
});
|
|
60
|
+
const init = (await initResp.json());
|
|
61
|
+
const publishId = init.data?.publish_id;
|
|
62
|
+
if (!initResp.ok || init.error?.code === "access_token_invalid" || !publishId) {
|
|
63
|
+
throw new Error(`TikTokPublisher: init ${initResp.status} ${init.error?.message ?? "no publish_id"}`);
|
|
64
|
+
}
|
|
65
|
+
// 2. Poll for completion.
|
|
66
|
+
const postId = await this.pollStatus(input.accessToken, publishId);
|
|
67
|
+
logger_1.logger.info("TikTokPublisher: published", { publishId, postId });
|
|
68
|
+
return {
|
|
69
|
+
providerPostId: postId ?? publishId,
|
|
70
|
+
// TikTok doesn't return a canonical web URL pre-audit; the worker can fill
|
|
71
|
+
// it once the post id resolves (profile-relative).
|
|
72
|
+
publishedUrl: undefined,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async pollStatus(accessToken, publishId) {
|
|
76
|
+
for (let i = 0; i < this.maxPolls; i++) {
|
|
77
|
+
await sleep(this.pollDelayMs);
|
|
78
|
+
const resp = await fetch(STATUS_ENDPOINT, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: {
|
|
81
|
+
Authorization: `Bearer ${accessToken}`,
|
|
82
|
+
"Content-Type": "application/json; charset=UTF-8",
|
|
83
|
+
},
|
|
84
|
+
body: JSON.stringify({ publish_id: publishId }),
|
|
85
|
+
});
|
|
86
|
+
const json = (await resp.json());
|
|
87
|
+
const status = json.data?.status;
|
|
88
|
+
if (status === "PUBLISH_COMPLETE") {
|
|
89
|
+
return json.data?.publicaly_available_post_id?.[0];
|
|
90
|
+
}
|
|
91
|
+
if (status === "FAILED") {
|
|
92
|
+
throw new Error(`TikTokPublisher: publish failed — ${json.data?.fail_reason ?? "unknown"}`);
|
|
93
|
+
}
|
|
94
|
+
// PROCESSING_* / SEND_TO_USER_INBOX → keep polling.
|
|
95
|
+
}
|
|
96
|
+
throw new Error("TikTokPublisher: timed out waiting for publish completion");
|
|
97
|
+
}
|
|
98
|
+
/** TikTok caption ("title") max ~2200 chars; merge hashtags inline. */
|
|
99
|
+
buildTitle(input) {
|
|
100
|
+
const tags = input.hashtags && input.hashtags.length
|
|
101
|
+
? " " +
|
|
102
|
+
input.hashtags.map((h) => (h.startsWith("#") ? h : `#${h}`)).join(" ")
|
|
103
|
+
: "";
|
|
104
|
+
return `${input.caption ?? ""}${tags}`.trim().slice(0, 2200);
|
|
105
|
+
}
|
|
106
|
+
resolvePrivacy(input) {
|
|
107
|
+
const p = (input.privacy ?? "").toUpperCase();
|
|
108
|
+
if (PRIVACY_VALUES.has(p))
|
|
109
|
+
return p;
|
|
110
|
+
// Map common generic values; default SELF_ONLY (audit-safe).
|
|
111
|
+
if (p === "PUBLIC")
|
|
112
|
+
return "PUBLIC_TO_EVERYONE";
|
|
113
|
+
if (p === "PRIVATE")
|
|
114
|
+
return "SELF_ONLY";
|
|
115
|
+
return "SELF_ONLY";
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.TikTokPublisher = TikTokPublisher;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ESocialProvider } from "../../globals/types";
|
|
2
|
+
/**
|
|
3
|
+
* X8 Social Suite — publisher abstraction. One implementation per platform turns
|
|
4
|
+
* a (mediaUrl, caption, options, accessToken) into a live post. The publish
|
|
5
|
+
* worker resolves a valid access token (refreshing if needed) and calls this.
|
|
6
|
+
* See notes/SOCIAL_SUITE_PLAN.md §4.
|
|
7
|
+
*/
|
|
8
|
+
export interface PublishInput {
|
|
9
|
+
/** Cleartext access token for the target account (already refreshed). */
|
|
10
|
+
accessToken: string;
|
|
11
|
+
/**
|
|
12
|
+
* The provider's account id (IG Business user id / FB Page id). Required by
|
|
13
|
+
* Meta publishers, which POST to `/{ig-user-id}/media` or `/{page-id}/videos`.
|
|
14
|
+
* YouTube ignores it (the access token already scopes to the channel).
|
|
15
|
+
*/
|
|
16
|
+
providerAccountId?: string;
|
|
17
|
+
/** Public URL of the media to publish (rendered/cropped for the platform). */
|
|
18
|
+
mediaUrl: string;
|
|
19
|
+
/**
|
|
20
|
+
* Public URL of a poster/cover frame for the video. Optional and ignored by
|
|
21
|
+
* most publishers; Pinterest REQUIRES a cover image for video pins, so the
|
|
22
|
+
* worker should populate it (e.g. the videoJob's poster) when targeting
|
|
23
|
+
* Pinterest. When absent, the Pinterest publisher falls back to a key-frame.
|
|
24
|
+
*/
|
|
25
|
+
thumbnailUrl?: string;
|
|
26
|
+
/** Caption / description text. */
|
|
27
|
+
caption: string;
|
|
28
|
+
/** Title (YouTube uses this; others ignore). */
|
|
29
|
+
title?: string;
|
|
30
|
+
/** Provider visibility value (e.g. "public" | "unlisted" | "private"). */
|
|
31
|
+
privacy?: string;
|
|
32
|
+
/** Unix ms for native scheduled publish where the platform supports it (YT). */
|
|
33
|
+
scheduledAt?: number;
|
|
34
|
+
/** Hashtags to merge into the caption per-platform convention. */
|
|
35
|
+
hashtags?: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface PublishResult {
|
|
38
|
+
/** Provider's id for the new post. */
|
|
39
|
+
providerPostId: string;
|
|
40
|
+
/** Public URL of the live (or scheduled) post, when derivable. */
|
|
41
|
+
publishedUrl?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ISocialPublisher {
|
|
44
|
+
readonly provider: ESocialProvider;
|
|
45
|
+
publish(input: PublishInput): Promise<PublishResult>;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/socialPublish/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACtD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ESocialProvider } from "../../globals/types";
|
|
2
|
+
import { ISocialPublisher, PublishInput, PublishResult } from "./types";
|
|
3
|
+
export declare class XPublisher implements ISocialPublisher {
|
|
4
|
+
readonly provider = ESocialProvider.X;
|
|
5
|
+
private readonly maxPolls;
|
|
6
|
+
publish(input: PublishInput): Promise<PublishResult>;
|
|
7
|
+
private uploadForm;
|
|
8
|
+
private pollMediaStatus;
|
|
9
|
+
/** X has a hard 280-char limit; trim caption + as many hashtags as fit. */
|
|
10
|
+
private buildText;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=x.publish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x.publish.d.ts","sourceRoot":"","sources":["../../../src/services/socialPublish/x.publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAkCxE,qBAAa,UAAW,YAAW,gBAAgB;IACjD,QAAQ,CAAC,QAAQ,qBAAqB;IAEtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAM;IAEzB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;YAoF5C,UAAU;YAoBV,eAAe;IAuB7B,2EAA2E;IAC3E,OAAO,CAAC,SAAS;CAalB"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.XPublisher = void 0;
|
|
4
|
+
const types_1 = require("../../globals/types");
|
|
5
|
+
const logger_1 = require("../../utils/logger");
|
|
6
|
+
/**
|
|
7
|
+
* X (Twitter) publisher — Phase 6. Chunked video upload (v1.1 media/upload,
|
|
8
|
+
* which accepts an OAuth 2.0 user-context bearer) then a v2 Tweet referencing
|
|
9
|
+
* the media id:
|
|
10
|
+
* 1. INIT → media_id_string
|
|
11
|
+
* 2. APPEND → upload each ≤5MB chunk (multipart)
|
|
12
|
+
* 3. FINALIZE → may return async processing_info
|
|
13
|
+
* 4. STATUS → poll until state=succeeded
|
|
14
|
+
* 5. POST /2/tweets { text, media: { media_ids: [id] } }
|
|
15
|
+
*
|
|
16
|
+
* No native scheduling — the worker schedules via BullMQ delay. Caption is hard-
|
|
17
|
+
* capped at 280 chars (X's real limit), hashtags merged inline within that cap.
|
|
18
|
+
*/
|
|
19
|
+
const UPLOAD_ENDPOINT = "https://upload.twitter.com/1.1/media/upload.json";
|
|
20
|
+
const TWEETS_ENDPOINT = "https://api.twitter.com/2/tweets";
|
|
21
|
+
const CHUNK_SIZE = 5 * 1024 * 1024; // 5MB, X's per-APPEND limit
|
|
22
|
+
const TWEET_MAX = 280;
|
|
23
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
24
|
+
class XPublisher {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.provider = types_1.ESocialProvider.X;
|
|
27
|
+
this.maxPolls = 30;
|
|
28
|
+
}
|
|
29
|
+
async publish(input) {
|
|
30
|
+
const token = input.accessToken;
|
|
31
|
+
// 0. Fetch the media bytes.
|
|
32
|
+
const mediaResp = await fetch(input.mediaUrl);
|
|
33
|
+
if (!mediaResp.ok) {
|
|
34
|
+
throw new Error(`XPublisher: media fetch ${mediaResp.status}`);
|
|
35
|
+
}
|
|
36
|
+
const bytes = Buffer.from(await mediaResp.arrayBuffer());
|
|
37
|
+
// 1. INIT.
|
|
38
|
+
const init = (await this.uploadForm(token, {
|
|
39
|
+
command: "INIT",
|
|
40
|
+
total_bytes: String(bytes.length),
|
|
41
|
+
media_type: "video/mp4",
|
|
42
|
+
media_category: "tweet_video",
|
|
43
|
+
}));
|
|
44
|
+
const mediaId = init.media_id_string;
|
|
45
|
+
if (!mediaId) {
|
|
46
|
+
throw new Error(`XPublisher: INIT failed ${init.errors?.[0]?.message ?? ""}`);
|
|
47
|
+
}
|
|
48
|
+
// 2. APPEND each chunk.
|
|
49
|
+
let segment = 0;
|
|
50
|
+
for (let offset = 0; offset < bytes.length; offset += CHUNK_SIZE) {
|
|
51
|
+
const chunk = bytes.subarray(offset, offset + CHUNK_SIZE);
|
|
52
|
+
const form = new FormData();
|
|
53
|
+
form.append("command", "APPEND");
|
|
54
|
+
form.append("media_id", mediaId);
|
|
55
|
+
form.append("segment_index", String(segment));
|
|
56
|
+
form.append("media", new Blob([chunk]));
|
|
57
|
+
const resp = await fetch(UPLOAD_ENDPOINT, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
60
|
+
body: form,
|
|
61
|
+
});
|
|
62
|
+
if (!resp.ok) {
|
|
63
|
+
throw new Error(`XPublisher: APPEND segment ${segment} ${resp.status}`);
|
|
64
|
+
}
|
|
65
|
+
segment++;
|
|
66
|
+
}
|
|
67
|
+
// 3. FINALIZE.
|
|
68
|
+
const finalize = (await this.uploadForm(token, {
|
|
69
|
+
command: "FINALIZE",
|
|
70
|
+
media_id: mediaId,
|
|
71
|
+
}));
|
|
72
|
+
// 4. Poll async processing if needed.
|
|
73
|
+
if (finalize.processing_info && finalize.processing_info.state !== "succeeded") {
|
|
74
|
+
await this.pollMediaStatus(token, mediaId, finalize.processing_info.check_after_secs);
|
|
75
|
+
}
|
|
76
|
+
// 5. Create the Tweet.
|
|
77
|
+
const tweetResp = await fetch(TWEETS_ENDPOINT, {
|
|
78
|
+
method: "POST",
|
|
79
|
+
headers: {
|
|
80
|
+
Authorization: `Bearer ${token}`,
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({
|
|
84
|
+
text: this.buildText(input),
|
|
85
|
+
media: { media_ids: [mediaId] },
|
|
86
|
+
}),
|
|
87
|
+
});
|
|
88
|
+
const tweet = (await tweetResp.json());
|
|
89
|
+
const tweetId = tweet.data?.id;
|
|
90
|
+
if (!tweetResp.ok || !tweetId) {
|
|
91
|
+
throw new Error(`XPublisher: create tweet ${tweetResp.status} ${tweet.errors?.[0]?.message ?? tweet.detail ?? ""}`.trim());
|
|
92
|
+
}
|
|
93
|
+
logger_1.logger.info("XPublisher: published", { tweetId });
|
|
94
|
+
return {
|
|
95
|
+
providerPostId: tweetId,
|
|
96
|
+
publishedUrl: `https://x.com/i/web/status/${tweetId}`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
async uploadForm(token, fields) {
|
|
100
|
+
const form = new FormData();
|
|
101
|
+
for (const [k, v] of Object.entries(fields))
|
|
102
|
+
form.append(k, v);
|
|
103
|
+
const resp = await fetch(UPLOAD_ENDPOINT, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
106
|
+
body: form,
|
|
107
|
+
});
|
|
108
|
+
if (!resp.ok) {
|
|
109
|
+
const text = await resp.text();
|
|
110
|
+
throw new Error(`XPublisher: upload ${fields.command} ${resp.status} ${text}`);
|
|
111
|
+
}
|
|
112
|
+
return resp.json();
|
|
113
|
+
}
|
|
114
|
+
async pollMediaStatus(token, mediaId, firstDelaySecs) {
|
|
115
|
+
let delayMs = (firstDelaySecs ?? 3) * 1000;
|
|
116
|
+
for (let i = 0; i < this.maxPolls; i++) {
|
|
117
|
+
await sleep(delayMs);
|
|
118
|
+
const url = `${UPLOAD_ENDPOINT}?command=STATUS&media_id=${mediaId}`;
|
|
119
|
+
const resp = await fetch(url, {
|
|
120
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
121
|
+
});
|
|
122
|
+
const json = (await resp.json());
|
|
123
|
+
const state = json.processing_info?.state;
|
|
124
|
+
if (state === "succeeded")
|
|
125
|
+
return;
|
|
126
|
+
if (state === "failed") {
|
|
127
|
+
throw new Error("XPublisher: media processing failed");
|
|
128
|
+
}
|
|
129
|
+
delayMs = (json.processing_info?.check_after_secs ?? 3) * 1000;
|
|
130
|
+
}
|
|
131
|
+
throw new Error("XPublisher: timed out waiting for media processing");
|
|
132
|
+
}
|
|
133
|
+
/** X has a hard 280-char limit; trim caption + as many hashtags as fit. */
|
|
134
|
+
buildText(input) {
|
|
135
|
+
const caption = (input.caption ?? "").trim();
|
|
136
|
+
const tags = (input.hashtags ?? []).map((h) => h.startsWith("#") ? h : `#${h}`);
|
|
137
|
+
let text = caption;
|
|
138
|
+
for (const tag of tags) {
|
|
139
|
+
const candidate = text ? `${text} ${tag}` : tag;
|
|
140
|
+
if (candidate.length > TWEET_MAX)
|
|
141
|
+
break;
|
|
142
|
+
text = candidate;
|
|
143
|
+
}
|
|
144
|
+
return text.slice(0, TWEET_MAX);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.XPublisher = XPublisher;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ESocialProvider } from "../../globals/types";
|
|
2
|
+
import { ISocialPublisher, PublishInput, PublishResult } from "./types";
|
|
3
|
+
export declare class YouTubePublisher implements ISocialPublisher {
|
|
4
|
+
readonly provider = ESocialProvider.YOUTUBE;
|
|
5
|
+
publish(input: PublishInput): Promise<PublishResult>;
|
|
6
|
+
private resolvePrivacy;
|
|
7
|
+
private buildDescription;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=youtube.publish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"youtube.publish.d.ts","sourceRoot":"","sources":["../../../src/services/socialPublish/youtube.publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AA0BxE,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,QAAQ,CAAC,QAAQ,2BAA2B;IAEtC,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IA+E1D,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,gBAAgB;CAUzB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.YouTubePublisher = void 0;
|
|
4
|
+
const types_1 = require("../../globals/types");
|
|
5
|
+
const logger_1 = require("../../utils/logger");
|
|
6
|
+
/**
|
|
7
|
+
* YouTube publisher — uploads a video via the Data API `videos.insert` resumable
|
|
8
|
+
* endpoint and sets visibility / native scheduling. Phase 1. See SOCIAL_SUITE_PLAN.md.
|
|
9
|
+
*
|
|
10
|
+
* Flow:
|
|
11
|
+
* 1. POST metadata to the resumable endpoint → get the upload session URL.
|
|
12
|
+
* 2. PUT the media bytes to that URL → get the video resource (with id).
|
|
13
|
+
*
|
|
14
|
+
* Scheduling: when `scheduledAt` is set, YouTube requires `privacyStatus=private`
|
|
15
|
+
* + `status.publishAt` (RFC3339); it auto-flips to public at that time.
|
|
16
|
+
*
|
|
17
|
+
* Quota: `videos.insert` is the expensive call against the shared 10k/day project
|
|
18
|
+
* quota — the worker should track burn (plan §3). Single-PUT upload is fine for
|
|
19
|
+
* short-form; switch to chunked upload if we publish very large long-form files.
|
|
20
|
+
*/
|
|
21
|
+
const RESUMABLE_INIT = "https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=snippet,status";
|
|
22
|
+
class YouTubePublisher {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.provider = types_1.ESocialProvider.YOUTUBE;
|
|
25
|
+
}
|
|
26
|
+
async publish(input) {
|
|
27
|
+
const description = this.buildDescription(input);
|
|
28
|
+
const privacyStatus = this.resolvePrivacy(input);
|
|
29
|
+
const metadata = {
|
|
30
|
+
snippet: {
|
|
31
|
+
title: (input.title ?? input.caption ?? "VidSpot video").slice(0, 100),
|
|
32
|
+
description: description.slice(0, 5000),
|
|
33
|
+
},
|
|
34
|
+
status: {
|
|
35
|
+
privacyStatus,
|
|
36
|
+
selfDeclaredMadeForKids: false,
|
|
37
|
+
...(input.scheduledAt
|
|
38
|
+
? { publishAt: new Date(input.scheduledAt).toISOString() }
|
|
39
|
+
: {}),
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
// 1. Fetch the media bytes (the worker passes a public/rendered URL).
|
|
43
|
+
const mediaResp = await fetch(input.mediaUrl);
|
|
44
|
+
if (!mediaResp.ok) {
|
|
45
|
+
throw new Error(`YouTubePublisher: media fetch ${mediaResp.status} for ${input.mediaUrl}`);
|
|
46
|
+
}
|
|
47
|
+
const contentType = mediaResp.headers.get("content-type") ?? "video/mp4";
|
|
48
|
+
const bytes = Buffer.from(await mediaResp.arrayBuffer());
|
|
49
|
+
// 2. Init the resumable session.
|
|
50
|
+
const initResp = await fetch(RESUMABLE_INIT, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
Authorization: `Bearer ${input.accessToken}`,
|
|
54
|
+
"Content-Type": "application/json; charset=UTF-8",
|
|
55
|
+
"X-Upload-Content-Type": contentType,
|
|
56
|
+
"X-Upload-Content-Length": String(bytes.length),
|
|
57
|
+
},
|
|
58
|
+
body: JSON.stringify(metadata),
|
|
59
|
+
});
|
|
60
|
+
if (!initResp.ok) {
|
|
61
|
+
const text = await initResp.text();
|
|
62
|
+
throw new Error(`YouTubePublisher: resumable init ${initResp.status} ${text}`);
|
|
63
|
+
}
|
|
64
|
+
const uploadUrl = initResp.headers.get("location");
|
|
65
|
+
if (!uploadUrl) {
|
|
66
|
+
throw new Error("YouTubePublisher: no upload session URL returned");
|
|
67
|
+
}
|
|
68
|
+
// 3. Upload the bytes.
|
|
69
|
+
const uploadResp = await fetch(uploadUrl, {
|
|
70
|
+
method: "PUT",
|
|
71
|
+
headers: {
|
|
72
|
+
"Content-Type": contentType,
|
|
73
|
+
"Content-Length": String(bytes.length),
|
|
74
|
+
},
|
|
75
|
+
body: bytes,
|
|
76
|
+
});
|
|
77
|
+
const result = (await uploadResp.json());
|
|
78
|
+
if (!uploadResp.ok || !result.id) {
|
|
79
|
+
throw new Error(`YouTubePublisher: upload failed ${uploadResp.status} ${result.error?.message ?? ""}`);
|
|
80
|
+
}
|
|
81
|
+
logger_1.logger.info("YouTubePublisher: published", {
|
|
82
|
+
videoId: result.id,
|
|
83
|
+
scheduled: Boolean(input.scheduledAt),
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
providerPostId: result.id,
|
|
87
|
+
publishedUrl: `https://www.youtube.com/watch?v=${result.id}`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
resolvePrivacy(input) {
|
|
91
|
+
// Native scheduling requires private until publishAt fires.
|
|
92
|
+
if (input.scheduledAt)
|
|
93
|
+
return "private";
|
|
94
|
+
const p = (input.privacy ?? "public").toLowerCase();
|
|
95
|
+
return ["public", "unlisted", "private"].includes(p) ? p : "public";
|
|
96
|
+
}
|
|
97
|
+
buildDescription(input) {
|
|
98
|
+
const tags = input.hashtags && input.hashtags.length
|
|
99
|
+
? "\n\n" +
|
|
100
|
+
input.hashtags
|
|
101
|
+
.map((h) => (h.startsWith("#") ? h : `#${h}`))
|
|
102
|
+
.join(" ")
|
|
103
|
+
: "";
|
|
104
|
+
return `${input.caption ?? ""}${tags}`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.YouTubePublisher = YouTubePublisher;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/stock/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./realPersonSafety"), exports);
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S-1 — real-person safety screening for the internal stock library.
|
|
3
|
+
*
|
|
4
|
+
* The stock catalog (S-1/S-2/S-3) may surface free-tier user output as public
|
|
5
|
+
* "made on VidSpot" / inspiration content. Per ToS we must NEVER surface a
|
|
6
|
+
* video whose prompt or input imagery involves a *real, identifiable person*
|
|
7
|
+
* (privacy / likeness exposure). This module is the safety gate the candidate
|
|
8
|
+
* scanner (and later the S-2 tagger) runs before a video is even eligible for
|
|
9
|
+
* human review.
|
|
10
|
+
*
|
|
11
|
+
* Two independent signals, both via Gemini Flash (cheap, ~$0.00002/image):
|
|
12
|
+
* 1. `detectRealPersonNamesInText` — LLM scan of all prompt/title/VO text for
|
|
13
|
+
* proper names of real people (celebrities, politicians, public figures,
|
|
14
|
+
* or a specific named private individual). Generic descriptors
|
|
15
|
+
* ("a woman", "the CEO", "a doctor"), brand names, and clearly-fictional
|
|
16
|
+
* character names are NOT flagged.
|
|
17
|
+
* 2. `detectRealPersonInImage` — vision pass over an input/reference/poster
|
|
18
|
+
* image asking whether it shows a real *photographic* human person (an
|
|
19
|
+
* actual individual's likeness) vs. an illustration / 3D-render / clearly
|
|
20
|
+
* AI-generated synthetic face.
|
|
21
|
+
*
|
|
22
|
+
* Fail-safe posture: any check that errors is reported with `error` set and
|
|
23
|
+
* `incomplete: true` on the combined result — the caller treats "could not
|
|
24
|
+
* confirm safe" as NOT cleared (never silently passes a video through).
|
|
25
|
+
*
|
|
26
|
+
* Pure + side-effect-free apart from the network call to Gemini. No Firestore,
|
|
27
|
+
* no writes — see `scripts/scanStockCandidates.ts` for orchestration.
|
|
28
|
+
*/
|
|
29
|
+
export interface RealPersonSafetyConfig {
|
|
30
|
+
/** Gemini / Google AI Studio API key. */
|
|
31
|
+
apiKey: string;
|
|
32
|
+
/** Override the model. Defaults to gemini-2.5-flash. */
|
|
33
|
+
model?: string;
|
|
34
|
+
/** Per-call timeout. Defaults to 30s. */
|
|
35
|
+
timeoutMs?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface NameScanResult {
|
|
38
|
+
/** True when at least one real, identifiable person's name appears. */
|
|
39
|
+
flagged: boolean;
|
|
40
|
+
/** The specific real-person names found (best-effort, may be empty). */
|
|
41
|
+
names: string[];
|
|
42
|
+
/** Short rationale from the model. */
|
|
43
|
+
reason: string;
|
|
44
|
+
/** Set when the scan could not run; caller treats this as not-cleared. */
|
|
45
|
+
error?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface ImagePersonResult {
|
|
48
|
+
imageUrl: string;
|
|
49
|
+
/** True when the image shows a real photographic human (a real likeness). */
|
|
50
|
+
containsRealPerson: boolean;
|
|
51
|
+
/** Model confidence 0..1. */
|
|
52
|
+
confidence: number;
|
|
53
|
+
reason: string;
|
|
54
|
+
/** Set when the check could not run; caller treats this as not-cleared. */
|
|
55
|
+
error?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface VideoSafetyInput {
|
|
58
|
+
/** All free-text associated with the video: prompt, originalPrompt, title, ttsText, per-scene prompts. */
|
|
59
|
+
texts: string[];
|
|
60
|
+
/** Candidate likeness images: input/reference images + poster still. */
|
|
61
|
+
imageUrls: string[];
|
|
62
|
+
}
|
|
63
|
+
export interface VideoSafetyResult {
|
|
64
|
+
/** True once at least one screening signal actually ran. */
|
|
65
|
+
checked: boolean;
|
|
66
|
+
nameScan?: NameScanResult;
|
|
67
|
+
imageScans: ImagePersonResult[];
|
|
68
|
+
/** Final verdict: a real, identifiable person is involved → must be dropped. */
|
|
69
|
+
involvesRealPerson: boolean;
|
|
70
|
+
/** True when some signal errored, so "safe" could not be fully confirmed. */
|
|
71
|
+
incomplete: boolean;
|
|
72
|
+
/** Human-readable reasons backing the verdict / incompleteness. */
|
|
73
|
+
reasons: string[];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Scan all of a video's free text for references to real, identifiable people.
|
|
77
|
+
* Returns `flagged:false` for empty input. On error returns `flagged:false`
|
|
78
|
+
* with `error` set — the caller must treat a set `error` as not-cleared.
|
|
79
|
+
*/
|
|
80
|
+
export declare function detectRealPersonNamesInText(texts: string[], config: RealPersonSafetyConfig): Promise<NameScanResult>;
|
|
81
|
+
/**
|
|
82
|
+
* Vision pass: does this single image show a real, identifiable photographic
|
|
83
|
+
* person? On any fetch/model error returns `containsRealPerson:false` with
|
|
84
|
+
* `error` set — caller treats a set `error` as not-cleared.
|
|
85
|
+
*/
|
|
86
|
+
export declare function detectRealPersonInImage(imageUrl: string, config: RealPersonSafetyConfig): Promise<ImagePersonResult>;
|
|
87
|
+
export interface ScreenOptions {
|
|
88
|
+
/** Cap how many images get a (paid) vision call. Defaults to 4. */
|
|
89
|
+
maxImages?: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Run the full real-person screen for one video: name scan + per-image vision.
|
|
93
|
+
*
|
|
94
|
+
* `involvesRealPerson` is the OR of every positive signal. `incomplete` is true
|
|
95
|
+
* when any signal errored — callers must require `checked && !involvesRealPerson
|
|
96
|
+
* && !incomplete` before treating a video as a cleared stock candidate.
|
|
97
|
+
*/
|
|
98
|
+
export declare function screenForRealPerson(input: VideoSafetyInput, config: RealPersonSafetyConfig, opts?: ScreenOptions): Promise<VideoSafetyResult>;
|
|
99
|
+
//# sourceMappingURL=realPersonSafety.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realPersonSafety.d.ts","sourceRoot":"","sources":["../../../src/services/stock/realPersonSafety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAQH,MAAM,WAAW,sBAAsB;IACrC,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,kBAAkB,EAAE,OAAO,CAAC;IAC5B,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,0GAA0G;IAC1G,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,wEAAwE;IACxE,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,gFAAgF;IAChF,kBAAkB,EAAE,OAAO,CAAC;IAC5B,6EAA6E;IAC7E,UAAU,EAAE,OAAO,CAAC;IACpB,mEAAmE;IACnE,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAuCD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,cAAc,CAAC,CA6CzB;AA4BD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,CAyD5B;AAED,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,sBAAsB,EAC9B,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,iBAAiB,CAAC,CA8C5B"}
|