pptx-custom 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -102,6 +102,7 @@ type SlideElement = {
102
102
  type: string;
103
103
  id?: string;
104
104
  groupId?: string;
105
+ lock?: boolean;
105
106
  left?: number;
106
107
  top?: number;
107
108
  width?: number;
@@ -248,10 +249,30 @@ type CustomSlide = {
248
249
  data?: undefined;
249
250
  };
250
251
  type PptxCustomContentInput = string | CustomSlide[];
252
+ type ThemeScopeKey = 'cover' | 'contents' | 'transition' | 'content' | 'end';
253
+ type ThemeScope = Record<ThemeScopeKey, boolean>;
254
+ type ThemeBackgroundImageInput = {
255
+ src: string;
256
+ scope: ThemeScope;
257
+ width?: number;
258
+ height?: number;
259
+ };
260
+ type ThemeLogoPosition = 'left' | 'right';
261
+ type ThemeLogoImageInput = {
262
+ src: string;
263
+ scope: ThemeScope;
264
+ position: ThemeLogoPosition;
265
+ width?: number;
266
+ height?: number;
267
+ };
251
268
  type PptxCustomThemeInput = {
252
269
  themeColors: string[];
253
270
  fontColor: string;
254
271
  backgroundColor?: string;
272
+ backgroundImage?: ThemeBackgroundImageInput;
273
+ logoImage?: ThemeLogoImageInput;
274
+ clearBackgroundImage?: boolean;
275
+ clearLogoImage?: boolean;
255
276
  };
256
277
  type PptxCustomOptions = {
257
278
  customContent?: PptxCustomContentInput;
package/dist/index.d.ts CHANGED
@@ -102,6 +102,7 @@ type SlideElement = {
102
102
  type: string;
103
103
  id?: string;
104
104
  groupId?: string;
105
+ lock?: boolean;
105
106
  left?: number;
106
107
  top?: number;
107
108
  width?: number;
@@ -248,10 +249,30 @@ type CustomSlide = {
248
249
  data?: undefined;
249
250
  };
250
251
  type PptxCustomContentInput = string | CustomSlide[];
252
+ type ThemeScopeKey = 'cover' | 'contents' | 'transition' | 'content' | 'end';
253
+ type ThemeScope = Record<ThemeScopeKey, boolean>;
254
+ type ThemeBackgroundImageInput = {
255
+ src: string;
256
+ scope: ThemeScope;
257
+ width?: number;
258
+ height?: number;
259
+ };
260
+ type ThemeLogoPosition = 'left' | 'right';
261
+ type ThemeLogoImageInput = {
262
+ src: string;
263
+ scope: ThemeScope;
264
+ position: ThemeLogoPosition;
265
+ width?: number;
266
+ height?: number;
267
+ };
251
268
  type PptxCustomThemeInput = {
252
269
  themeColors: string[];
253
270
  fontColor: string;
254
271
  backgroundColor?: string;
272
+ backgroundImage?: ThemeBackgroundImageInput;
273
+ logoImage?: ThemeLogoImageInput;
274
+ clearBackgroundImage?: boolean;
275
+ clearLogoImage?: boolean;
255
276
  };
256
277
  type PptxCustomOptions = {
257
278
  customContent?: PptxCustomContentInput;
package/dist/index.js CHANGED
@@ -306,11 +306,63 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
306
306
  };
307
307
 
308
308
  // src/custom-content/index.ts
309
+ var FALLBACK_SLIDE_WIDTH = 1e3;
310
+ var FALLBACK_SLIDE_HEIGHT = 562.5;
311
+ var LOGO_MARGIN_X = 24;
312
+ var LOGO_MARGIN_Y = 18;
313
+ var LOGO_MAX_WIDTH_RATIO = 0.34;
314
+ var LOGO_MAX_HEIGHT_RATIO = 0.16;
315
+ function isLogoImageElement(element) {
316
+ return element.type === "image" && element.imageType === "logo";
317
+ }
318
+ function fitSize(width, height, maxWidth, maxHeight) {
319
+ const safeWidth = width > 0 ? width : maxWidth;
320
+ const safeHeight = height > 0 ? height : maxHeight;
321
+ const scale = Math.min(maxWidth / safeWidth, maxHeight / safeHeight);
322
+ return {
323
+ width: safeWidth * scale,
324
+ height: safeHeight * scale
325
+ };
326
+ }
327
+ function normalizeLogoElements(deck) {
328
+ const slideWidth = deck.width || FALLBACK_SLIDE_WIDTH;
329
+ const slideHeight = deck.height || FALLBACK_SLIDE_HEIGHT;
330
+ const logoMaxWidth = slideWidth * LOGO_MAX_WIDTH_RATIO;
331
+ const logoMaxHeight = slideHeight * LOGO_MAX_HEIGHT_RATIO;
332
+ const slides = deck.slides.map((slide) => {
333
+ let changed = false;
334
+ const elements = slide.elements.map((element) => {
335
+ if (!isLogoImageElement(element)) return element;
336
+ const size = fitSize(
337
+ element.width ?? logoMaxWidth,
338
+ element.height ?? logoMaxHeight,
339
+ logoMaxWidth,
340
+ logoMaxHeight
341
+ );
342
+ const isLeft = (element.left ?? 0) < slideWidth / 2;
343
+ const left = isLeft ? LOGO_MARGIN_X : Math.max(LOGO_MARGIN_X, slideWidth - size.width - LOGO_MARGIN_X);
344
+ const top = LOGO_MARGIN_Y;
345
+ const { clip: _clip, ...rest } = element;
346
+ changed = true;
347
+ return {
348
+ ...rest,
349
+ left,
350
+ top,
351
+ width: size.width,
352
+ height: size.height,
353
+ fixedRatio: true
354
+ };
355
+ });
356
+ return changed ? { ...slide, elements } : slide;
357
+ });
358
+ return { ...deck, slides };
359
+ }
309
360
  function applyCustomContent(template, input) {
310
361
  const normalizedTemplate = (0, import_json2pptx_schema.parseDocument)(template);
311
362
  const CustomSlides = typeof input === "string" ? parseCustomContent(input) : input;
312
363
  const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides);
313
- return (0, import_json2pptx_schema.parseDocument)(updated);
364
+ const withNormalizedLogo = normalizeLogoElements(updated);
365
+ return (0, import_json2pptx_schema.parseDocument)(withNormalizedLogo);
314
366
  }
315
367
 
316
368
  // src/custom-theme/index.ts
@@ -579,10 +631,178 @@ function applyTheme2Json(deck, update) {
579
631
  }
580
632
 
581
633
  // src/custom-theme/index.ts
634
+ var FALLBACK_SLIDE_WIDTH2 = 1e3;
635
+ var FALLBACK_SLIDE_HEIGHT2 = 562.5;
636
+ var LOGO_MARGIN_X2 = 24;
637
+ var LOGO_MARGIN_Y2 = 18;
638
+ var LOGO_MAX_WIDTH_RATIO2 = 0.34;
639
+ var LOGO_MAX_HEIGHT_RATIO2 = 0.16;
640
+ var DEFAULT_LOGO_ASPECT_RATIO = 3.2;
641
+ function mapSlideTypeToScopeKey(type) {
642
+ const normalized = type?.trim().toLowerCase();
643
+ if (!normalized) return null;
644
+ if (normalized === "cover") return "cover";
645
+ if (normalized === "contents" || normalized === "agenda") return "contents";
646
+ if (normalized === "transition" || normalized === "section") return "transition";
647
+ if (normalized === "content") return "content";
648
+ if (normalized === "end" || normalized === "ending") return "end";
649
+ return null;
650
+ }
651
+ function isSlideInScope(slide, scope) {
652
+ const key = mapSlideTypeToScopeKey(slide.type);
653
+ if (!key) return false;
654
+ return Boolean(scope[key]);
655
+ }
656
+ function createElementId(prefix, slideIndex) {
657
+ const random = Math.random().toString(36).slice(2, 10);
658
+ return `${prefix}-${slideIndex}-${random}`;
659
+ }
660
+ function toHalfOpacityColor(value) {
661
+ const rgb = parseColorToRgb(value);
662
+ if (!rgb) return value;
663
+ return `rgba(${rgb.r},${rgb.g},${rgb.b},0.5)`;
664
+ }
665
+ function buildBackgroundElement(src, slideWidth, slideHeight, slideIndex) {
666
+ return {
667
+ type: "image",
668
+ id: createElementId("background", slideIndex),
669
+ src,
670
+ width: slideWidth,
671
+ height: slideHeight,
672
+ left: 0,
673
+ top: 0,
674
+ fixedRatio: true,
675
+ rotate: 0,
676
+ imageType: "background",
677
+ filters: {
678
+ opacity: "100%"
679
+ }
680
+ };
681
+ }
682
+ function buildLogoElement(src, slideWidth, slideHeight, position, slideIndex, logoWidth, logoHeight) {
683
+ const aspectRatio = resolveLogoAspectRatio(logoWidth, logoHeight);
684
+ const maxWidth = slideWidth * LOGO_MAX_WIDTH_RATIO2;
685
+ const maxHeight = slideHeight * LOGO_MAX_HEIGHT_RATIO2;
686
+ let width = maxWidth;
687
+ let height = width / aspectRatio;
688
+ if (height > maxHeight) {
689
+ height = maxHeight;
690
+ width = height * aspectRatio;
691
+ }
692
+ const left = position === "left" ? LOGO_MARGIN_X2 : Math.max(LOGO_MARGIN_X2, slideWidth - width - LOGO_MARGIN_X2);
693
+ return {
694
+ type: "image",
695
+ id: createElementId("logo", slideIndex),
696
+ src,
697
+ width,
698
+ height,
699
+ left,
700
+ top: LOGO_MARGIN_Y2,
701
+ fixedRatio: true,
702
+ rotate: 0,
703
+ imageType: "logo"
704
+ };
705
+ }
706
+ function resolveLogoAspectRatio(width, height) {
707
+ if (typeof width === "number" && typeof height === "number" && width > 0 && height > 0) {
708
+ return width / height;
709
+ }
710
+ return DEFAULT_LOGO_ASPECT_RATIO;
711
+ }
712
+ function replaceScopedMedia(deck, input) {
713
+ if (!deck.slides?.length) return deck;
714
+ const slideWidth = deck.width ?? FALLBACK_SLIDE_WIDTH2;
715
+ const slideHeight = deck.height ?? FALLBACK_SLIDE_HEIGHT2;
716
+ const backgroundInput = input.backgroundImage;
717
+ const logoInput = input.logoImage;
718
+ const shouldClearBackground = Boolean(input.clearBackgroundImage);
719
+ const shouldClearLogo = Boolean(input.clearLogoImage || shouldClearBackground);
720
+ if (!backgroundInput?.src && !logoInput?.src && !shouldClearBackground && !shouldClearLogo) {
721
+ return deck;
722
+ }
723
+ const slides = deck.slides.map((slide, slideIndex) => {
724
+ let nextElements = slide.elements ? [...slide.elements] : [];
725
+ let nextBackground = slide.background;
726
+ let changed = false;
727
+ if (shouldClearBackground) {
728
+ const before = nextElements.length;
729
+ nextElements = nextElements.filter(
730
+ (element) => !(element.type === "image" && element.imageType === "background")
731
+ );
732
+ if (nextElements.length !== before) {
733
+ changed = true;
734
+ if (input.backgroundColor) {
735
+ nextBackground = {
736
+ ...nextBackground ?? {},
737
+ type: "solid",
738
+ color: input.backgroundColor
739
+ };
740
+ }
741
+ }
742
+ }
743
+ if (shouldClearLogo) {
744
+ const before = nextElements.length;
745
+ nextElements = nextElements.filter(
746
+ (element) => !(element.type === "image" && element.imageType === "logo")
747
+ );
748
+ if (nextElements.length !== before) {
749
+ changed = true;
750
+ }
751
+ }
752
+ if (backgroundInput?.src && isSlideInScope(slide, backgroundInput.scope)) {
753
+ const withoutBackground = nextElements.filter(
754
+ (element) => !(element.type === "image" && element.imageType === "background")
755
+ );
756
+ nextElements = [
757
+ buildBackgroundElement(
758
+ backgroundInput.src,
759
+ slideWidth,
760
+ slideHeight,
761
+ slideIndex
762
+ ),
763
+ ...withoutBackground
764
+ ];
765
+ changed = true;
766
+ if (input.backgroundColor) {
767
+ nextBackground = {
768
+ ...nextBackground ?? {},
769
+ type: "solid",
770
+ color: toHalfOpacityColor(input.backgroundColor)
771
+ };
772
+ }
773
+ }
774
+ if (logoInput?.src && isSlideInScope(slide, logoInput.scope)) {
775
+ const withoutLogo = nextElements.filter(
776
+ (element) => !(element.type === "image" && element.imageType === "logo")
777
+ );
778
+ nextElements = [
779
+ ...withoutLogo,
780
+ buildLogoElement(
781
+ logoInput.src,
782
+ slideWidth,
783
+ slideHeight,
784
+ logoInput.position,
785
+ slideIndex,
786
+ logoInput.width,
787
+ logoInput.height
788
+ )
789
+ ];
790
+ changed = true;
791
+ }
792
+ if (!changed && nextBackground === slide.background) return slide;
793
+ return {
794
+ ...slide,
795
+ ...changed ? { elements: nextElements } : {},
796
+ ...nextBackground ? { background: nextBackground } : {}
797
+ };
798
+ });
799
+ return { ...deck, slides };
800
+ }
582
801
  function applyCustomTheme(deck, input) {
583
802
  const normalizedDeck = (0, import_json2pptx_schema2.parseDocument)(deck);
584
- const updated = applyTheme2Json(normalizedDeck, input);
585
- return (0, import_json2pptx_schema2.parseDocument)(updated);
803
+ const withColors = applyTheme2Json(normalizedDeck, input);
804
+ const withMedia = replaceScopedMedia(withColors, input);
805
+ return (0, import_json2pptx_schema2.parseDocument)(withMedia);
586
806
  }
587
807
  // Annotate the CommonJS export names for ESM import in node:
588
808
  0 && (module.exports = {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/custom-content/index.ts","../src/custom-content/parser.ts","../src/custom-content/html.ts","../src/custom-content/slide-appliers.ts","../src/custom-content/template-builder.ts","../src/custom-theme/index.ts","../src/custom-theme/color-utils.ts","../src/custom-theme/mappings.ts","../src/custom-theme/replacers.ts","../src/custom-theme/theme-applier.ts"],"sourcesContent":["import { applyCustomContent, parseCustomContent, applyCustomContentToTemplate } from './custom-content/index'\nimport { applyCustomTheme } from './custom-theme/index'\n\nexport {\n parseCustomContent,\n applyCustomContent,\n applyCustomContentToTemplate,\n\n applyCustomTheme,\n}\n\nexport type {\n CustomSlide,\n Deck,\n PptxCustomContentInput,\n PptxCustomOptions,\n PptxCustomThemeInput,\n TemplateJson,\n TemplateJsonElement,\n TemplateJsonSlide,\n TemplateJsonTheme\n} from './types'\n","import { parseDocument } from 'json2pptx-schema'\nimport type { PptxCustomContentInput, TemplateJson } from '../types'\nimport { parseCustomContent } from './parser'\nimport { applyCustomContentToTemplate } from './template-builder'\n\nexport function applyCustomContent (\n template: TemplateJson,\n input: PptxCustomContentInput\n): TemplateJson {\n const normalizedTemplate = parseDocument(template) as unknown as TemplateJson\n const CustomSlides = typeof input === 'string' ? parseCustomContent(input) : input\n const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides)\n return parseDocument(updated) as unknown as TemplateJson\n}\n\nexport { parseCustomContent, applyCustomContentToTemplate }\n","import type { BackendContentItem, CustomSlide } from '../types'\n\ntype UnknownRecord = Record<string, unknown>\n\nconst isRecord = (value: unknown): value is UnknownRecord =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst asString = (value: unknown): string | null =>\n typeof value === 'string' ? value : null\n\nconst asStringArray = (value: unknown): string[] | null => {\n if (!Array.isArray(value)) return null\n const normalized = value\n .map(item => asString(item))\n .filter((item): item is string => item !== null)\n return normalized.length === value.length ? normalized : null\n}\n\nconst normalizeType = (value: unknown): CustomSlide['type'] | null => {\n const raw = asString(value)?.trim().toLowerCase()\n if (!raw) return null\n if (raw === 'agenda') return 'contents'\n if (raw === 'section') return 'transition'\n if (raw === 'ending') return 'end'\n if (\n raw === 'cover' ||\n raw === 'contents' ||\n raw === 'transition' ||\n raw === 'content' ||\n raw === 'end'\n ) {\n return raw\n }\n return null\n}\n\nconst normalizeContentItems = (value: unknown): BackendContentItem[] | null => {\n if (!Array.isArray(value)) return null\n const normalized: BackendContentItem[] = []\n for (const item of value) {\n if (!isRecord(item)) return null\n const title = asString(item.title)\n const text = asString(item.text)\n if (title == null || text == null) return null\n normalized.push({ title, text })\n }\n return normalized\n}\n\nconst normalizeSlide = (value: unknown): CustomSlide | null => {\n if (!isRecord(value)) return null\n const type = normalizeType(value.type)\n if (!type) return null\n\n const rawData = isRecord(value.data) ? value.data : {}\n\n if (type === 'cover') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'contents') {\n const items = asStringArray(rawData.items)\n if (!items) return null\n return { type, data: { items } }\n }\n\n if (type === 'transition') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'content') {\n const title = asString(rawData.title)\n const items = normalizeContentItems(rawData.items)\n if (title == null || !items) return null\n return { type, data: { title, items } }\n }\n\n return { type }\n}\n\nconst parseNdJsonSlides = (raw: string): unknown[] =>\n raw\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => JSON.parse(line) as unknown)\n\nconst parseStructuredSlides = (raw: string): unknown[] | null => {\n const trimmed = raw.trim()\n if (!trimmed) return []\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed) as unknown\n } catch {\n return null\n }\n if (Array.isArray(parsed)) return parsed\n if (!isRecord(parsed)) return null\n if (Array.isArray(parsed.slides)) return parsed.slides\n if ('type' in parsed) return [parsed]\n return null\n}\n\nexport const parseCustomContent = (raw: string): CustomSlide[] => {\n const candidates = parseStructuredSlides(raw) ?? parseNdJsonSlides(raw)\n const slides = candidates\n .map(item => normalizeSlide(item))\n .filter((item): item is CustomSlide => item !== null)\n\n if (slides.length !== candidates.length) {\n throw new Error('Invalid custom content format')\n }\n return slides\n}\n","import type { TemplateJsonElement } from '../types'\n\nexport const updateHtmlContent = (html: string, text: string) => {\n if (typeof DOMParser === 'undefined') {\n return `<p>${text}</p>`\n }\n const parser = new DOMParser()\n const doc = parser.parseFromString(html, 'text/html')\n const spans = Array.from(doc.querySelectorAll('span'))\n if (spans.length > 0) {\n spans.forEach((span, index) => {\n span.textContent = index === 0 ? text : ''\n })\n } else {\n const paragraph = doc.querySelector('p')\n if (paragraph) {\n paragraph.textContent = text\n } else {\n doc.body.textContent = text\n }\n }\n return doc.body.innerHTML\n}\n\nexport const setElementText = (element: TemplateJsonElement, text: string) => {\n if (element.type !== 'text') return\n element.content = updateHtmlContent(element.content, text)\n}\n","import type {\n BackendContentData,\n BackendContentsData,\n BackendCoverData,\n BackendTransitionData,\n TemplateJsonSlide\n} from '../types'\nimport { setElementText, updateHtmlContent } from './html'\n\nfunction setShapeTextByType (\n slide: TemplateJsonSlide,\n textType: string,\n text: string\n): boolean {\n const shape = slide.elements.find((element) => {\n if (element.type !== 'shape') return false\n const maybeShape = element as unknown as {\n text?: { type?: string; content?: string }\n }\n return maybeShape.text?.type === textType\n })\n\n if (!shape) return false\n\n const shapeWithText = shape as unknown as {\n text?: { type?: string; content?: string }\n }\n if (!shapeWithText.text || typeof shapeWithText.text.content !== 'string') {\n return false\n }\n\n shapeWithText.text.content = updateHtmlContent(shapeWithText.text.content, text)\n return true\n}\n\nexport const applyCoverData = (slide: TemplateJsonSlide, data: BackendCoverData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n}\n\nexport const applyContentsData = (\n slide: TemplateJsonSlide,\n data: BackendContentsData\n) => {\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n items.forEach((element, index) => {\n const text = data.items[index]\n if (text) setElementText(element, text)\n })\n}\n\nexport const applyTransitionData = (\n slide: TemplateJsonSlide,\n data: BackendTransitionData,\n sectionIndex: number\n) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n const partNumber = slide.elements.find(\n element => element.type === 'text' && element.textType === 'partNumber'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n const formattedSectionIndex = `${sectionIndex}`.padStart(2, '0')\n if (partNumber) {\n setElementText(partNumber, formattedSectionIndex)\n } else {\n setShapeTextByType(slide, 'partNumber', formattedSectionIndex)\n }\n}\n\nexport const applyContentData = (slide: TemplateJsonSlide, data: BackendContentData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n if (title) setElementText(title, data.title)\n\n const itemTitles = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'itemTitle'\n )\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n\n data.items.forEach((item, index) => {\n const titleEl = itemTitles[index]\n const textEl = items[index]\n if (titleEl) setElementText(titleEl, item.title)\n if (textEl) setElementText(textEl, item.text)\n })\n}\n","import type { CustomSlide, TemplateJson, TemplateJsonSlide } from '../types'\nimport {\n applyContentData,\n applyContentsData,\n applyCoverData,\n applyTransitionData\n} from './slide-appliers'\n\nconst cloneSlide = (slide: TemplateJsonSlide): TemplateJsonSlide =>\n JSON.parse(JSON.stringify(slide)) as TemplateJsonSlide\n\nfunction normalizeLabel (value: string): string {\n return value\n .replace(/\\s+/g, ' ')\n .replace(/[,。、“”‘’:;!?【】()《》〈〉·,.:;!?()[\\]{}\"'`~\\-_/\\\\]/g, '')\n .trim()\n .toLowerCase()\n}\n\nfunction resolveTransitionIndex (\n customSlides: CustomSlide[],\n currentSlideIndex: number,\n transitionTitle: string,\n fallbackIndex: number\n): number {\n const normalizedTitle = normalizeLabel(transitionTitle)\n if (!normalizedTitle) return fallbackIndex\n\n const contentsItems = customSlides\n .slice(0, currentSlideIndex + 1)\n .filter((slide): slide is Extract<CustomSlide, { type: 'contents' }> => slide.type === 'contents')\n .flatMap(slide => slide.data.items)\n\n for (let index = 0; index < contentsItems.length; index += 1) {\n const normalizedItem = normalizeLabel(contentsItems[index])\n if (!normalizedItem) continue\n if (\n normalizedItem === normalizedTitle ||\n normalizedItem.includes(normalizedTitle) ||\n normalizedTitle.includes(normalizedItem)\n ) {\n return index + 1\n }\n }\n\n return fallbackIndex\n}\n\nexport const applyCustomContentToTemplate = (\n template: TemplateJson,\n CustomSlides: CustomSlide[]\n): TemplateJson => {\n const grouped = template.slides.reduce<Record<string, TemplateJsonSlide[]>>(\n (acc, slide) => {\n const key = slide.type || 'default'\n if (!acc[key]) acc[key] = []\n acc[key].push(slide)\n return acc\n },\n {}\n )\n\n const usage = new Map<string, number>()\n const getTextTypeCount = (slide: TemplateJsonSlide, textType: string) =>\n slide.elements.filter(\n element => element.type === 'text' && element.textType === textType\n ).length\n\n const getContentCapacity = (slide: TemplateJsonSlide) => {\n const titleSlots = getTextTypeCount(slide, 'itemTitle')\n const itemSlots = getTextTypeCount(slide, 'item')\n return Math.min(titleSlots, itemSlots)\n }\n\n const pickFromPool = (key: string, pool: TemplateJsonSlide[]) => {\n const index = usage.get(key) ?? 0\n usage.set(key, index + 1)\n return cloneSlide(pool[index % pool.length])\n }\n\n const pickSlide = (type: string, desiredCount?: number) => {\n const pool = grouped[type] || grouped.default || template.slides\n if (desiredCount == null || pool.length === 1) {\n return pickFromPool(type, pool)\n }\n\n const scored = pool.map(slide => {\n const capacity =\n type === 'content'\n ? getContentCapacity(slide)\n : getTextTypeCount(slide, 'item')\n return { slide, capacity }\n })\n const eligible = scored.filter(item => item.capacity >= desiredCount)\n if (eligible.length > 0) {\n const minCapacity = Math.min(...eligible.map(item => item.capacity))\n const best = eligible\n .filter(item => item.capacity === minCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, best)\n }\n const maxCapacity = Math.max(...scored.map(item => item.capacity))\n const fallback = scored\n .filter(item => item.capacity === maxCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, fallback)\n }\n\n let transitionIndex = 0\n const slides = CustomSlides.map((item, index) => {\n const desiredCount =\n item.type === 'contents'\n ? item.data.items.length\n : item.type === 'content'\n ? item.data.items.length\n : undefined\n const slide = pickSlide(item.type, desiredCount)\n if (item.type === 'cover') {\n applyCoverData(slide, item.data)\n } else if (item.type === 'contents') {\n applyContentsData(slide, item.data)\n } else if (item.type === 'transition') {\n transitionIndex += 1\n const partNumber = resolveTransitionIndex(\n CustomSlides,\n index,\n item.data.title,\n transitionIndex\n )\n applyTransitionData(slide, item.data, partNumber)\n } else if (item.type === 'content') {\n applyContentData(slide, item.data)\n }\n return slide\n })\n\n return {\n ...template,\n slides\n }\n}\n","import { parseDocument } from 'json2pptx-schema'\nimport type { Deck, PptxCustomThemeInput } from '../types'\nimport { applyTheme2Json } from './theme-applier'\n\nexport function applyCustomTheme (\n deck: Deck,\n input: PptxCustomThemeInput\n): Deck {\n const normalizedDeck = parseDocument(deck) as unknown as Deck\n const updated = applyTheme2Json(normalizedDeck, input)\n return parseDocument(updated) as unknown as Deck\n}\n\nexport { applyTheme2Json }\n","import type { ColorMapping, RGB } from './types'\n\nexport function normalizeHexColor (value: string): string | null {\n const raw = value.trim()\n const withHash = raw.startsWith('#') ? raw.slice(1) : raw\n if (withHash.length !== 3 && withHash.length !== 6) return null\n if (!/^[0-9a-fA-F]+$/.test(withHash)) return null\n const expanded =\n withHash.length === 3\n ? withHash\n .split('')\n .map((char) => char + char)\n .join('')\n : withHash\n return `#${expanded.toUpperCase()}`\n}\n\nexport function parseColorToRgb (\n value: string\n): (RGB & { alpha?: number }) | null {\n const hex = normalizeHexColor(value)\n if (hex) {\n const raw = hex.slice(1)\n const r = Number.parseInt(raw.slice(0, 2), 16)\n const g = Number.parseInt(raw.slice(2, 4), 16)\n const b = Number.parseInt(raw.slice(4, 6), 16)\n return { r, g, b }\n }\n\n const match = value.match(\n /rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)/i\n )\n if (!match) return null\n const r = Math.round(Number(match[1]))\n const g = Math.round(Number(match[2]))\n const b = Math.round(Number(match[3]))\n const alpha = match[4] !== undefined ? Number(match[4]) : undefined\n return {\n r,\n g,\n b,\n ...(Number.isFinite(alpha) ? { alpha } : {})\n }\n}\n\nexport function normalizeThemeColor (value: string): string | null {\n const hex = normalizeHexColor(value)\n if (hex) return hex\n const parsed = parseColorToRgb(value)\n if (!parsed) return null\n if (parsed.alpha !== undefined) {\n return `rgba(${parsed.r},${parsed.g},${parsed.b},${parsed.alpha})`\n }\n return `rgb(${parsed.r},${parsed.g},${parsed.b})`\n}\n\nexport function isPureColorString (value: string): boolean {\n const trimmed = value.trim()\n if (!trimmed) return false\n if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(trimmed)) return true\n return /^rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)$/i.test(\n trimmed\n )\n}\n\nfunction normalizeColorKey (value?: string): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n const parsed = parseColorToRgb(trimmed)\n if (parsed) {\n return `${parsed.r},${parsed.g},${parsed.b},${parsed.alpha ?? 'none'}`\n }\n const hex = normalizeHexColor(trimmed)\n if (hex) return hex\n return trimmed.toLowerCase()\n}\n\nexport function colorsEqual (a: string, b: string): boolean {\n const aKey = normalizeColorKey(a)\n const bKey = normalizeColorKey(b)\n if (!aKey || !bKey) return false\n return aKey === bKey\n}\n\nexport function isWhiteColor (value?: string): boolean {\n const key = normalizeColorKey(value)\n if (!key) return false\n return (\n key === '#FFFFFF' ||\n key === '255,255,255,none' ||\n key === '255,255,255,1'\n )\n}\n\nexport function rgbToString (rgb: RGB): string {\n return `rgb(${rgb.r},${rgb.g},${rgb.b})`\n}\n\nexport function findMappingForColor (\n value: string,\n mappings: ColorMapping[]\n): ColorMapping | undefined {\n const parsed = parseColorToRgb(value)\n if (!parsed) return undefined\n return mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n}\n","import { normalizeHexColor, parseColorToRgb } from './color-utils'\nimport type { ColorMapping } from './types'\n\nexport function buildColorMappings (\n previous: string[],\n next: string[]\n): ColorMapping[] {\n const mappings: ColorMapping[] = []\n const length = Math.min(previous.length, next.length)\n for (let i = 0; i < length; i += 1) {\n const fromParsed = parseColorToRgb(previous[i])\n const toParsed = parseColorToRgb(next[i])\n if (!fromParsed || !toParsed) continue\n const toHex = normalizeHexColor(next[i]) ?? undefined\n mappings.push({\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n })\n }\n return mappings\n}\n\nexport function buildSingleMapping (\n from?: string,\n to?: string\n): ColorMapping | null {\n if (!from || !to) return null\n const fromParsed = parseColorToRgb(from)\n const toParsed = parseColorToRgb(to)\n if (!fromParsed || !toParsed) return null\n const toHex = normalizeHexColor(to) ?? undefined\n return {\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n }\n}\n","import type { Slide, SlideElement } from '../types'\nimport {\n findMappingForColor,\n isPureColorString,\n normalizeThemeColor,\n parseColorToRgb,\n rgbToString\n} from './color-utils'\nimport type { ColorMapping } from './types'\n\nfunction applyFontColorToHtml (value: string, fontColor: string): string {\n if (!value || !fontColor) return value\n const normalized = normalizeThemeColor(fontColor) ?? fontColor\n const hasStyleColor = /\\bcolor\\s*:/i.test(value)\n if (hasStyleColor) {\n return value.replace(/color\\s*:\\s*([^;\"']+)/gi, () => `color: ${normalized}`)\n }\n return value.replace(\n /(<[^>]+style\\s*=\\s*[\"'])([^\"']*)([\"'])/gi,\n (_match, start, styles, end) => {\n if (/\\bcolor\\s*:/i.test(styles)) return _match\n const nextStyles = styles.trim()\n ? `${styles.trim()}; color: ${normalized}`\n : `color: ${normalized}`\n return `${start}${nextStyles}${end}`\n }\n )\n}\n\nfunction replaceColorValue (value: string, mappings: ColorMapping[]): string {\n const mapping = findMappingForColor(value, mappings)\n if (!mapping) return value\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n if (parsed.alpha !== undefined) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceRgbaString (value: string, mappings: ColorMapping[]): string {\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n const mapping = mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n if (!mapping) return value\n if (parsed.alpha !== undefined || value.toLowerCase().startsWith('rgba')) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha ?? 1})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceColorsInText (value: string, mappings: ColorMapping[]): string {\n let next = value\n next = next.replace(/#([0-9a-f]{3}|[0-9a-f]{6})/gi, (match) => {\n const mapping = findMappingForColor(match, mappings)\n if (!mapping) return match\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n })\n next = next.replace(/rgba?\\([^)]*\\)/gi, (match) =>\n replaceRgbaString(match, mappings)\n )\n return next\n}\n\nfunction replaceColorsDeep (value: unknown, mappings: ColorMapping[]): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim()\n const pureColor = isPureColorString(trimmed)\n if (pureColor) {\n const replaced = replaceColorValue(trimmed, mappings)\n return value === trimmed ? replaced : value.replace(trimmed, replaced)\n }\n return replaceColorsInText(value, mappings)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => replaceColorsDeep(item, mappings))\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n const next: Record<string, unknown> = {}\n for (const [key, item] of entries) {\n next[key] = replaceColorsDeep(item, mappings)\n }\n return next\n }\n\n return value\n}\n\nfunction replaceTextElementColors (\n element: SlideElement,\n fontMappings: ColorMapping[],\n fontColor: string\n): SlideElement {\n const next = replaceColorsDeep(element, fontMappings) as SlideElement\n const normalizedFontColor = normalizeThemeColor(fontColor) ?? fontColor\n const withDefault =\n normalizedFontColor && 'defaultColor' in next\n ? { ...next, defaultColor: normalizedFontColor }\n : next\n if (!('content' in withDefault) || typeof withDefault.content !== 'string') {\n return withDefault\n }\n return {\n ...withDefault,\n content: applyFontColorToHtml(withDefault.content, normalizedFontColor)\n }\n}\n\nexport function replaceSlideColors (\n slide: Slide,\n themeMappings: ColorMapping[],\n fontMappings: ColorMapping[],\n fontColor: string\n): Slide {\n const { elements, ...rest } = slide\n const nextSlide = replaceColorsDeep(rest, themeMappings) as Slide\n if (!elements) return nextSlide\n\n const nextElements: SlideElement[] = elements.map((element) => {\n if (element && typeof element === 'object' && element.type === 'text') {\n return replaceTextElementColors(element, fontMappings, fontColor)\n }\n return replaceColorsDeep(element, themeMappings) as SlideElement\n })\n\n return { ...nextSlide, elements: nextElements }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { colorsEqual, isWhiteColor } from './color-utils'\nimport { buildColorMappings, buildSingleMapping } from './mappings'\nimport { replaceSlideColors } from './replacers'\n\nexport function applyTheme2Json (deck: Deck, update: PptxCustomThemeInput): Deck {\n const previousTheme = deck.theme ?? {}\n const themeColors = update.themeColors.slice(0, 6)\n const themeMappings = buildColorMappings(\n previousTheme.themeColors ?? [],\n themeColors\n )\n const fontMapping = buildSingleMapping(\n previousTheme.fontColor,\n update.fontColor\n )\n const fontMappings = fontMapping ? [fontMapping] : []\n\n const nextBackground = update.backgroundColor ?? previousTheme.backgroundColor\n const prevBackground = previousTheme.backgroundColor\n const slides = deck.slides?.map((slide) => {\n const nextSlide = replaceSlideColors(\n slide,\n themeMappings,\n fontMappings,\n update.fontColor\n )\n if (!nextBackground) return nextSlide\n const currentColor = nextSlide.background?.color\n const shouldUpdate =\n !currentColor ||\n (prevBackground && colorsEqual(currentColor, prevBackground)) ||\n (!prevBackground && isWhiteColor(currentColor))\n if (!shouldUpdate) return nextSlide\n return {\n ...nextSlide,\n background: {\n ...(nextSlide.background ?? {}),\n type: nextSlide.background?.type ?? 'solid',\n color: nextBackground\n }\n }\n })\n\n return {\n ...deck,\n theme: {\n ...previousTheme,\n themeColors,\n fontColor: update.fontColor,\n backgroundColor: update.backgroundColor ?? previousTheme.backgroundColor\n },\n slides\n }\n}\n"],"mappings":"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","names":["import_json2pptx_schema","r","g","b"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/custom-content/index.ts","../src/custom-content/parser.ts","../src/custom-content/html.ts","../src/custom-content/slide-appliers.ts","../src/custom-content/template-builder.ts","../src/custom-theme/index.ts","../src/custom-theme/color-utils.ts","../src/custom-theme/mappings.ts","../src/custom-theme/replacers.ts","../src/custom-theme/theme-applier.ts"],"sourcesContent":["import { applyCustomContent, parseCustomContent, applyCustomContentToTemplate } from './custom-content/index'\nimport { applyCustomTheme } from './custom-theme/index'\n\nexport {\n parseCustomContent,\n applyCustomContent,\n applyCustomContentToTemplate,\n\n applyCustomTheme,\n}\n\nexport type {\n CustomSlide,\n Deck,\n PptxCustomContentInput,\n PptxCustomOptions,\n PptxCustomThemeInput,\n TemplateJson,\n TemplateJsonElement,\n TemplateJsonSlide,\n TemplateJsonTheme\n} from './types'\n","import { parseDocument } from 'json2pptx-schema'\nimport type {\n PptxCustomContentInput,\n TemplateJson,\n TemplateJsonElement,\n TemplateJsonImage\n} from '../types'\nimport { parseCustomContent } from './parser'\nimport { applyCustomContentToTemplate } from './template-builder'\n\nconst FALLBACK_SLIDE_WIDTH = 1000\nconst FALLBACK_SLIDE_HEIGHT = 562.5\nconst LOGO_MARGIN_X = 24\nconst LOGO_MARGIN_Y = 18\nconst LOGO_MAX_WIDTH_RATIO = 0.34\nconst LOGO_MAX_HEIGHT_RATIO = 0.16\n\nfunction isLogoImageElement (\n element: TemplateJsonElement\n): element is TemplateJsonImage {\n return element.type === 'image' && element.imageType === 'logo'\n}\n\nfunction fitSize (\n width: number,\n height: number,\n maxWidth: number,\n maxHeight: number\n): { width: number; height: number } {\n const safeWidth = width > 0 ? width : maxWidth\n const safeHeight = height > 0 ? height : maxHeight\n const scale = Math.min(maxWidth / safeWidth, maxHeight / safeHeight)\n return {\n width: safeWidth * scale,\n height: safeHeight * scale\n }\n}\n\nfunction normalizeLogoElements (deck: TemplateJson): TemplateJson {\n const slideWidth = deck.width || FALLBACK_SLIDE_WIDTH\n const slideHeight = deck.height || FALLBACK_SLIDE_HEIGHT\n const logoMaxWidth = slideWidth * LOGO_MAX_WIDTH_RATIO\n const logoMaxHeight = slideHeight * LOGO_MAX_HEIGHT_RATIO\n\n const slides = deck.slides.map(slide => {\n let changed = false\n const elements = slide.elements.map(element => {\n if (!isLogoImageElement(element)) return element\n\n const size = fitSize(\n element.width ?? logoMaxWidth,\n element.height ?? logoMaxHeight,\n logoMaxWidth,\n logoMaxHeight\n )\n const isLeft = (element.left ?? 0) < slideWidth / 2\n const left = isLeft\n ? LOGO_MARGIN_X\n : Math.max(LOGO_MARGIN_X, slideWidth - size.width - LOGO_MARGIN_X)\n const top = LOGO_MARGIN_Y\n const { clip: _clip, ...rest } = element\n\n changed = true\n return {\n ...rest,\n left,\n top,\n width: size.width,\n height: size.height,\n fixedRatio: true\n }\n })\n\n return changed ? { ...slide, elements } : slide\n })\n\n return { ...deck, slides }\n}\n\nexport function applyCustomContent (\n template: TemplateJson,\n input: PptxCustomContentInput\n): TemplateJson {\n const normalizedTemplate = parseDocument(template) as unknown as TemplateJson\n const CustomSlides = typeof input === 'string' ? parseCustomContent(input) : input\n const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides)\n const withNormalizedLogo = normalizeLogoElements(updated)\n return parseDocument(withNormalizedLogo) as unknown as TemplateJson\n}\n\nexport { parseCustomContent, applyCustomContentToTemplate }\n","import type { BackendContentItem, CustomSlide } from '../types'\n\ntype UnknownRecord = Record<string, unknown>\n\nconst isRecord = (value: unknown): value is UnknownRecord =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst asString = (value: unknown): string | null =>\n typeof value === 'string' ? value : null\n\nconst asStringArray = (value: unknown): string[] | null => {\n if (!Array.isArray(value)) return null\n const normalized = value\n .map(item => asString(item))\n .filter((item): item is string => item !== null)\n return normalized.length === value.length ? normalized : null\n}\n\nconst normalizeType = (value: unknown): CustomSlide['type'] | null => {\n const raw = asString(value)?.trim().toLowerCase()\n if (!raw) return null\n if (raw === 'agenda') return 'contents'\n if (raw === 'section') return 'transition'\n if (raw === 'ending') return 'end'\n if (\n raw === 'cover' ||\n raw === 'contents' ||\n raw === 'transition' ||\n raw === 'content' ||\n raw === 'end'\n ) {\n return raw\n }\n return null\n}\n\nconst normalizeContentItems = (value: unknown): BackendContentItem[] | null => {\n if (!Array.isArray(value)) return null\n const normalized: BackendContentItem[] = []\n for (const item of value) {\n if (!isRecord(item)) return null\n const title = asString(item.title)\n const text = asString(item.text)\n if (title == null || text == null) return null\n normalized.push({ title, text })\n }\n return normalized\n}\n\nconst normalizeSlide = (value: unknown): CustomSlide | null => {\n if (!isRecord(value)) return null\n const type = normalizeType(value.type)\n if (!type) return null\n\n const rawData = isRecord(value.data) ? value.data : {}\n\n if (type === 'cover') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'contents') {\n const items = asStringArray(rawData.items)\n if (!items) return null\n return { type, data: { items } }\n }\n\n if (type === 'transition') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'content') {\n const title = asString(rawData.title)\n const items = normalizeContentItems(rawData.items)\n if (title == null || !items) return null\n return { type, data: { title, items } }\n }\n\n return { type }\n}\n\nconst parseNdJsonSlides = (raw: string): unknown[] =>\n raw\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => JSON.parse(line) as unknown)\n\nconst parseStructuredSlides = (raw: string): unknown[] | null => {\n const trimmed = raw.trim()\n if (!trimmed) return []\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed) as unknown\n } catch {\n return null\n }\n if (Array.isArray(parsed)) return parsed\n if (!isRecord(parsed)) return null\n if (Array.isArray(parsed.slides)) return parsed.slides\n if ('type' in parsed) return [parsed]\n return null\n}\n\nexport const parseCustomContent = (raw: string): CustomSlide[] => {\n const candidates = parseStructuredSlides(raw) ?? parseNdJsonSlides(raw)\n const slides = candidates\n .map(item => normalizeSlide(item))\n .filter((item): item is CustomSlide => item !== null)\n\n if (slides.length !== candidates.length) {\n throw new Error('Invalid custom content format')\n }\n return slides\n}\n","import type { TemplateJsonElement } from '../types'\n\nexport const updateHtmlContent = (html: string, text: string) => {\n if (typeof DOMParser === 'undefined') {\n return `<p>${text}</p>`\n }\n const parser = new DOMParser()\n const doc = parser.parseFromString(html, 'text/html')\n const spans = Array.from(doc.querySelectorAll('span'))\n if (spans.length > 0) {\n spans.forEach((span, index) => {\n span.textContent = index === 0 ? text : ''\n })\n } else {\n const paragraph = doc.querySelector('p')\n if (paragraph) {\n paragraph.textContent = text\n } else {\n doc.body.textContent = text\n }\n }\n return doc.body.innerHTML\n}\n\nexport const setElementText = (element: TemplateJsonElement, text: string) => {\n if (element.type !== 'text') return\n element.content = updateHtmlContent(element.content, text)\n}\n","import type {\n BackendContentData,\n BackendContentsData,\n BackendCoverData,\n BackendTransitionData,\n TemplateJsonSlide\n} from '../types'\nimport { setElementText, updateHtmlContent } from './html'\n\nfunction setShapeTextByType (\n slide: TemplateJsonSlide,\n textType: string,\n text: string\n): boolean {\n const shape = slide.elements.find((element) => {\n if (element.type !== 'shape') return false\n const maybeShape = element as unknown as {\n text?: { type?: string; content?: string }\n }\n return maybeShape.text?.type === textType\n })\n\n if (!shape) return false\n\n const shapeWithText = shape as unknown as {\n text?: { type?: string; content?: string }\n }\n if (!shapeWithText.text || typeof shapeWithText.text.content !== 'string') {\n return false\n }\n\n shapeWithText.text.content = updateHtmlContent(shapeWithText.text.content, text)\n return true\n}\n\nexport const applyCoverData = (slide: TemplateJsonSlide, data: BackendCoverData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n}\n\nexport const applyContentsData = (\n slide: TemplateJsonSlide,\n data: BackendContentsData\n) => {\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n items.forEach((element, index) => {\n const text = data.items[index]\n if (text) setElementText(element, text)\n })\n}\n\nexport const applyTransitionData = (\n slide: TemplateJsonSlide,\n data: BackendTransitionData,\n sectionIndex: number\n) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n const partNumber = slide.elements.find(\n element => element.type === 'text' && element.textType === 'partNumber'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n const formattedSectionIndex = `${sectionIndex}`.padStart(2, '0')\n if (partNumber) {\n setElementText(partNumber, formattedSectionIndex)\n } else {\n setShapeTextByType(slide, 'partNumber', formattedSectionIndex)\n }\n}\n\nexport const applyContentData = (slide: TemplateJsonSlide, data: BackendContentData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n if (title) setElementText(title, data.title)\n\n const itemTitles = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'itemTitle'\n )\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n\n data.items.forEach((item, index) => {\n const titleEl = itemTitles[index]\n const textEl = items[index]\n if (titleEl) setElementText(titleEl, item.title)\n if (textEl) setElementText(textEl, item.text)\n })\n}\n","import type { CustomSlide, TemplateJson, TemplateJsonSlide } from '../types'\nimport {\n applyContentData,\n applyContentsData,\n applyCoverData,\n applyTransitionData\n} from './slide-appliers'\n\nconst cloneSlide = (slide: TemplateJsonSlide): TemplateJsonSlide =>\n JSON.parse(JSON.stringify(slide)) as TemplateJsonSlide\n\nfunction normalizeLabel (value: string): string {\n return value\n .replace(/\\s+/g, ' ')\n .replace(/[,。、“”‘’:;!?【】()《》〈〉·,.:;!?()[\\]{}\"'`~\\-_/\\\\]/g, '')\n .trim()\n .toLowerCase()\n}\n\nfunction resolveTransitionIndex (\n customSlides: CustomSlide[],\n currentSlideIndex: number,\n transitionTitle: string,\n fallbackIndex: number\n): number {\n const normalizedTitle = normalizeLabel(transitionTitle)\n if (!normalizedTitle) return fallbackIndex\n\n const contentsItems = customSlides\n .slice(0, currentSlideIndex + 1)\n .filter((slide): slide is Extract<CustomSlide, { type: 'contents' }> => slide.type === 'contents')\n .flatMap(slide => slide.data.items)\n\n for (let index = 0; index < contentsItems.length; index += 1) {\n const normalizedItem = normalizeLabel(contentsItems[index])\n if (!normalizedItem) continue\n if (\n normalizedItem === normalizedTitle ||\n normalizedItem.includes(normalizedTitle) ||\n normalizedTitle.includes(normalizedItem)\n ) {\n return index + 1\n }\n }\n\n return fallbackIndex\n}\n\nexport const applyCustomContentToTemplate = (\n template: TemplateJson,\n CustomSlides: CustomSlide[]\n): TemplateJson => {\n const grouped = template.slides.reduce<Record<string, TemplateJsonSlide[]>>(\n (acc, slide) => {\n const key = slide.type || 'default'\n if (!acc[key]) acc[key] = []\n acc[key].push(slide)\n return acc\n },\n {}\n )\n\n const usage = new Map<string, number>()\n const getTextTypeCount = (slide: TemplateJsonSlide, textType: string) =>\n slide.elements.filter(\n element => element.type === 'text' && element.textType === textType\n ).length\n\n const getContentCapacity = (slide: TemplateJsonSlide) => {\n const titleSlots = getTextTypeCount(slide, 'itemTitle')\n const itemSlots = getTextTypeCount(slide, 'item')\n return Math.min(titleSlots, itemSlots)\n }\n\n const pickFromPool = (key: string, pool: TemplateJsonSlide[]) => {\n const index = usage.get(key) ?? 0\n usage.set(key, index + 1)\n return cloneSlide(pool[index % pool.length])\n }\n\n const pickSlide = (type: string, desiredCount?: number) => {\n const pool = grouped[type] || grouped.default || template.slides\n if (desiredCount == null || pool.length === 1) {\n return pickFromPool(type, pool)\n }\n\n const scored = pool.map(slide => {\n const capacity =\n type === 'content'\n ? getContentCapacity(slide)\n : getTextTypeCount(slide, 'item')\n return { slide, capacity }\n })\n const eligible = scored.filter(item => item.capacity >= desiredCount)\n if (eligible.length > 0) {\n const minCapacity = Math.min(...eligible.map(item => item.capacity))\n const best = eligible\n .filter(item => item.capacity === minCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, best)\n }\n const maxCapacity = Math.max(...scored.map(item => item.capacity))\n const fallback = scored\n .filter(item => item.capacity === maxCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, fallback)\n }\n\n let transitionIndex = 0\n const slides = CustomSlides.map((item, index) => {\n const desiredCount =\n item.type === 'contents'\n ? item.data.items.length\n : item.type === 'content'\n ? item.data.items.length\n : undefined\n const slide = pickSlide(item.type, desiredCount)\n if (item.type === 'cover') {\n applyCoverData(slide, item.data)\n } else if (item.type === 'contents') {\n applyContentsData(slide, item.data)\n } else if (item.type === 'transition') {\n transitionIndex += 1\n const partNumber = resolveTransitionIndex(\n CustomSlides,\n index,\n item.data.title,\n transitionIndex\n )\n applyTransitionData(slide, item.data, partNumber)\n } else if (item.type === 'content') {\n applyContentData(slide, item.data)\n }\n return slide\n })\n\n return {\n ...template,\n slides\n }\n}\n","import { parseDocument } from 'json2pptx-schema'\nimport type {\n Deck,\n PptxCustomThemeInput,\n Slide,\n SlideElement,\n ThemeLogoPosition,\n ThemeScope,\n ThemeScopeKey\n} from '../types'\nimport { parseColorToRgb } from './color-utils'\nimport { applyTheme2Json } from './theme-applier'\n\nconst FALLBACK_SLIDE_WIDTH = 1000\nconst FALLBACK_SLIDE_HEIGHT = 562.5\nconst LOGO_MARGIN_X = 24\nconst LOGO_MARGIN_Y = 18\nconst LOGO_MAX_WIDTH_RATIO = 0.34\nconst LOGO_MAX_HEIGHT_RATIO = 0.16\nconst DEFAULT_LOGO_ASPECT_RATIO = 3.2\n\nfunction mapSlideTypeToScopeKey (type?: string): ThemeScopeKey | null {\n const normalized = type?.trim().toLowerCase()\n if (!normalized) return null\n\n if (normalized === 'cover') return 'cover'\n if (normalized === 'contents' || normalized === 'agenda') return 'contents'\n if (normalized === 'transition' || normalized === 'section') return 'transition'\n if (normalized === 'content') return 'content'\n if (normalized === 'end' || normalized === 'ending') return 'end'\n\n return null\n}\n\nfunction isSlideInScope (slide: Slide, scope: ThemeScope): boolean {\n const key = mapSlideTypeToScopeKey(slide.type)\n if (!key) return false\n return Boolean(scope[key])\n}\n\nfunction createElementId (prefix: string, slideIndex: number): string {\n const random = Math.random().toString(36).slice(2, 10)\n return `${prefix}-${slideIndex}-${random}`\n}\n\nfunction toHalfOpacityColor (value: string): string {\n const rgb = parseColorToRgb(value)\n if (!rgb) return value\n return `rgba(${rgb.r},${rgb.g},${rgb.b},0.5)`\n}\n\nfunction buildBackgroundElement (\n src: string,\n slideWidth: number,\n slideHeight: number,\n slideIndex: number\n): SlideElement {\n return {\n type: 'image',\n id: createElementId('background', slideIndex),\n src,\n width: slideWidth,\n height: slideHeight,\n left: 0,\n top: 0,\n fixedRatio: true,\n rotate: 0,\n imageType: 'background',\n filters: {\n opacity: '100%'\n }\n }\n}\n\nfunction buildLogoElement (\n src: string,\n slideWidth: number,\n slideHeight: number,\n position: ThemeLogoPosition,\n slideIndex: number,\n logoWidth?: number,\n logoHeight?: number\n): SlideElement {\n const aspectRatio = resolveLogoAspectRatio(logoWidth, logoHeight)\n const maxWidth = slideWidth * LOGO_MAX_WIDTH_RATIO\n const maxHeight = slideHeight * LOGO_MAX_HEIGHT_RATIO\n let width = maxWidth\n let height = width / aspectRatio\n if (height > maxHeight) {\n height = maxHeight\n width = height * aspectRatio\n }\n const left =\n position === 'left'\n ? LOGO_MARGIN_X\n : Math.max(LOGO_MARGIN_X, slideWidth - width - LOGO_MARGIN_X)\n\n return {\n type: 'image',\n id: createElementId('logo', slideIndex),\n src,\n width,\n height,\n left,\n top: LOGO_MARGIN_Y,\n fixedRatio: true,\n rotate: 0,\n imageType: 'logo'\n }\n}\n\nfunction resolveLogoAspectRatio (\n width?: number,\n height?: number\n): number {\n if (\n typeof width === 'number' &&\n typeof height === 'number' &&\n width > 0 &&\n height > 0\n ) {\n return width / height\n }\n return DEFAULT_LOGO_ASPECT_RATIO\n}\n\nfunction replaceScopedMedia (deck: Deck, input: PptxCustomThemeInput): Deck {\n if (!deck.slides?.length) return deck\n\n const slideWidth = deck.width ?? FALLBACK_SLIDE_WIDTH\n const slideHeight = deck.height ?? FALLBACK_SLIDE_HEIGHT\n const backgroundInput = input.backgroundImage\n const logoInput = input.logoImage\n const shouldClearBackground = Boolean(input.clearBackgroundImage)\n const shouldClearLogo = Boolean(input.clearLogoImage || shouldClearBackground)\n\n if (\n !backgroundInput?.src &&\n !logoInput?.src &&\n !shouldClearBackground &&\n !shouldClearLogo\n ) {\n return deck\n }\n\n const slides = deck.slides.map((slide, slideIndex) => {\n let nextElements = slide.elements ? [...slide.elements] : []\n let nextBackground = slide.background\n let changed = false\n\n if (shouldClearBackground) {\n const before = nextElements.length\n nextElements = nextElements.filter(\n element => !(element.type === 'image' && element.imageType === 'background')\n )\n if (nextElements.length !== before) {\n changed = true\n if (input.backgroundColor) {\n nextBackground = {\n ...(nextBackground ?? {}),\n type: 'solid',\n color: input.backgroundColor\n }\n }\n }\n }\n\n if (shouldClearLogo) {\n const before = nextElements.length\n nextElements = nextElements.filter(\n element => !(element.type === 'image' && element.imageType === 'logo')\n )\n if (nextElements.length !== before) {\n changed = true\n }\n }\n\n if (backgroundInput?.src && isSlideInScope(slide, backgroundInput.scope)) {\n const withoutBackground = nextElements.filter(\n element => !(element.type === 'image' && element.imageType === 'background')\n )\n nextElements = [\n buildBackgroundElement(\n backgroundInput.src,\n slideWidth,\n slideHeight,\n slideIndex\n ),\n ...withoutBackground\n ]\n changed = true\n\n if (input.backgroundColor) {\n nextBackground = {\n ...(nextBackground ?? {}),\n type: 'solid',\n color: toHalfOpacityColor(input.backgroundColor)\n }\n }\n }\n\n if (logoInput?.src && isSlideInScope(slide, logoInput.scope)) {\n const withoutLogo = nextElements.filter(\n element => !(element.type === 'image' && element.imageType === 'logo')\n )\n nextElements = [\n ...withoutLogo,\n buildLogoElement(\n logoInput.src,\n slideWidth,\n slideHeight,\n logoInput.position,\n slideIndex,\n logoInput.width,\n logoInput.height\n )\n ]\n changed = true\n }\n\n if (!changed && nextBackground === slide.background) return slide\n\n return {\n ...slide,\n ...(changed ? { elements: nextElements } : {}),\n ...(nextBackground ? { background: nextBackground } : {})\n }\n })\n\n return { ...deck, slides }\n}\n\nexport function applyCustomTheme (\n deck: Deck,\n input: PptxCustomThemeInput\n): Deck {\n const normalizedDeck = parseDocument(deck) as unknown as Deck\n const withColors = applyTheme2Json(normalizedDeck, input)\n const withMedia = replaceScopedMedia(withColors, input)\n return parseDocument(withMedia) as unknown as Deck\n}\n\nexport { applyTheme2Json }\n","import type { ColorMapping, RGB } from './types'\n\nexport function normalizeHexColor (value: string): string | null {\n const raw = value.trim()\n const withHash = raw.startsWith('#') ? raw.slice(1) : raw\n if (withHash.length !== 3 && withHash.length !== 6) return null\n if (!/^[0-9a-fA-F]+$/.test(withHash)) return null\n const expanded =\n withHash.length === 3\n ? withHash\n .split('')\n .map((char) => char + char)\n .join('')\n : withHash\n return `#${expanded.toUpperCase()}`\n}\n\nexport function parseColorToRgb (\n value: string\n): (RGB & { alpha?: number }) | null {\n const hex = normalizeHexColor(value)\n if (hex) {\n const raw = hex.slice(1)\n const r = Number.parseInt(raw.slice(0, 2), 16)\n const g = Number.parseInt(raw.slice(2, 4), 16)\n const b = Number.parseInt(raw.slice(4, 6), 16)\n return { r, g, b }\n }\n\n const match = value.match(\n /rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)/i\n )\n if (!match) return null\n const r = Math.round(Number(match[1]))\n const g = Math.round(Number(match[2]))\n const b = Math.round(Number(match[3]))\n const alpha = match[4] !== undefined ? Number(match[4]) : undefined\n return {\n r,\n g,\n b,\n ...(Number.isFinite(alpha) ? { alpha } : {})\n }\n}\n\nexport function normalizeThemeColor (value: string): string | null {\n const hex = normalizeHexColor(value)\n if (hex) return hex\n const parsed = parseColorToRgb(value)\n if (!parsed) return null\n if (parsed.alpha !== undefined) {\n return `rgba(${parsed.r},${parsed.g},${parsed.b},${parsed.alpha})`\n }\n return `rgb(${parsed.r},${parsed.g},${parsed.b})`\n}\n\nexport function isPureColorString (value: string): boolean {\n const trimmed = value.trim()\n if (!trimmed) return false\n if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(trimmed)) return true\n return /^rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)$/i.test(\n trimmed\n )\n}\n\nfunction normalizeColorKey (value?: string): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n const parsed = parseColorToRgb(trimmed)\n if (parsed) {\n return `${parsed.r},${parsed.g},${parsed.b},${parsed.alpha ?? 'none'}`\n }\n const hex = normalizeHexColor(trimmed)\n if (hex) return hex\n return trimmed.toLowerCase()\n}\n\nexport function colorsEqual (a: string, b: string): boolean {\n const aKey = normalizeColorKey(a)\n const bKey = normalizeColorKey(b)\n if (!aKey || !bKey) return false\n return aKey === bKey\n}\n\nexport function isWhiteColor (value?: string): boolean {\n const key = normalizeColorKey(value)\n if (!key) return false\n return (\n key === '#FFFFFF' ||\n key === '255,255,255,none' ||\n key === '255,255,255,1'\n )\n}\n\nexport function rgbToString (rgb: RGB): string {\n return `rgb(${rgb.r},${rgb.g},${rgb.b})`\n}\n\nexport function findMappingForColor (\n value: string,\n mappings: ColorMapping[]\n): ColorMapping | undefined {\n const parsed = parseColorToRgb(value)\n if (!parsed) return undefined\n return mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n}\n","import { normalizeHexColor, parseColorToRgb } from './color-utils'\nimport type { ColorMapping } from './types'\n\nexport function buildColorMappings (\n previous: string[],\n next: string[]\n): ColorMapping[] {\n const mappings: ColorMapping[] = []\n const length = Math.min(previous.length, next.length)\n for (let i = 0; i < length; i += 1) {\n const fromParsed = parseColorToRgb(previous[i])\n const toParsed = parseColorToRgb(next[i])\n if (!fromParsed || !toParsed) continue\n const toHex = normalizeHexColor(next[i]) ?? undefined\n mappings.push({\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n })\n }\n return mappings\n}\n\nexport function buildSingleMapping (\n from?: string,\n to?: string\n): ColorMapping | null {\n if (!from || !to) return null\n const fromParsed = parseColorToRgb(from)\n const toParsed = parseColorToRgb(to)\n if (!fromParsed || !toParsed) return null\n const toHex = normalizeHexColor(to) ?? undefined\n return {\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n }\n}\n","import type { Slide, SlideElement } from '../types'\nimport {\n findMappingForColor,\n isPureColorString,\n normalizeThemeColor,\n parseColorToRgb,\n rgbToString\n} from './color-utils'\nimport type { ColorMapping } from './types'\n\nfunction applyFontColorToHtml (value: string, fontColor: string): string {\n if (!value || !fontColor) return value\n const normalized = normalizeThemeColor(fontColor) ?? fontColor\n const hasStyleColor = /\\bcolor\\s*:/i.test(value)\n if (hasStyleColor) {\n return value.replace(/color\\s*:\\s*([^;\"']+)/gi, () => `color: ${normalized}`)\n }\n return value.replace(\n /(<[^>]+style\\s*=\\s*[\"'])([^\"']*)([\"'])/gi,\n (_match, start, styles, end) => {\n if (/\\bcolor\\s*:/i.test(styles)) return _match\n const nextStyles = styles.trim()\n ? `${styles.trim()}; color: ${normalized}`\n : `color: ${normalized}`\n return `${start}${nextStyles}${end}`\n }\n )\n}\n\nfunction replaceColorValue (value: string, mappings: ColorMapping[]): string {\n const mapping = findMappingForColor(value, mappings)\n if (!mapping) return value\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n if (parsed.alpha !== undefined) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceRgbaString (value: string, mappings: ColorMapping[]): string {\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n const mapping = mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n if (!mapping) return value\n if (parsed.alpha !== undefined || value.toLowerCase().startsWith('rgba')) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha ?? 1})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceColorsInText (value: string, mappings: ColorMapping[]): string {\n let next = value\n next = next.replace(/#([0-9a-f]{3}|[0-9a-f]{6})/gi, (match) => {\n const mapping = findMappingForColor(match, mappings)\n if (!mapping) return match\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n })\n next = next.replace(/rgba?\\([^)]*\\)/gi, (match) =>\n replaceRgbaString(match, mappings)\n )\n return next\n}\n\nfunction replaceColorsDeep (value: unknown, mappings: ColorMapping[]): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim()\n const pureColor = isPureColorString(trimmed)\n if (pureColor) {\n const replaced = replaceColorValue(trimmed, mappings)\n return value === trimmed ? replaced : value.replace(trimmed, replaced)\n }\n return replaceColorsInText(value, mappings)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => replaceColorsDeep(item, mappings))\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n const next: Record<string, unknown> = {}\n for (const [key, item] of entries) {\n next[key] = replaceColorsDeep(item, mappings)\n }\n return next\n }\n\n return value\n}\n\nfunction replaceTextElementColors (\n element: SlideElement,\n fontMappings: ColorMapping[],\n fontColor: string\n): SlideElement {\n const next = replaceColorsDeep(element, fontMappings) as SlideElement\n const normalizedFontColor = normalizeThemeColor(fontColor) ?? fontColor\n const withDefault =\n normalizedFontColor && 'defaultColor' in next\n ? { ...next, defaultColor: normalizedFontColor }\n : next\n if (!('content' in withDefault) || typeof withDefault.content !== 'string') {\n return withDefault\n }\n return {\n ...withDefault,\n content: applyFontColorToHtml(withDefault.content, normalizedFontColor)\n }\n}\n\nexport function replaceSlideColors (\n slide: Slide,\n themeMappings: ColorMapping[],\n fontMappings: ColorMapping[],\n fontColor: string\n): Slide {\n const { elements, ...rest } = slide\n const nextSlide = replaceColorsDeep(rest, themeMappings) as Slide\n if (!elements) return nextSlide\n\n const nextElements: SlideElement[] = elements.map((element) => {\n if (element && typeof element === 'object' && element.type === 'text') {\n return replaceTextElementColors(element, fontMappings, fontColor)\n }\n return replaceColorsDeep(element, themeMappings) as SlideElement\n })\n\n return { ...nextSlide, elements: nextElements }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { colorsEqual, isWhiteColor } from './color-utils'\nimport { buildColorMappings, buildSingleMapping } from './mappings'\nimport { replaceSlideColors } from './replacers'\n\nexport function applyTheme2Json (deck: Deck, update: PptxCustomThemeInput): Deck {\n const previousTheme = deck.theme ?? {}\n const themeColors = update.themeColors.slice(0, 6)\n const themeMappings = buildColorMappings(\n previousTheme.themeColors ?? [],\n themeColors\n )\n const fontMapping = buildSingleMapping(\n previousTheme.fontColor,\n update.fontColor\n )\n const fontMappings = fontMapping ? [fontMapping] : []\n\n const nextBackground = update.backgroundColor ?? previousTheme.backgroundColor\n const prevBackground = previousTheme.backgroundColor\n const slides = deck.slides?.map((slide) => {\n const nextSlide = replaceSlideColors(\n slide,\n themeMappings,\n fontMappings,\n update.fontColor\n )\n if (!nextBackground) return nextSlide\n const currentColor = nextSlide.background?.color\n const shouldUpdate =\n !currentColor ||\n (prevBackground && colorsEqual(currentColor, prevBackground)) ||\n (!prevBackground && isWhiteColor(currentColor))\n if (!shouldUpdate) return nextSlide\n return {\n ...nextSlide,\n background: {\n ...(nextSlide.background ?? {}),\n type: nextSlide.background?.type ?? 'solid',\n color: nextBackground\n }\n }\n })\n\n return {\n ...deck,\n theme: {\n ...previousTheme,\n themeColors,\n fontColor: update.fontColor,\n backgroundColor: update.backgroundColor ?? previousTheme.backgroundColor\n },\n slides\n }\n}\n"],"mappings":"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","names":["import_json2pptx_schema","r","g","b","FALLBACK_SLIDE_WIDTH","FALLBACK_SLIDE_HEIGHT","LOGO_MARGIN_X","LOGO_MARGIN_Y","LOGO_MAX_WIDTH_RATIO","LOGO_MAX_HEIGHT_RATIO"]}
package/dist/index.mjs CHANGED
@@ -277,11 +277,63 @@ var applyCustomContentToTemplate = (template, CustomSlides) => {
277
277
  };
278
278
 
279
279
  // src/custom-content/index.ts
280
+ var FALLBACK_SLIDE_WIDTH = 1e3;
281
+ var FALLBACK_SLIDE_HEIGHT = 562.5;
282
+ var LOGO_MARGIN_X = 24;
283
+ var LOGO_MARGIN_Y = 18;
284
+ var LOGO_MAX_WIDTH_RATIO = 0.34;
285
+ var LOGO_MAX_HEIGHT_RATIO = 0.16;
286
+ function isLogoImageElement(element) {
287
+ return element.type === "image" && element.imageType === "logo";
288
+ }
289
+ function fitSize(width, height, maxWidth, maxHeight) {
290
+ const safeWidth = width > 0 ? width : maxWidth;
291
+ const safeHeight = height > 0 ? height : maxHeight;
292
+ const scale = Math.min(maxWidth / safeWidth, maxHeight / safeHeight);
293
+ return {
294
+ width: safeWidth * scale,
295
+ height: safeHeight * scale
296
+ };
297
+ }
298
+ function normalizeLogoElements(deck) {
299
+ const slideWidth = deck.width || FALLBACK_SLIDE_WIDTH;
300
+ const slideHeight = deck.height || FALLBACK_SLIDE_HEIGHT;
301
+ const logoMaxWidth = slideWidth * LOGO_MAX_WIDTH_RATIO;
302
+ const logoMaxHeight = slideHeight * LOGO_MAX_HEIGHT_RATIO;
303
+ const slides = deck.slides.map((slide) => {
304
+ let changed = false;
305
+ const elements = slide.elements.map((element) => {
306
+ if (!isLogoImageElement(element)) return element;
307
+ const size = fitSize(
308
+ element.width ?? logoMaxWidth,
309
+ element.height ?? logoMaxHeight,
310
+ logoMaxWidth,
311
+ logoMaxHeight
312
+ );
313
+ const isLeft = (element.left ?? 0) < slideWidth / 2;
314
+ const left = isLeft ? LOGO_MARGIN_X : Math.max(LOGO_MARGIN_X, slideWidth - size.width - LOGO_MARGIN_X);
315
+ const top = LOGO_MARGIN_Y;
316
+ const { clip: _clip, ...rest } = element;
317
+ changed = true;
318
+ return {
319
+ ...rest,
320
+ left,
321
+ top,
322
+ width: size.width,
323
+ height: size.height,
324
+ fixedRatio: true
325
+ };
326
+ });
327
+ return changed ? { ...slide, elements } : slide;
328
+ });
329
+ return { ...deck, slides };
330
+ }
280
331
  function applyCustomContent(template, input) {
281
332
  const normalizedTemplate = parseDocument(template);
282
333
  const CustomSlides = typeof input === "string" ? parseCustomContent(input) : input;
283
334
  const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides);
284
- return parseDocument(updated);
335
+ const withNormalizedLogo = normalizeLogoElements(updated);
336
+ return parseDocument(withNormalizedLogo);
285
337
  }
286
338
 
287
339
  // src/custom-theme/index.ts
@@ -550,10 +602,178 @@ function applyTheme2Json(deck, update) {
550
602
  }
551
603
 
552
604
  // src/custom-theme/index.ts
605
+ var FALLBACK_SLIDE_WIDTH2 = 1e3;
606
+ var FALLBACK_SLIDE_HEIGHT2 = 562.5;
607
+ var LOGO_MARGIN_X2 = 24;
608
+ var LOGO_MARGIN_Y2 = 18;
609
+ var LOGO_MAX_WIDTH_RATIO2 = 0.34;
610
+ var LOGO_MAX_HEIGHT_RATIO2 = 0.16;
611
+ var DEFAULT_LOGO_ASPECT_RATIO = 3.2;
612
+ function mapSlideTypeToScopeKey(type) {
613
+ const normalized = type?.trim().toLowerCase();
614
+ if (!normalized) return null;
615
+ if (normalized === "cover") return "cover";
616
+ if (normalized === "contents" || normalized === "agenda") return "contents";
617
+ if (normalized === "transition" || normalized === "section") return "transition";
618
+ if (normalized === "content") return "content";
619
+ if (normalized === "end" || normalized === "ending") return "end";
620
+ return null;
621
+ }
622
+ function isSlideInScope(slide, scope) {
623
+ const key = mapSlideTypeToScopeKey(slide.type);
624
+ if (!key) return false;
625
+ return Boolean(scope[key]);
626
+ }
627
+ function createElementId(prefix, slideIndex) {
628
+ const random = Math.random().toString(36).slice(2, 10);
629
+ return `${prefix}-${slideIndex}-${random}`;
630
+ }
631
+ function toHalfOpacityColor(value) {
632
+ const rgb = parseColorToRgb(value);
633
+ if (!rgb) return value;
634
+ return `rgba(${rgb.r},${rgb.g},${rgb.b},0.5)`;
635
+ }
636
+ function buildBackgroundElement(src, slideWidth, slideHeight, slideIndex) {
637
+ return {
638
+ type: "image",
639
+ id: createElementId("background", slideIndex),
640
+ src,
641
+ width: slideWidth,
642
+ height: slideHeight,
643
+ left: 0,
644
+ top: 0,
645
+ fixedRatio: true,
646
+ rotate: 0,
647
+ imageType: "background",
648
+ filters: {
649
+ opacity: "100%"
650
+ }
651
+ };
652
+ }
653
+ function buildLogoElement(src, slideWidth, slideHeight, position, slideIndex, logoWidth, logoHeight) {
654
+ const aspectRatio = resolveLogoAspectRatio(logoWidth, logoHeight);
655
+ const maxWidth = slideWidth * LOGO_MAX_WIDTH_RATIO2;
656
+ const maxHeight = slideHeight * LOGO_MAX_HEIGHT_RATIO2;
657
+ let width = maxWidth;
658
+ let height = width / aspectRatio;
659
+ if (height > maxHeight) {
660
+ height = maxHeight;
661
+ width = height * aspectRatio;
662
+ }
663
+ const left = position === "left" ? LOGO_MARGIN_X2 : Math.max(LOGO_MARGIN_X2, slideWidth - width - LOGO_MARGIN_X2);
664
+ return {
665
+ type: "image",
666
+ id: createElementId("logo", slideIndex),
667
+ src,
668
+ width,
669
+ height,
670
+ left,
671
+ top: LOGO_MARGIN_Y2,
672
+ fixedRatio: true,
673
+ rotate: 0,
674
+ imageType: "logo"
675
+ };
676
+ }
677
+ function resolveLogoAspectRatio(width, height) {
678
+ if (typeof width === "number" && typeof height === "number" && width > 0 && height > 0) {
679
+ return width / height;
680
+ }
681
+ return DEFAULT_LOGO_ASPECT_RATIO;
682
+ }
683
+ function replaceScopedMedia(deck, input) {
684
+ if (!deck.slides?.length) return deck;
685
+ const slideWidth = deck.width ?? FALLBACK_SLIDE_WIDTH2;
686
+ const slideHeight = deck.height ?? FALLBACK_SLIDE_HEIGHT2;
687
+ const backgroundInput = input.backgroundImage;
688
+ const logoInput = input.logoImage;
689
+ const shouldClearBackground = Boolean(input.clearBackgroundImage);
690
+ const shouldClearLogo = Boolean(input.clearLogoImage || shouldClearBackground);
691
+ if (!backgroundInput?.src && !logoInput?.src && !shouldClearBackground && !shouldClearLogo) {
692
+ return deck;
693
+ }
694
+ const slides = deck.slides.map((slide, slideIndex) => {
695
+ let nextElements = slide.elements ? [...slide.elements] : [];
696
+ let nextBackground = slide.background;
697
+ let changed = false;
698
+ if (shouldClearBackground) {
699
+ const before = nextElements.length;
700
+ nextElements = nextElements.filter(
701
+ (element) => !(element.type === "image" && element.imageType === "background")
702
+ );
703
+ if (nextElements.length !== before) {
704
+ changed = true;
705
+ if (input.backgroundColor) {
706
+ nextBackground = {
707
+ ...nextBackground ?? {},
708
+ type: "solid",
709
+ color: input.backgroundColor
710
+ };
711
+ }
712
+ }
713
+ }
714
+ if (shouldClearLogo) {
715
+ const before = nextElements.length;
716
+ nextElements = nextElements.filter(
717
+ (element) => !(element.type === "image" && element.imageType === "logo")
718
+ );
719
+ if (nextElements.length !== before) {
720
+ changed = true;
721
+ }
722
+ }
723
+ if (backgroundInput?.src && isSlideInScope(slide, backgroundInput.scope)) {
724
+ const withoutBackground = nextElements.filter(
725
+ (element) => !(element.type === "image" && element.imageType === "background")
726
+ );
727
+ nextElements = [
728
+ buildBackgroundElement(
729
+ backgroundInput.src,
730
+ slideWidth,
731
+ slideHeight,
732
+ slideIndex
733
+ ),
734
+ ...withoutBackground
735
+ ];
736
+ changed = true;
737
+ if (input.backgroundColor) {
738
+ nextBackground = {
739
+ ...nextBackground ?? {},
740
+ type: "solid",
741
+ color: toHalfOpacityColor(input.backgroundColor)
742
+ };
743
+ }
744
+ }
745
+ if (logoInput?.src && isSlideInScope(slide, logoInput.scope)) {
746
+ const withoutLogo = nextElements.filter(
747
+ (element) => !(element.type === "image" && element.imageType === "logo")
748
+ );
749
+ nextElements = [
750
+ ...withoutLogo,
751
+ buildLogoElement(
752
+ logoInput.src,
753
+ slideWidth,
754
+ slideHeight,
755
+ logoInput.position,
756
+ slideIndex,
757
+ logoInput.width,
758
+ logoInput.height
759
+ )
760
+ ];
761
+ changed = true;
762
+ }
763
+ if (!changed && nextBackground === slide.background) return slide;
764
+ return {
765
+ ...slide,
766
+ ...changed ? { elements: nextElements } : {},
767
+ ...nextBackground ? { background: nextBackground } : {}
768
+ };
769
+ });
770
+ return { ...deck, slides };
771
+ }
553
772
  function applyCustomTheme(deck, input) {
554
773
  const normalizedDeck = parseDocument2(deck);
555
- const updated = applyTheme2Json(normalizedDeck, input);
556
- return parseDocument2(updated);
774
+ const withColors = applyTheme2Json(normalizedDeck, input);
775
+ const withMedia = replaceScopedMedia(withColors, input);
776
+ return parseDocument2(withMedia);
557
777
  }
558
778
  export {
559
779
  applyCustomContent,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/custom-content/index.ts","../src/custom-content/parser.ts","../src/custom-content/html.ts","../src/custom-content/slide-appliers.ts","../src/custom-content/template-builder.ts","../src/custom-theme/index.ts","../src/custom-theme/color-utils.ts","../src/custom-theme/mappings.ts","../src/custom-theme/replacers.ts","../src/custom-theme/theme-applier.ts"],"sourcesContent":["import { parseDocument } from 'json2pptx-schema'\nimport type { PptxCustomContentInput, TemplateJson } from '../types'\nimport { parseCustomContent } from './parser'\nimport { applyCustomContentToTemplate } from './template-builder'\n\nexport function applyCustomContent (\n template: TemplateJson,\n input: PptxCustomContentInput\n): TemplateJson {\n const normalizedTemplate = parseDocument(template) as unknown as TemplateJson\n const CustomSlides = typeof input === 'string' ? parseCustomContent(input) : input\n const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides)\n return parseDocument(updated) as unknown as TemplateJson\n}\n\nexport { parseCustomContent, applyCustomContentToTemplate }\n","import type { BackendContentItem, CustomSlide } from '../types'\n\ntype UnknownRecord = Record<string, unknown>\n\nconst isRecord = (value: unknown): value is UnknownRecord =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst asString = (value: unknown): string | null =>\n typeof value === 'string' ? value : null\n\nconst asStringArray = (value: unknown): string[] | null => {\n if (!Array.isArray(value)) return null\n const normalized = value\n .map(item => asString(item))\n .filter((item): item is string => item !== null)\n return normalized.length === value.length ? normalized : null\n}\n\nconst normalizeType = (value: unknown): CustomSlide['type'] | null => {\n const raw = asString(value)?.trim().toLowerCase()\n if (!raw) return null\n if (raw === 'agenda') return 'contents'\n if (raw === 'section') return 'transition'\n if (raw === 'ending') return 'end'\n if (\n raw === 'cover' ||\n raw === 'contents' ||\n raw === 'transition' ||\n raw === 'content' ||\n raw === 'end'\n ) {\n return raw\n }\n return null\n}\n\nconst normalizeContentItems = (value: unknown): BackendContentItem[] | null => {\n if (!Array.isArray(value)) return null\n const normalized: BackendContentItem[] = []\n for (const item of value) {\n if (!isRecord(item)) return null\n const title = asString(item.title)\n const text = asString(item.text)\n if (title == null || text == null) return null\n normalized.push({ title, text })\n }\n return normalized\n}\n\nconst normalizeSlide = (value: unknown): CustomSlide | null => {\n if (!isRecord(value)) return null\n const type = normalizeType(value.type)\n if (!type) return null\n\n const rawData = isRecord(value.data) ? value.data : {}\n\n if (type === 'cover') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'contents') {\n const items = asStringArray(rawData.items)\n if (!items) return null\n return { type, data: { items } }\n }\n\n if (type === 'transition') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'content') {\n const title = asString(rawData.title)\n const items = normalizeContentItems(rawData.items)\n if (title == null || !items) return null\n return { type, data: { title, items } }\n }\n\n return { type }\n}\n\nconst parseNdJsonSlides = (raw: string): unknown[] =>\n raw\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => JSON.parse(line) as unknown)\n\nconst parseStructuredSlides = (raw: string): unknown[] | null => {\n const trimmed = raw.trim()\n if (!trimmed) return []\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed) as unknown\n } catch {\n return null\n }\n if (Array.isArray(parsed)) return parsed\n if (!isRecord(parsed)) return null\n if (Array.isArray(parsed.slides)) return parsed.slides\n if ('type' in parsed) return [parsed]\n return null\n}\n\nexport const parseCustomContent = (raw: string): CustomSlide[] => {\n const candidates = parseStructuredSlides(raw) ?? parseNdJsonSlides(raw)\n const slides = candidates\n .map(item => normalizeSlide(item))\n .filter((item): item is CustomSlide => item !== null)\n\n if (slides.length !== candidates.length) {\n throw new Error('Invalid custom content format')\n }\n return slides\n}\n","import type { TemplateJsonElement } from '../types'\n\nexport const updateHtmlContent = (html: string, text: string) => {\n if (typeof DOMParser === 'undefined') {\n return `<p>${text}</p>`\n }\n const parser = new DOMParser()\n const doc = parser.parseFromString(html, 'text/html')\n const spans = Array.from(doc.querySelectorAll('span'))\n if (spans.length > 0) {\n spans.forEach((span, index) => {\n span.textContent = index === 0 ? text : ''\n })\n } else {\n const paragraph = doc.querySelector('p')\n if (paragraph) {\n paragraph.textContent = text\n } else {\n doc.body.textContent = text\n }\n }\n return doc.body.innerHTML\n}\n\nexport const setElementText = (element: TemplateJsonElement, text: string) => {\n if (element.type !== 'text') return\n element.content = updateHtmlContent(element.content, text)\n}\n","import type {\n BackendContentData,\n BackendContentsData,\n BackendCoverData,\n BackendTransitionData,\n TemplateJsonSlide\n} from '../types'\nimport { setElementText, updateHtmlContent } from './html'\n\nfunction setShapeTextByType (\n slide: TemplateJsonSlide,\n textType: string,\n text: string\n): boolean {\n const shape = slide.elements.find((element) => {\n if (element.type !== 'shape') return false\n const maybeShape = element as unknown as {\n text?: { type?: string; content?: string }\n }\n return maybeShape.text?.type === textType\n })\n\n if (!shape) return false\n\n const shapeWithText = shape as unknown as {\n text?: { type?: string; content?: string }\n }\n if (!shapeWithText.text || typeof shapeWithText.text.content !== 'string') {\n return false\n }\n\n shapeWithText.text.content = updateHtmlContent(shapeWithText.text.content, text)\n return true\n}\n\nexport const applyCoverData = (slide: TemplateJsonSlide, data: BackendCoverData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n}\n\nexport const applyContentsData = (\n slide: TemplateJsonSlide,\n data: BackendContentsData\n) => {\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n items.forEach((element, index) => {\n const text = data.items[index]\n if (text) setElementText(element, text)\n })\n}\n\nexport const applyTransitionData = (\n slide: TemplateJsonSlide,\n data: BackendTransitionData,\n sectionIndex: number\n) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n const partNumber = slide.elements.find(\n element => element.type === 'text' && element.textType === 'partNumber'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n const formattedSectionIndex = `${sectionIndex}`.padStart(2, '0')\n if (partNumber) {\n setElementText(partNumber, formattedSectionIndex)\n } else {\n setShapeTextByType(slide, 'partNumber', formattedSectionIndex)\n }\n}\n\nexport const applyContentData = (slide: TemplateJsonSlide, data: BackendContentData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n if (title) setElementText(title, data.title)\n\n const itemTitles = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'itemTitle'\n )\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n\n data.items.forEach((item, index) => {\n const titleEl = itemTitles[index]\n const textEl = items[index]\n if (titleEl) setElementText(titleEl, item.title)\n if (textEl) setElementText(textEl, item.text)\n })\n}\n","import type { CustomSlide, TemplateJson, TemplateJsonSlide } from '../types'\nimport {\n applyContentData,\n applyContentsData,\n applyCoverData,\n applyTransitionData\n} from './slide-appliers'\n\nconst cloneSlide = (slide: TemplateJsonSlide): TemplateJsonSlide =>\n JSON.parse(JSON.stringify(slide)) as TemplateJsonSlide\n\nfunction normalizeLabel (value: string): string {\n return value\n .replace(/\\s+/g, ' ')\n .replace(/[,。、“”‘’:;!?【】()《》〈〉·,.:;!?()[\\]{}\"'`~\\-_/\\\\]/g, '')\n .trim()\n .toLowerCase()\n}\n\nfunction resolveTransitionIndex (\n customSlides: CustomSlide[],\n currentSlideIndex: number,\n transitionTitle: string,\n fallbackIndex: number\n): number {\n const normalizedTitle = normalizeLabel(transitionTitle)\n if (!normalizedTitle) return fallbackIndex\n\n const contentsItems = customSlides\n .slice(0, currentSlideIndex + 1)\n .filter((slide): slide is Extract<CustomSlide, { type: 'contents' }> => slide.type === 'contents')\n .flatMap(slide => slide.data.items)\n\n for (let index = 0; index < contentsItems.length; index += 1) {\n const normalizedItem = normalizeLabel(contentsItems[index])\n if (!normalizedItem) continue\n if (\n normalizedItem === normalizedTitle ||\n normalizedItem.includes(normalizedTitle) ||\n normalizedTitle.includes(normalizedItem)\n ) {\n return index + 1\n }\n }\n\n return fallbackIndex\n}\n\nexport const applyCustomContentToTemplate = (\n template: TemplateJson,\n CustomSlides: CustomSlide[]\n): TemplateJson => {\n const grouped = template.slides.reduce<Record<string, TemplateJsonSlide[]>>(\n (acc, slide) => {\n const key = slide.type || 'default'\n if (!acc[key]) acc[key] = []\n acc[key].push(slide)\n return acc\n },\n {}\n )\n\n const usage = new Map<string, number>()\n const getTextTypeCount = (slide: TemplateJsonSlide, textType: string) =>\n slide.elements.filter(\n element => element.type === 'text' && element.textType === textType\n ).length\n\n const getContentCapacity = (slide: TemplateJsonSlide) => {\n const titleSlots = getTextTypeCount(slide, 'itemTitle')\n const itemSlots = getTextTypeCount(slide, 'item')\n return Math.min(titleSlots, itemSlots)\n }\n\n const pickFromPool = (key: string, pool: TemplateJsonSlide[]) => {\n const index = usage.get(key) ?? 0\n usage.set(key, index + 1)\n return cloneSlide(pool[index % pool.length])\n }\n\n const pickSlide = (type: string, desiredCount?: number) => {\n const pool = grouped[type] || grouped.default || template.slides\n if (desiredCount == null || pool.length === 1) {\n return pickFromPool(type, pool)\n }\n\n const scored = pool.map(slide => {\n const capacity =\n type === 'content'\n ? getContentCapacity(slide)\n : getTextTypeCount(slide, 'item')\n return { slide, capacity }\n })\n const eligible = scored.filter(item => item.capacity >= desiredCount)\n if (eligible.length > 0) {\n const minCapacity = Math.min(...eligible.map(item => item.capacity))\n const best = eligible\n .filter(item => item.capacity === minCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, best)\n }\n const maxCapacity = Math.max(...scored.map(item => item.capacity))\n const fallback = scored\n .filter(item => item.capacity === maxCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, fallback)\n }\n\n let transitionIndex = 0\n const slides = CustomSlides.map((item, index) => {\n const desiredCount =\n item.type === 'contents'\n ? item.data.items.length\n : item.type === 'content'\n ? item.data.items.length\n : undefined\n const slide = pickSlide(item.type, desiredCount)\n if (item.type === 'cover') {\n applyCoverData(slide, item.data)\n } else if (item.type === 'contents') {\n applyContentsData(slide, item.data)\n } else if (item.type === 'transition') {\n transitionIndex += 1\n const partNumber = resolveTransitionIndex(\n CustomSlides,\n index,\n item.data.title,\n transitionIndex\n )\n applyTransitionData(slide, item.data, partNumber)\n } else if (item.type === 'content') {\n applyContentData(slide, item.data)\n }\n return slide\n })\n\n return {\n ...template,\n slides\n }\n}\n","import { parseDocument } from 'json2pptx-schema'\nimport type { Deck, PptxCustomThemeInput } from '../types'\nimport { applyTheme2Json } from './theme-applier'\n\nexport function applyCustomTheme (\n deck: Deck,\n input: PptxCustomThemeInput\n): Deck {\n const normalizedDeck = parseDocument(deck) as unknown as Deck\n const updated = applyTheme2Json(normalizedDeck, input)\n return parseDocument(updated) as unknown as Deck\n}\n\nexport { applyTheme2Json }\n","import type { ColorMapping, RGB } from './types'\n\nexport function normalizeHexColor (value: string): string | null {\n const raw = value.trim()\n const withHash = raw.startsWith('#') ? raw.slice(1) : raw\n if (withHash.length !== 3 && withHash.length !== 6) return null\n if (!/^[0-9a-fA-F]+$/.test(withHash)) return null\n const expanded =\n withHash.length === 3\n ? withHash\n .split('')\n .map((char) => char + char)\n .join('')\n : withHash\n return `#${expanded.toUpperCase()}`\n}\n\nexport function parseColorToRgb (\n value: string\n): (RGB & { alpha?: number }) | null {\n const hex = normalizeHexColor(value)\n if (hex) {\n const raw = hex.slice(1)\n const r = Number.parseInt(raw.slice(0, 2), 16)\n const g = Number.parseInt(raw.slice(2, 4), 16)\n const b = Number.parseInt(raw.slice(4, 6), 16)\n return { r, g, b }\n }\n\n const match = value.match(\n /rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)/i\n )\n if (!match) return null\n const r = Math.round(Number(match[1]))\n const g = Math.round(Number(match[2]))\n const b = Math.round(Number(match[3]))\n const alpha = match[4] !== undefined ? Number(match[4]) : undefined\n return {\n r,\n g,\n b,\n ...(Number.isFinite(alpha) ? { alpha } : {})\n }\n}\n\nexport function normalizeThemeColor (value: string): string | null {\n const hex = normalizeHexColor(value)\n if (hex) return hex\n const parsed = parseColorToRgb(value)\n if (!parsed) return null\n if (parsed.alpha !== undefined) {\n return `rgba(${parsed.r},${parsed.g},${parsed.b},${parsed.alpha})`\n }\n return `rgb(${parsed.r},${parsed.g},${parsed.b})`\n}\n\nexport function isPureColorString (value: string): boolean {\n const trimmed = value.trim()\n if (!trimmed) return false\n if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(trimmed)) return true\n return /^rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)$/i.test(\n trimmed\n )\n}\n\nfunction normalizeColorKey (value?: string): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n const parsed = parseColorToRgb(trimmed)\n if (parsed) {\n return `${parsed.r},${parsed.g},${parsed.b},${parsed.alpha ?? 'none'}`\n }\n const hex = normalizeHexColor(trimmed)\n if (hex) return hex\n return trimmed.toLowerCase()\n}\n\nexport function colorsEqual (a: string, b: string): boolean {\n const aKey = normalizeColorKey(a)\n const bKey = normalizeColorKey(b)\n if (!aKey || !bKey) return false\n return aKey === bKey\n}\n\nexport function isWhiteColor (value?: string): boolean {\n const key = normalizeColorKey(value)\n if (!key) return false\n return (\n key === '#FFFFFF' ||\n key === '255,255,255,none' ||\n key === '255,255,255,1'\n )\n}\n\nexport function rgbToString (rgb: RGB): string {\n return `rgb(${rgb.r},${rgb.g},${rgb.b})`\n}\n\nexport function findMappingForColor (\n value: string,\n mappings: ColorMapping[]\n): ColorMapping | undefined {\n const parsed = parseColorToRgb(value)\n if (!parsed) return undefined\n return mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n}\n","import { normalizeHexColor, parseColorToRgb } from './color-utils'\nimport type { ColorMapping } from './types'\n\nexport function buildColorMappings (\n previous: string[],\n next: string[]\n): ColorMapping[] {\n const mappings: ColorMapping[] = []\n const length = Math.min(previous.length, next.length)\n for (let i = 0; i < length; i += 1) {\n const fromParsed = parseColorToRgb(previous[i])\n const toParsed = parseColorToRgb(next[i])\n if (!fromParsed || !toParsed) continue\n const toHex = normalizeHexColor(next[i]) ?? undefined\n mappings.push({\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n })\n }\n return mappings\n}\n\nexport function buildSingleMapping (\n from?: string,\n to?: string\n): ColorMapping | null {\n if (!from || !to) return null\n const fromParsed = parseColorToRgb(from)\n const toParsed = parseColorToRgb(to)\n if (!fromParsed || !toParsed) return null\n const toHex = normalizeHexColor(to) ?? undefined\n return {\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n }\n}\n","import type { Slide, SlideElement } from '../types'\nimport {\n findMappingForColor,\n isPureColorString,\n normalizeThemeColor,\n parseColorToRgb,\n rgbToString\n} from './color-utils'\nimport type { ColorMapping } from './types'\n\nfunction applyFontColorToHtml (value: string, fontColor: string): string {\n if (!value || !fontColor) return value\n const normalized = normalizeThemeColor(fontColor) ?? fontColor\n const hasStyleColor = /\\bcolor\\s*:/i.test(value)\n if (hasStyleColor) {\n return value.replace(/color\\s*:\\s*([^;\"']+)/gi, () => `color: ${normalized}`)\n }\n return value.replace(\n /(<[^>]+style\\s*=\\s*[\"'])([^\"']*)([\"'])/gi,\n (_match, start, styles, end) => {\n if (/\\bcolor\\s*:/i.test(styles)) return _match\n const nextStyles = styles.trim()\n ? `${styles.trim()}; color: ${normalized}`\n : `color: ${normalized}`\n return `${start}${nextStyles}${end}`\n }\n )\n}\n\nfunction replaceColorValue (value: string, mappings: ColorMapping[]): string {\n const mapping = findMappingForColor(value, mappings)\n if (!mapping) return value\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n if (parsed.alpha !== undefined) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceRgbaString (value: string, mappings: ColorMapping[]): string {\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n const mapping = mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n if (!mapping) return value\n if (parsed.alpha !== undefined || value.toLowerCase().startsWith('rgba')) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha ?? 1})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceColorsInText (value: string, mappings: ColorMapping[]): string {\n let next = value\n next = next.replace(/#([0-9a-f]{3}|[0-9a-f]{6})/gi, (match) => {\n const mapping = findMappingForColor(match, mappings)\n if (!mapping) return match\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n })\n next = next.replace(/rgba?\\([^)]*\\)/gi, (match) =>\n replaceRgbaString(match, mappings)\n )\n return next\n}\n\nfunction replaceColorsDeep (value: unknown, mappings: ColorMapping[]): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim()\n const pureColor = isPureColorString(trimmed)\n if (pureColor) {\n const replaced = replaceColorValue(trimmed, mappings)\n return value === trimmed ? replaced : value.replace(trimmed, replaced)\n }\n return replaceColorsInText(value, mappings)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => replaceColorsDeep(item, mappings))\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n const next: Record<string, unknown> = {}\n for (const [key, item] of entries) {\n next[key] = replaceColorsDeep(item, mappings)\n }\n return next\n }\n\n return value\n}\n\nfunction replaceTextElementColors (\n element: SlideElement,\n fontMappings: ColorMapping[],\n fontColor: string\n): SlideElement {\n const next = replaceColorsDeep(element, fontMappings) as SlideElement\n const normalizedFontColor = normalizeThemeColor(fontColor) ?? fontColor\n const withDefault =\n normalizedFontColor && 'defaultColor' in next\n ? { ...next, defaultColor: normalizedFontColor }\n : next\n if (!('content' in withDefault) || typeof withDefault.content !== 'string') {\n return withDefault\n }\n return {\n ...withDefault,\n content: applyFontColorToHtml(withDefault.content, normalizedFontColor)\n }\n}\n\nexport function replaceSlideColors (\n slide: Slide,\n themeMappings: ColorMapping[],\n fontMappings: ColorMapping[],\n fontColor: string\n): Slide {\n const { elements, ...rest } = slide\n const nextSlide = replaceColorsDeep(rest, themeMappings) as Slide\n if (!elements) return nextSlide\n\n const nextElements: SlideElement[] = elements.map((element) => {\n if (element && typeof element === 'object' && element.type === 'text') {\n return replaceTextElementColors(element, fontMappings, fontColor)\n }\n return replaceColorsDeep(element, themeMappings) as SlideElement\n })\n\n return { ...nextSlide, elements: nextElements }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { colorsEqual, isWhiteColor } from './color-utils'\nimport { buildColorMappings, buildSingleMapping } from './mappings'\nimport { replaceSlideColors } from './replacers'\n\nexport function applyTheme2Json (deck: Deck, update: PptxCustomThemeInput): Deck {\n const previousTheme = deck.theme ?? {}\n const themeColors = update.themeColors.slice(0, 6)\n const themeMappings = buildColorMappings(\n previousTheme.themeColors ?? [],\n themeColors\n )\n const fontMapping = buildSingleMapping(\n previousTheme.fontColor,\n update.fontColor\n )\n const fontMappings = fontMapping ? [fontMapping] : []\n\n const nextBackground = update.backgroundColor ?? previousTheme.backgroundColor\n const prevBackground = previousTheme.backgroundColor\n const slides = deck.slides?.map((slide) => {\n const nextSlide = replaceSlideColors(\n slide,\n themeMappings,\n fontMappings,\n update.fontColor\n )\n if (!nextBackground) return nextSlide\n const currentColor = nextSlide.background?.color\n const shouldUpdate =\n !currentColor ||\n (prevBackground && colorsEqual(currentColor, prevBackground)) ||\n (!prevBackground && isWhiteColor(currentColor))\n if (!shouldUpdate) return nextSlide\n return {\n ...nextSlide,\n background: {\n ...(nextSlide.background ?? {}),\n type: nextSlide.background?.type ?? 'solid',\n color: nextBackground\n }\n }\n })\n\n return {\n ...deck,\n theme: {\n ...previousTheme,\n themeColors,\n fontColor: update.fontColor,\n backgroundColor: update.backgroundColor ?? previousTheme.backgroundColor\n },\n slides\n }\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;;;ACI9B,IAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,WAAW,CAAC,UAChB,OAAO,UAAU,WAAW,QAAQ;AAEtC,IAAM,gBAAgB,CAAC,UAAoC;AACzD,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAClC,QAAM,aAAa,MAChB,IAAI,UAAQ,SAAS,IAAI,CAAC,EAC1B,OAAO,CAAC,SAAyB,SAAS,IAAI;AACjD,SAAO,WAAW,WAAW,MAAM,SAAS,aAAa;AAC3D;AAEA,IAAM,gBAAgB,CAAC,UAA+C;AACpE,QAAM,MAAM,SAAS,KAAK,GAAG,KAAK,EAAE,YAAY;AAChD,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,QAAQ,SAAU,QAAO;AAC7B,MAAI,QAAQ,UAAW,QAAO;AAC9B,MAAI,QAAQ,SAAU,QAAO;AAC7B,MACE,QAAQ,WACR,QAAQ,cACR,QAAQ,gBACR,QAAQ,aACR,QAAQ,OACR;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,IAAM,wBAAwB,CAAC,UAAgD;AAC7E,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAClC,QAAM,aAAmC,CAAC;AAC1C,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,SAAS,IAAI,EAAG,QAAO;AAC5B,UAAM,QAAQ,SAAS,KAAK,KAAK;AACjC,UAAM,OAAO,SAAS,KAAK,IAAI;AAC/B,QAAI,SAAS,QAAQ,QAAQ,KAAM,QAAO;AAC1C,eAAW,KAAK,EAAE,OAAO,KAAK,CAAC;AAAA,EACjC;AACA,SAAO;AACT;AAEA,IAAM,iBAAiB,CAAC,UAAuC;AAC7D,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,OAAO,cAAc,MAAM,IAAI;AACrC,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,UAAU,SAAS,MAAM,IAAI,IAAI,MAAM,OAAO,CAAC;AAErD,MAAI,SAAS,SAAS;AACpB,UAAM,QAAQ,SAAS,QAAQ,KAAK;AACpC,UAAM,OAAO,SAAS,QAAQ,IAAI;AAClC,QAAI,SAAS,QAAQ,QAAQ,KAAM,QAAO;AAC1C,WAAO,EAAE,MAAM,MAAM,EAAE,OAAO,KAAK,EAAE;AAAA,EACvC;AAEA,MAAI,SAAS,YAAY;AACvB,UAAM,QAAQ,cAAc,QAAQ,KAAK;AACzC,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,EAAE,MAAM,MAAM,EAAE,MAAM,EAAE;AAAA,EACjC;AAEA,MAAI,SAAS,cAAc;AACzB,UAAM,QAAQ,SAAS,QAAQ,KAAK;AACpC,UAAM,OAAO,SAAS,QAAQ,IAAI;AAClC,QAAI,SAAS,QAAQ,QAAQ,KAAM,QAAO;AAC1C,WAAO,EAAE,MAAM,MAAM,EAAE,OAAO,KAAK,EAAE;AAAA,EACvC;AAEA,MAAI,SAAS,WAAW;AACtB,UAAM,QAAQ,SAAS,QAAQ,KAAK;AACpC,UAAM,QAAQ,sBAAsB,QAAQ,KAAK;AACjD,QAAI,SAAS,QAAQ,CAAC,MAAO,QAAO;AACpC,WAAO,EAAE,MAAM,MAAM,EAAE,OAAO,MAAM,EAAE;AAAA,EACxC;AAEA,SAAO,EAAE,KAAK;AAChB;AAEA,IAAM,oBAAoB,CAAC,QACzB,IACG,MAAM,OAAO,EACb,IAAI,UAAQ,KAAK,KAAK,CAAC,EACvB,OAAO,OAAO,EACd,IAAI,UAAQ,KAAK,MAAM,IAAI,CAAY;AAE5C,IAAM,wBAAwB,CAAC,QAAkC;AAC/D,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,MAAI,CAAC,QAAQ,WAAW,GAAG,KAAK,CAAC,QAAQ,WAAW,GAAG,EAAG,QAAO;AAEjE,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,OAAO;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,MAAM,EAAG,QAAO;AAClC,MAAI,CAAC,SAAS,MAAM,EAAG,QAAO;AAC9B,MAAI,MAAM,QAAQ,OAAO,MAAM,EAAG,QAAO,OAAO;AAChD,MAAI,UAAU,OAAQ,QAAO,CAAC,MAAM;AACpC,SAAO;AACT;AAEO,IAAM,qBAAqB,CAAC,QAA+B;AAChE,QAAM,aAAa,sBAAsB,GAAG,KAAK,kBAAkB,GAAG;AACtE,QAAM,SAAS,WACZ,IAAI,UAAQ,eAAe,IAAI,CAAC,EAChC,OAAO,CAAC,SAA8B,SAAS,IAAI;AAEtD,MAAI,OAAO,WAAW,WAAW,QAAQ;AACvC,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AACA,SAAO;AACT;;;ACvHO,IAAM,oBAAoB,CAAC,MAAc,SAAiB;AAC/D,MAAI,OAAO,cAAc,aAAa;AACpC,WAAO,MAAM,IAAI;AAAA,EACnB;AACA,QAAM,SAAS,IAAI,UAAU;AAC7B,QAAM,MAAM,OAAO,gBAAgB,MAAM,WAAW;AACpD,QAAM,QAAQ,MAAM,KAAK,IAAI,iBAAiB,MAAM,CAAC;AACrD,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,QAAQ,CAAC,MAAM,UAAU;AAC7B,WAAK,cAAc,UAAU,IAAI,OAAO;AAAA,IAC1C,CAAC;AAAA,EACH,OAAO;AACL,UAAM,YAAY,IAAI,cAAc,GAAG;AACvC,QAAI,WAAW;AACb,gBAAU,cAAc;AAAA,IAC1B,OAAO;AACL,UAAI,KAAK,cAAc;AAAA,IACzB;AAAA,EACF;AACA,SAAO,IAAI,KAAK;AAClB;AAEO,IAAM,iBAAiB,CAAC,SAA8B,SAAiB;AAC5E,MAAI,QAAQ,SAAS,OAAQ;AAC7B,UAAQ,UAAU,kBAAkB,QAAQ,SAAS,IAAI;AAC3D;;;AClBA,SAAS,mBACP,OACA,UACA,MACS;AACT,QAAM,QAAQ,MAAM,SAAS,KAAK,CAAC,YAAY;AAC7C,QAAI,QAAQ,SAAS,QAAS,QAAO;AACrC,UAAM,aAAa;AAGnB,WAAO,WAAW,MAAM,SAAS;AAAA,EACnC,CAAC;AAED,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,gBAAgB;AAGtB,MAAI,CAAC,cAAc,QAAQ,OAAO,cAAc,KAAK,YAAY,UAAU;AACzE,WAAO;AAAA,EACT;AAEA,gBAAc,KAAK,UAAU,kBAAkB,cAAc,KAAK,SAAS,IAAI;AAC/E,SAAO;AACT;AAEO,IAAM,iBAAiB,CAAC,OAA0B,SAA2B;AAClF,QAAM,QAAQ,MAAM,SAAS;AAAA,IAC3B,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D;AACA,QAAM,UAAU,MAAM,SAAS;AAAA,IAC7B,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D;AACA,MAAI,MAAO,gBAAe,OAAO,KAAK,KAAK;AAC3C,MAAI,QAAS,gBAAe,SAAS,KAAK,IAAI;AAChD;AAEO,IAAM,oBAAoB,CAC/B,OACA,SACG;AACH,QAAM,QAAQ,MAAM,SAAS;AAAA,IAC3B,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D;AACA,QAAM,QAAQ,CAAC,SAAS,UAAU;AAChC,UAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,QAAI,KAAM,gBAAe,SAAS,IAAI;AAAA,EACxC,CAAC;AACH;AAEO,IAAM,sBAAsB,CACjC,OACA,MACA,iBACG;AACH,QAAM,QAAQ,MAAM,SAAS;AAAA,IAC3B,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D;AACA,QAAM,UAAU,MAAM,SAAS;AAAA,IAC7B,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D;AACA,QAAM,aAAa,MAAM,SAAS;AAAA,IAChC,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D;AACA,MAAI,MAAO,gBAAe,OAAO,KAAK,KAAK;AAC3C,MAAI,QAAS,gBAAe,SAAS,KAAK,IAAI;AAC9C,QAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,GAAG,GAAG;AAC/D,MAAI,YAAY;AACd,mBAAe,YAAY,qBAAqB;AAAA,EAClD,OAAO;AACL,uBAAmB,OAAO,cAAc,qBAAqB;AAAA,EAC/D;AACF;AAEO,IAAM,mBAAmB,CAAC,OAA0B,SAA6B;AACtF,QAAM,QAAQ,MAAM,SAAS;AAAA,IAC3B,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D;AACA,MAAI,MAAO,gBAAe,OAAO,KAAK,KAAK;AAE3C,QAAM,aAAa,MAAM,SAAS;AAAA,IAChC,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D;AACA,QAAM,QAAQ,MAAM,SAAS;AAAA,IAC3B,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D;AAEA,OAAK,MAAM,QAAQ,CAAC,MAAM,UAAU;AAClC,UAAM,UAAU,WAAW,KAAK;AAChC,UAAM,SAAS,MAAM,KAAK;AAC1B,QAAI,QAAS,gBAAe,SAAS,KAAK,KAAK;AAC/C,QAAI,OAAQ,gBAAe,QAAQ,KAAK,IAAI;AAAA,EAC9C,CAAC;AACH;;;AC9FA,IAAM,aAAa,CAAC,UAClB,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AAElC,SAAS,eAAgB,OAAuB;AAC9C,SAAO,MACJ,QAAQ,QAAQ,GAAG,EACnB,QAAQ,kDAAkD,EAAE,EAC5D,KAAK,EACL,YAAY;AACjB;AAEA,SAAS,uBACP,cACA,mBACA,iBACA,eACQ;AACR,QAAM,kBAAkB,eAAe,eAAe;AACtD,MAAI,CAAC,gBAAiB,QAAO;AAE7B,QAAM,gBAAgB,aACnB,MAAM,GAAG,oBAAoB,CAAC,EAC9B,OAAO,CAAC,UAA+D,MAAM,SAAS,UAAU,EAChG,QAAQ,WAAS,MAAM,KAAK,KAAK;AAEpC,WAAS,QAAQ,GAAG,QAAQ,cAAc,QAAQ,SAAS,GAAG;AAC5D,UAAM,iBAAiB,eAAe,cAAc,KAAK,CAAC;AAC1D,QAAI,CAAC,eAAgB;AACrB,QACE,mBAAmB,mBACnB,eAAe,SAAS,eAAe,KACvC,gBAAgB,SAAS,cAAc,GACvC;AACA,aAAO,QAAQ;AAAA,IACjB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,+BAA+B,CAC1C,UACA,iBACiB;AACjB,QAAM,UAAU,SAAS,OAAO;AAAA,IAC9B,CAAC,KAAK,UAAU;AACd,YAAM,MAAM,MAAM,QAAQ;AAC1B,UAAI,CAAC,IAAI,GAAG,EAAG,KAAI,GAAG,IAAI,CAAC;AAC3B,UAAI,GAAG,EAAE,KAAK,KAAK;AACnB,aAAO;AAAA,IACT;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,QAAQ,oBAAI,IAAoB;AACtC,QAAM,mBAAmB,CAAC,OAA0B,aAClD,MAAM,SAAS;AAAA,IACb,aAAW,QAAQ,SAAS,UAAU,QAAQ,aAAa;AAAA,EAC7D,EAAE;AAEJ,QAAM,qBAAqB,CAAC,UAA6B;AACvD,UAAM,aAAa,iBAAiB,OAAO,WAAW;AACtD,UAAM,YAAY,iBAAiB,OAAO,MAAM;AAChD,WAAO,KAAK,IAAI,YAAY,SAAS;AAAA,EACvC;AAEA,QAAM,eAAe,CAAC,KAAa,SAA8B;AAC/D,UAAM,QAAQ,MAAM,IAAI,GAAG,KAAK;AAChC,UAAM,IAAI,KAAK,QAAQ,CAAC;AACxB,WAAO,WAAW,KAAK,QAAQ,KAAK,MAAM,CAAC;AAAA,EAC7C;AAEA,QAAM,YAAY,CAAC,MAAc,iBAA0B;AACzD,UAAM,OAAO,QAAQ,IAAI,KAAK,QAAQ,WAAW,SAAS;AAC1D,QAAI,gBAAgB,QAAQ,KAAK,WAAW,GAAG;AAC7C,aAAO,aAAa,MAAM,IAAI;AAAA,IAChC;AAEA,UAAM,SAAS,KAAK,IAAI,WAAS;AAC/B,YAAM,WACJ,SAAS,YACL,mBAAmB,KAAK,IACxB,iBAAiB,OAAO,MAAM;AACpC,aAAO,EAAE,OAAO,SAAS;AAAA,IAC3B,CAAC;AACD,UAAM,WAAW,OAAO,OAAO,UAAQ,KAAK,YAAY,YAAY;AACpE,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,cAAc,KAAK,IAAI,GAAG,SAAS,IAAI,UAAQ,KAAK,QAAQ,CAAC;AACnE,YAAM,OAAO,SACV,OAAO,UAAQ,KAAK,aAAa,WAAW,EAC5C,IAAI,UAAQ,KAAK,KAAK;AACzB,aAAO,aAAa,GAAG,IAAI,IAAI,YAAY,IAAI,IAAI;AAAA,IACrD;AACA,UAAM,cAAc,KAAK,IAAI,GAAG,OAAO,IAAI,UAAQ,KAAK,QAAQ,CAAC;AACjE,UAAM,WAAW,OACd,OAAO,UAAQ,KAAK,aAAa,WAAW,EAC5C,IAAI,UAAQ,KAAK,KAAK;AACzB,WAAO,aAAa,GAAG,IAAI,IAAI,YAAY,IAAI,QAAQ;AAAA,EACzD;AAEA,MAAI,kBAAkB;AACtB,QAAM,SAAS,aAAa,IAAI,CAAC,MAAM,UAAU;AAC/C,UAAM,eACJ,KAAK,SAAS,aACV,KAAK,KAAK,MAAM,SAChB,KAAK,SAAS,YACd,KAAK,KAAK,MAAM,SAChB;AACN,UAAM,QAAQ,UAAU,KAAK,MAAM,YAAY;AAC/C,QAAI,KAAK,SAAS,SAAS;AACzB,qBAAe,OAAO,KAAK,IAAI;AAAA,IACjC,WAAW,KAAK,SAAS,YAAY;AACnC,wBAAkB,OAAO,KAAK,IAAI;AAAA,IACpC,WAAW,KAAK,SAAS,cAAc;AACrC,yBAAmB;AACnB,YAAM,aAAa;AAAA,QACjB;AAAA,QACA;AAAA,QACA,KAAK,KAAK;AAAA,QACV;AAAA,MACF;AACA,0BAAoB,OAAO,KAAK,MAAM,UAAU;AAAA,IAClD,WAAW,KAAK,SAAS,WAAW;AAClC,uBAAiB,OAAO,KAAK,IAAI;AAAA,IACnC;AACA,WAAO;AAAA,EACT,CAAC;AAED,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,EACF;AACF;;;AJvIO,SAAS,mBACd,UACA,OACc;AACd,QAAM,qBAAqB,cAAc,QAAQ;AACjD,QAAM,eAAe,OAAO,UAAU,WAAW,mBAAmB,KAAK,IAAI;AAC7E,QAAM,UAAU,6BAA6B,oBAAoB,YAAY;AAC7E,SAAO,cAAc,OAAO;AAC9B;;;AKbA,SAAS,iBAAAA,sBAAqB;;;ACEvB,SAAS,kBAAmB,OAA8B;AAC/D,QAAM,MAAM,MAAM,KAAK;AACvB,QAAM,WAAW,IAAI,WAAW,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI;AACtD,MAAI,SAAS,WAAW,KAAK,SAAS,WAAW,EAAG,QAAO;AAC3D,MAAI,CAAC,iBAAiB,KAAK,QAAQ,EAAG,QAAO;AAC7C,QAAM,WACJ,SAAS,WAAW,IAChB,SACG,MAAM,EAAE,EACR,IAAI,CAAC,SAAS,OAAO,IAAI,EACzB,KAAK,EAAE,IACV;AACN,SAAO,IAAI,SAAS,YAAY,CAAC;AACnC;AAEO,SAAS,gBACd,OACmC;AACnC,QAAM,MAAM,kBAAkB,KAAK;AACnC,MAAI,KAAK;AACP,UAAM,MAAM,IAAI,MAAM,CAAC;AACvB,UAAMC,KAAI,OAAO,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAC7C,UAAMC,KAAI,OAAO,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAC7C,UAAMC,KAAI,OAAO,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAC7C,WAAO,EAAE,GAAAF,IAAG,GAAAC,IAAG,GAAAC,GAAE;AAAA,EACnB;AAEA,QAAM,QAAQ,MAAM;AAAA,IAClB;AAAA,EACF;AACA,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC,CAAC;AACrC,QAAM,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC,CAAC;AACrC,QAAM,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC,CAAC;AACrC,QAAM,QAAQ,MAAM,CAAC,MAAM,SAAY,OAAO,MAAM,CAAC,CAAC,IAAI;AAC1D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,SAAS,KAAK,IAAI,EAAE,MAAM,IAAI,CAAC;AAAA,EAC5C;AACF;AAEO,SAAS,oBAAqB,OAA8B;AACjE,QAAM,MAAM,kBAAkB,KAAK;AACnC,MAAI,IAAK,QAAO;AAChB,QAAM,SAAS,gBAAgB,KAAK;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,OAAO,UAAU,QAAW;AAC9B,WAAO,QAAQ,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,KAAK;AAAA,EACjE;AACA,SAAO,OAAO,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC;AAChD;AAEO,SAAS,kBAAmB,OAAwB;AACzD,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,gCAAgC,KAAK,OAAO,EAAG,QAAO;AAC1D,SAAO,mFAAmF;AAAA,IACxF;AAAA,EACF;AACF;AAEA,SAAS,kBAAmB,OAA+B;AACzD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,SAAS,gBAAgB,OAAO;AACtC,MAAI,QAAQ;AACV,WAAO,GAAG,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,SAAS,MAAM;AAAA,EACtE;AACA,QAAM,MAAM,kBAAkB,OAAO;AACrC,MAAI,IAAK,QAAO;AAChB,SAAO,QAAQ,YAAY;AAC7B;AAEO,SAAS,YAAa,GAAW,GAAoB;AAC1D,QAAM,OAAO,kBAAkB,CAAC;AAChC,QAAM,OAAO,kBAAkB,CAAC;AAChC,MAAI,CAAC,QAAQ,CAAC,KAAM,QAAO;AAC3B,SAAO,SAAS;AAClB;AAEO,SAAS,aAAc,OAAyB;AACrD,QAAM,MAAM,kBAAkB,KAAK;AACnC,MAAI,CAAC,IAAK,QAAO;AACjB,SACE,QAAQ,aACR,QAAQ,sBACR,QAAQ;AAEZ;AAEO,SAAS,YAAa,KAAkB;AAC7C,SAAO,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;AACvC;AAEO,SAAS,oBACd,OACA,UAC0B;AAC1B,QAAM,SAAS,gBAAgB,KAAK;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,SAAS;AAAA,IACd,CAAC,SACC,KAAK,QAAQ,MAAM,OAAO,KAC1B,KAAK,QAAQ,MAAM,OAAO,KAC1B,KAAK,QAAQ,MAAM,OAAO;AAAA,EAC9B;AACF;;;AC5GO,SAAS,mBACd,UACA,MACgB;AAChB,QAAM,WAA2B,CAAC;AAClC,QAAM,SAAS,KAAK,IAAI,SAAS,QAAQ,KAAK,MAAM;AACpD,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK,GAAG;AAClC,UAAM,aAAa,gBAAgB,SAAS,CAAC,CAAC;AAC9C,UAAM,WAAW,gBAAgB,KAAK,CAAC,CAAC;AACxC,QAAI,CAAC,cAAc,CAAC,SAAU;AAC9B,UAAM,QAAQ,kBAAkB,KAAK,CAAC,CAAC,KAAK;AAC5C,aAAS,KAAK;AAAA,MACZ,SAAS,EAAE,GAAG,WAAW,GAAG,GAAG,WAAW,GAAG,GAAG,WAAW,EAAE;AAAA,MAC7D,OAAO,EAAE,GAAG,SAAS,GAAG,GAAG,SAAS,GAAG,GAAG,SAAS,EAAE;AAAA,MACrD;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEO,SAAS,mBACd,MACA,IACqB;AACrB,MAAI,CAAC,QAAQ,CAAC,GAAI,QAAO;AACzB,QAAM,aAAa,gBAAgB,IAAI;AACvC,QAAM,WAAW,gBAAgB,EAAE;AACnC,MAAI,CAAC,cAAc,CAAC,SAAU,QAAO;AACrC,QAAM,QAAQ,kBAAkB,EAAE,KAAK;AACvC,SAAO;AAAA,IACL,SAAS,EAAE,GAAG,WAAW,GAAG,GAAG,WAAW,GAAG,GAAG,WAAW,EAAE;AAAA,IAC7D,OAAO,EAAE,GAAG,SAAS,GAAG,GAAG,SAAS,GAAG,GAAG,SAAS,EAAE;AAAA,IACrD;AAAA,EACF;AACF;;;AC3BA,SAAS,qBAAsB,OAAe,WAA2B;AACvE,MAAI,CAAC,SAAS,CAAC,UAAW,QAAO;AACjC,QAAM,aAAa,oBAAoB,SAAS,KAAK;AACrD,QAAM,gBAAgB,eAAe,KAAK,KAAK;AAC/C,MAAI,eAAe;AACjB,WAAO,MAAM,QAAQ,2BAA2B,MAAM,UAAU,UAAU,EAAE;AAAA,EAC9E;AACA,SAAO,MAAM;AAAA,IACX;AAAA,IACA,CAAC,QAAQ,OAAO,QAAQ,QAAQ;AAC9B,UAAI,eAAe,KAAK,MAAM,EAAG,QAAO;AACxC,YAAM,aAAa,OAAO,KAAK,IAC3B,GAAG,OAAO,KAAK,CAAC,YAAY,UAAU,KACtC,UAAU,UAAU;AACxB,aAAO,GAAG,KAAK,GAAG,UAAU,GAAG,GAAG;AAAA,IACpC;AAAA,EACF;AACF;AAEA,SAAS,kBAAmB,OAAe,UAAkC;AAC3E,QAAM,UAAU,oBAAoB,OAAO,QAAQ;AACnD,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,SAAS,gBAAgB,KAAK;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,OAAO,UAAU,QAAW;AAC9B,WAAO,QAAQ,QAAQ,MAAM,CAAC,IAAI,QAAQ,MAAM,CAAC,IAAI,QAAQ,MAAM,CAAC,IAAI,OAAO,KAAK;AAAA,EACtF;AACA,SAAO,QAAQ,SAAS,YAAY,QAAQ,KAAK;AACnD;AAEA,SAAS,kBAAmB,OAAe,UAAkC;AAC3E,QAAM,SAAS,gBAAgB,KAAK;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,UAAU,SAAS;AAAA,IACvB,CAAC,SACC,KAAK,QAAQ,MAAM,OAAO,KAC1B,KAAK,QAAQ,MAAM,OAAO,KAC1B,KAAK,QAAQ,MAAM,OAAO;AAAA,EAC9B;AACA,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,OAAO,UAAU,UAAa,MAAM,YAAY,EAAE,WAAW,MAAM,GAAG;AACxE,WAAO,QAAQ,QAAQ,MAAM,CAAC,IAAI,QAAQ,MAAM,CAAC,IAAI,QAAQ,MAAM,CAAC,IAAI,OAAO,SAAS,CAAC;AAAA,EAC3F;AACA,SAAO,QAAQ,SAAS,YAAY,QAAQ,KAAK;AACnD;AAEA,SAAS,oBAAqB,OAAe,UAAkC;AAC7E,MAAI,OAAO;AACX,SAAO,KAAK,QAAQ,gCAAgC,CAAC,UAAU;AAC7D,UAAM,UAAU,oBAAoB,OAAO,QAAQ;AACnD,QAAI,CAAC,QAAS,QAAO;AACrB,WAAO,QAAQ,SAAS,YAAY,QAAQ,KAAK;AAAA,EACnD,CAAC;AACD,SAAO,KAAK;AAAA,IAAQ;AAAA,IAAoB,CAAC,UACvC,kBAAkB,OAAO,QAAQ;AAAA,EACnC;AACA,SAAO;AACT;AAEA,SAAS,kBAAmB,OAAgB,UAAmC;AAC7E,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,MAAM,KAAK;AAC3B,UAAM,YAAY,kBAAkB,OAAO;AAC3C,QAAI,WAAW;AACb,YAAM,WAAW,kBAAkB,SAAS,QAAQ;AACpD,aAAO,UAAU,UAAU,WAAW,MAAM,QAAQ,SAAS,QAAQ;AAAA,IACvE;AACA,WAAO,oBAAoB,OAAO,QAAQ;AAAA,EAC5C;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAS,kBAAkB,MAAM,QAAQ,CAAC;AAAA,EAC9D;AAEA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,UAAU,OAAO,QAAQ,KAAgC;AAC/D,UAAM,OAAgC,CAAC;AACvC,eAAW,CAAC,KAAK,IAAI,KAAK,SAAS;AACjC,WAAK,GAAG,IAAI,kBAAkB,MAAM,QAAQ;AAAA,IAC9C;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,yBACP,SACA,cACA,WACc;AACd,QAAM,OAAO,kBAAkB,SAAS,YAAY;AACpD,QAAM,sBAAsB,oBAAoB,SAAS,KAAK;AAC9D,QAAM,cACJ,uBAAuB,kBAAkB,OACrC,EAAE,GAAG,MAAM,cAAc,oBAAoB,IAC7C;AACN,MAAI,EAAE,aAAa,gBAAgB,OAAO,YAAY,YAAY,UAAU;AAC1E,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,qBAAqB,YAAY,SAAS,mBAAmB;AAAA,EACxE;AACF;AAEO,SAAS,mBACd,OACA,eACA,cACA,WACO;AACP,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI;AAC9B,QAAM,YAAY,kBAAkB,MAAM,aAAa;AACvD,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,eAA+B,SAAS,IAAI,CAAC,YAAY;AAC7D,QAAI,WAAW,OAAO,YAAY,YAAY,QAAQ,SAAS,QAAQ;AACrE,aAAO,yBAAyB,SAAS,cAAc,SAAS;AAAA,IAClE;AACA,WAAO,kBAAkB,SAAS,aAAa;AAAA,EACjD,CAAC;AAED,SAAO,EAAE,GAAG,WAAW,UAAU,aAAa;AAChD;;;ACjIO,SAAS,gBAAiB,MAAY,QAAoC;AAC/E,QAAM,gBAAgB,KAAK,SAAS,CAAC;AACrC,QAAM,cAAc,OAAO,YAAY,MAAM,GAAG,CAAC;AACjD,QAAM,gBAAgB;AAAA,IACpB,cAAc,eAAe,CAAC;AAAA,IAC9B;AAAA,EACF;AACA,QAAM,cAAc;AAAA,IAClB,cAAc;AAAA,IACd,OAAO;AAAA,EACT;AACA,QAAM,eAAe,cAAc,CAAC,WAAW,IAAI,CAAC;AAEpD,QAAM,iBAAiB,OAAO,mBAAmB,cAAc;AAC/D,QAAM,iBAAiB,cAAc;AACrC,QAAM,SAAS,KAAK,QAAQ,IAAI,CAAC,UAAU;AACzC,UAAM,YAAY;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IACT;AACA,QAAI,CAAC,eAAgB,QAAO;AAC5B,UAAM,eAAe,UAAU,YAAY;AAC3C,UAAM,eACJ,CAAC,gBACA,kBAAkB,YAAY,cAAc,cAAc,KAC1D,CAAC,kBAAkB,aAAa,YAAY;AAC/C,QAAI,CAAC,aAAc,QAAO;AAC1B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,YAAY;AAAA,QACV,GAAI,UAAU,cAAc,CAAC;AAAA,QAC7B,MAAM,UAAU,YAAY,QAAQ;AAAA,QACpC,OAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,WAAW,OAAO;AAAA,MAClB,iBAAiB,OAAO,mBAAmB,cAAc;AAAA,IAC3D;AAAA,IACA;AAAA,EACF;AACF;;;AJlDO,SAAS,iBACd,MACA,OACM;AACN,QAAM,iBAAiBC,eAAc,IAAI;AACzC,QAAM,UAAU,gBAAgB,gBAAgB,KAAK;AACrD,SAAOA,eAAc,OAAO;AAC9B;","names":["parseDocument","r","g","b","parseDocument"]}
1
+ {"version":3,"sources":["../src/custom-content/index.ts","../src/custom-content/parser.ts","../src/custom-content/html.ts","../src/custom-content/slide-appliers.ts","../src/custom-content/template-builder.ts","../src/custom-theme/index.ts","../src/custom-theme/color-utils.ts","../src/custom-theme/mappings.ts","../src/custom-theme/replacers.ts","../src/custom-theme/theme-applier.ts"],"sourcesContent":["import { parseDocument } from 'json2pptx-schema'\nimport type {\n PptxCustomContentInput,\n TemplateJson,\n TemplateJsonElement,\n TemplateJsonImage\n} from '../types'\nimport { parseCustomContent } from './parser'\nimport { applyCustomContentToTemplate } from './template-builder'\n\nconst FALLBACK_SLIDE_WIDTH = 1000\nconst FALLBACK_SLIDE_HEIGHT = 562.5\nconst LOGO_MARGIN_X = 24\nconst LOGO_MARGIN_Y = 18\nconst LOGO_MAX_WIDTH_RATIO = 0.34\nconst LOGO_MAX_HEIGHT_RATIO = 0.16\n\nfunction isLogoImageElement (\n element: TemplateJsonElement\n): element is TemplateJsonImage {\n return element.type === 'image' && element.imageType === 'logo'\n}\n\nfunction fitSize (\n width: number,\n height: number,\n maxWidth: number,\n maxHeight: number\n): { width: number; height: number } {\n const safeWidth = width > 0 ? width : maxWidth\n const safeHeight = height > 0 ? height : maxHeight\n const scale = Math.min(maxWidth / safeWidth, maxHeight / safeHeight)\n return {\n width: safeWidth * scale,\n height: safeHeight * scale\n }\n}\n\nfunction normalizeLogoElements (deck: TemplateJson): TemplateJson {\n const slideWidth = deck.width || FALLBACK_SLIDE_WIDTH\n const slideHeight = deck.height || FALLBACK_SLIDE_HEIGHT\n const logoMaxWidth = slideWidth * LOGO_MAX_WIDTH_RATIO\n const logoMaxHeight = slideHeight * LOGO_MAX_HEIGHT_RATIO\n\n const slides = deck.slides.map(slide => {\n let changed = false\n const elements = slide.elements.map(element => {\n if (!isLogoImageElement(element)) return element\n\n const size = fitSize(\n element.width ?? logoMaxWidth,\n element.height ?? logoMaxHeight,\n logoMaxWidth,\n logoMaxHeight\n )\n const isLeft = (element.left ?? 0) < slideWidth / 2\n const left = isLeft\n ? LOGO_MARGIN_X\n : Math.max(LOGO_MARGIN_X, slideWidth - size.width - LOGO_MARGIN_X)\n const top = LOGO_MARGIN_Y\n const { clip: _clip, ...rest } = element\n\n changed = true\n return {\n ...rest,\n left,\n top,\n width: size.width,\n height: size.height,\n fixedRatio: true\n }\n })\n\n return changed ? { ...slide, elements } : slide\n })\n\n return { ...deck, slides }\n}\n\nexport function applyCustomContent (\n template: TemplateJson,\n input: PptxCustomContentInput\n): TemplateJson {\n const normalizedTemplate = parseDocument(template) as unknown as TemplateJson\n const CustomSlides = typeof input === 'string' ? parseCustomContent(input) : input\n const updated = applyCustomContentToTemplate(normalizedTemplate, CustomSlides)\n const withNormalizedLogo = normalizeLogoElements(updated)\n return parseDocument(withNormalizedLogo) as unknown as TemplateJson\n}\n\nexport { parseCustomContent, applyCustomContentToTemplate }\n","import type { BackendContentItem, CustomSlide } from '../types'\n\ntype UnknownRecord = Record<string, unknown>\n\nconst isRecord = (value: unknown): value is UnknownRecord =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst asString = (value: unknown): string | null =>\n typeof value === 'string' ? value : null\n\nconst asStringArray = (value: unknown): string[] | null => {\n if (!Array.isArray(value)) return null\n const normalized = value\n .map(item => asString(item))\n .filter((item): item is string => item !== null)\n return normalized.length === value.length ? normalized : null\n}\n\nconst normalizeType = (value: unknown): CustomSlide['type'] | null => {\n const raw = asString(value)?.trim().toLowerCase()\n if (!raw) return null\n if (raw === 'agenda') return 'contents'\n if (raw === 'section') return 'transition'\n if (raw === 'ending') return 'end'\n if (\n raw === 'cover' ||\n raw === 'contents' ||\n raw === 'transition' ||\n raw === 'content' ||\n raw === 'end'\n ) {\n return raw\n }\n return null\n}\n\nconst normalizeContentItems = (value: unknown): BackendContentItem[] | null => {\n if (!Array.isArray(value)) return null\n const normalized: BackendContentItem[] = []\n for (const item of value) {\n if (!isRecord(item)) return null\n const title = asString(item.title)\n const text = asString(item.text)\n if (title == null || text == null) return null\n normalized.push({ title, text })\n }\n return normalized\n}\n\nconst normalizeSlide = (value: unknown): CustomSlide | null => {\n if (!isRecord(value)) return null\n const type = normalizeType(value.type)\n if (!type) return null\n\n const rawData = isRecord(value.data) ? value.data : {}\n\n if (type === 'cover') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'contents') {\n const items = asStringArray(rawData.items)\n if (!items) return null\n return { type, data: { items } }\n }\n\n if (type === 'transition') {\n const title = asString(rawData.title)\n const text = asString(rawData.text)\n if (title == null || text == null) return null\n return { type, data: { title, text } }\n }\n\n if (type === 'content') {\n const title = asString(rawData.title)\n const items = normalizeContentItems(rawData.items)\n if (title == null || !items) return null\n return { type, data: { title, items } }\n }\n\n return { type }\n}\n\nconst parseNdJsonSlides = (raw: string): unknown[] =>\n raw\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => JSON.parse(line) as unknown)\n\nconst parseStructuredSlides = (raw: string): unknown[] | null => {\n const trimmed = raw.trim()\n if (!trimmed) return []\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed) as unknown\n } catch {\n return null\n }\n if (Array.isArray(parsed)) return parsed\n if (!isRecord(parsed)) return null\n if (Array.isArray(parsed.slides)) return parsed.slides\n if ('type' in parsed) return [parsed]\n return null\n}\n\nexport const parseCustomContent = (raw: string): CustomSlide[] => {\n const candidates = parseStructuredSlides(raw) ?? parseNdJsonSlides(raw)\n const slides = candidates\n .map(item => normalizeSlide(item))\n .filter((item): item is CustomSlide => item !== null)\n\n if (slides.length !== candidates.length) {\n throw new Error('Invalid custom content format')\n }\n return slides\n}\n","import type { TemplateJsonElement } from '../types'\n\nexport const updateHtmlContent = (html: string, text: string) => {\n if (typeof DOMParser === 'undefined') {\n return `<p>${text}</p>`\n }\n const parser = new DOMParser()\n const doc = parser.parseFromString(html, 'text/html')\n const spans = Array.from(doc.querySelectorAll('span'))\n if (spans.length > 0) {\n spans.forEach((span, index) => {\n span.textContent = index === 0 ? text : ''\n })\n } else {\n const paragraph = doc.querySelector('p')\n if (paragraph) {\n paragraph.textContent = text\n } else {\n doc.body.textContent = text\n }\n }\n return doc.body.innerHTML\n}\n\nexport const setElementText = (element: TemplateJsonElement, text: string) => {\n if (element.type !== 'text') return\n element.content = updateHtmlContent(element.content, text)\n}\n","import type {\n BackendContentData,\n BackendContentsData,\n BackendCoverData,\n BackendTransitionData,\n TemplateJsonSlide\n} from '../types'\nimport { setElementText, updateHtmlContent } from './html'\n\nfunction setShapeTextByType (\n slide: TemplateJsonSlide,\n textType: string,\n text: string\n): boolean {\n const shape = slide.elements.find((element) => {\n if (element.type !== 'shape') return false\n const maybeShape = element as unknown as {\n text?: { type?: string; content?: string }\n }\n return maybeShape.text?.type === textType\n })\n\n if (!shape) return false\n\n const shapeWithText = shape as unknown as {\n text?: { type?: string; content?: string }\n }\n if (!shapeWithText.text || typeof shapeWithText.text.content !== 'string') {\n return false\n }\n\n shapeWithText.text.content = updateHtmlContent(shapeWithText.text.content, text)\n return true\n}\n\nexport const applyCoverData = (slide: TemplateJsonSlide, data: BackendCoverData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n}\n\nexport const applyContentsData = (\n slide: TemplateJsonSlide,\n data: BackendContentsData\n) => {\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n items.forEach((element, index) => {\n const text = data.items[index]\n if (text) setElementText(element, text)\n })\n}\n\nexport const applyTransitionData = (\n slide: TemplateJsonSlide,\n data: BackendTransitionData,\n sectionIndex: number\n) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n const content = slide.elements.find(\n element => element.type === 'text' && element.textType === 'content'\n )\n const partNumber = slide.elements.find(\n element => element.type === 'text' && element.textType === 'partNumber'\n )\n if (title) setElementText(title, data.title)\n if (content) setElementText(content, data.text)\n const formattedSectionIndex = `${sectionIndex}`.padStart(2, '0')\n if (partNumber) {\n setElementText(partNumber, formattedSectionIndex)\n } else {\n setShapeTextByType(slide, 'partNumber', formattedSectionIndex)\n }\n}\n\nexport const applyContentData = (slide: TemplateJsonSlide, data: BackendContentData) => {\n const title = slide.elements.find(\n element => element.type === 'text' && element.textType === 'title'\n )\n if (title) setElementText(title, data.title)\n\n const itemTitles = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'itemTitle'\n )\n const items = slide.elements.filter(\n element => element.type === 'text' && element.textType === 'item'\n )\n\n data.items.forEach((item, index) => {\n const titleEl = itemTitles[index]\n const textEl = items[index]\n if (titleEl) setElementText(titleEl, item.title)\n if (textEl) setElementText(textEl, item.text)\n })\n}\n","import type { CustomSlide, TemplateJson, TemplateJsonSlide } from '../types'\nimport {\n applyContentData,\n applyContentsData,\n applyCoverData,\n applyTransitionData\n} from './slide-appliers'\n\nconst cloneSlide = (slide: TemplateJsonSlide): TemplateJsonSlide =>\n JSON.parse(JSON.stringify(slide)) as TemplateJsonSlide\n\nfunction normalizeLabel (value: string): string {\n return value\n .replace(/\\s+/g, ' ')\n .replace(/[,。、“”‘’:;!?【】()《》〈〉·,.:;!?()[\\]{}\"'`~\\-_/\\\\]/g, '')\n .trim()\n .toLowerCase()\n}\n\nfunction resolveTransitionIndex (\n customSlides: CustomSlide[],\n currentSlideIndex: number,\n transitionTitle: string,\n fallbackIndex: number\n): number {\n const normalizedTitle = normalizeLabel(transitionTitle)\n if (!normalizedTitle) return fallbackIndex\n\n const contentsItems = customSlides\n .slice(0, currentSlideIndex + 1)\n .filter((slide): slide is Extract<CustomSlide, { type: 'contents' }> => slide.type === 'contents')\n .flatMap(slide => slide.data.items)\n\n for (let index = 0; index < contentsItems.length; index += 1) {\n const normalizedItem = normalizeLabel(contentsItems[index])\n if (!normalizedItem) continue\n if (\n normalizedItem === normalizedTitle ||\n normalizedItem.includes(normalizedTitle) ||\n normalizedTitle.includes(normalizedItem)\n ) {\n return index + 1\n }\n }\n\n return fallbackIndex\n}\n\nexport const applyCustomContentToTemplate = (\n template: TemplateJson,\n CustomSlides: CustomSlide[]\n): TemplateJson => {\n const grouped = template.slides.reduce<Record<string, TemplateJsonSlide[]>>(\n (acc, slide) => {\n const key = slide.type || 'default'\n if (!acc[key]) acc[key] = []\n acc[key].push(slide)\n return acc\n },\n {}\n )\n\n const usage = new Map<string, number>()\n const getTextTypeCount = (slide: TemplateJsonSlide, textType: string) =>\n slide.elements.filter(\n element => element.type === 'text' && element.textType === textType\n ).length\n\n const getContentCapacity = (slide: TemplateJsonSlide) => {\n const titleSlots = getTextTypeCount(slide, 'itemTitle')\n const itemSlots = getTextTypeCount(slide, 'item')\n return Math.min(titleSlots, itemSlots)\n }\n\n const pickFromPool = (key: string, pool: TemplateJsonSlide[]) => {\n const index = usage.get(key) ?? 0\n usage.set(key, index + 1)\n return cloneSlide(pool[index % pool.length])\n }\n\n const pickSlide = (type: string, desiredCount?: number) => {\n const pool = grouped[type] || grouped.default || template.slides\n if (desiredCount == null || pool.length === 1) {\n return pickFromPool(type, pool)\n }\n\n const scored = pool.map(slide => {\n const capacity =\n type === 'content'\n ? getContentCapacity(slide)\n : getTextTypeCount(slide, 'item')\n return { slide, capacity }\n })\n const eligible = scored.filter(item => item.capacity >= desiredCount)\n if (eligible.length > 0) {\n const minCapacity = Math.min(...eligible.map(item => item.capacity))\n const best = eligible\n .filter(item => item.capacity === minCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, best)\n }\n const maxCapacity = Math.max(...scored.map(item => item.capacity))\n const fallback = scored\n .filter(item => item.capacity === maxCapacity)\n .map(item => item.slide)\n return pickFromPool(`${type}:${desiredCount}`, fallback)\n }\n\n let transitionIndex = 0\n const slides = CustomSlides.map((item, index) => {\n const desiredCount =\n item.type === 'contents'\n ? item.data.items.length\n : item.type === 'content'\n ? item.data.items.length\n : undefined\n const slide = pickSlide(item.type, desiredCount)\n if (item.type === 'cover') {\n applyCoverData(slide, item.data)\n } else if (item.type === 'contents') {\n applyContentsData(slide, item.data)\n } else if (item.type === 'transition') {\n transitionIndex += 1\n const partNumber = resolveTransitionIndex(\n CustomSlides,\n index,\n item.data.title,\n transitionIndex\n )\n applyTransitionData(slide, item.data, partNumber)\n } else if (item.type === 'content') {\n applyContentData(slide, item.data)\n }\n return slide\n })\n\n return {\n ...template,\n slides\n }\n}\n","import { parseDocument } from 'json2pptx-schema'\nimport type {\n Deck,\n PptxCustomThemeInput,\n Slide,\n SlideElement,\n ThemeLogoPosition,\n ThemeScope,\n ThemeScopeKey\n} from '../types'\nimport { parseColorToRgb } from './color-utils'\nimport { applyTheme2Json } from './theme-applier'\n\nconst FALLBACK_SLIDE_WIDTH = 1000\nconst FALLBACK_SLIDE_HEIGHT = 562.5\nconst LOGO_MARGIN_X = 24\nconst LOGO_MARGIN_Y = 18\nconst LOGO_MAX_WIDTH_RATIO = 0.34\nconst LOGO_MAX_HEIGHT_RATIO = 0.16\nconst DEFAULT_LOGO_ASPECT_RATIO = 3.2\n\nfunction mapSlideTypeToScopeKey (type?: string): ThemeScopeKey | null {\n const normalized = type?.trim().toLowerCase()\n if (!normalized) return null\n\n if (normalized === 'cover') return 'cover'\n if (normalized === 'contents' || normalized === 'agenda') return 'contents'\n if (normalized === 'transition' || normalized === 'section') return 'transition'\n if (normalized === 'content') return 'content'\n if (normalized === 'end' || normalized === 'ending') return 'end'\n\n return null\n}\n\nfunction isSlideInScope (slide: Slide, scope: ThemeScope): boolean {\n const key = mapSlideTypeToScopeKey(slide.type)\n if (!key) return false\n return Boolean(scope[key])\n}\n\nfunction createElementId (prefix: string, slideIndex: number): string {\n const random = Math.random().toString(36).slice(2, 10)\n return `${prefix}-${slideIndex}-${random}`\n}\n\nfunction toHalfOpacityColor (value: string): string {\n const rgb = parseColorToRgb(value)\n if (!rgb) return value\n return `rgba(${rgb.r},${rgb.g},${rgb.b},0.5)`\n}\n\nfunction buildBackgroundElement (\n src: string,\n slideWidth: number,\n slideHeight: number,\n slideIndex: number\n): SlideElement {\n return {\n type: 'image',\n id: createElementId('background', slideIndex),\n src,\n width: slideWidth,\n height: slideHeight,\n left: 0,\n top: 0,\n fixedRatio: true,\n rotate: 0,\n imageType: 'background',\n filters: {\n opacity: '100%'\n }\n }\n}\n\nfunction buildLogoElement (\n src: string,\n slideWidth: number,\n slideHeight: number,\n position: ThemeLogoPosition,\n slideIndex: number,\n logoWidth?: number,\n logoHeight?: number\n): SlideElement {\n const aspectRatio = resolveLogoAspectRatio(logoWidth, logoHeight)\n const maxWidth = slideWidth * LOGO_MAX_WIDTH_RATIO\n const maxHeight = slideHeight * LOGO_MAX_HEIGHT_RATIO\n let width = maxWidth\n let height = width / aspectRatio\n if (height > maxHeight) {\n height = maxHeight\n width = height * aspectRatio\n }\n const left =\n position === 'left'\n ? LOGO_MARGIN_X\n : Math.max(LOGO_MARGIN_X, slideWidth - width - LOGO_MARGIN_X)\n\n return {\n type: 'image',\n id: createElementId('logo', slideIndex),\n src,\n width,\n height,\n left,\n top: LOGO_MARGIN_Y,\n fixedRatio: true,\n rotate: 0,\n imageType: 'logo'\n }\n}\n\nfunction resolveLogoAspectRatio (\n width?: number,\n height?: number\n): number {\n if (\n typeof width === 'number' &&\n typeof height === 'number' &&\n width > 0 &&\n height > 0\n ) {\n return width / height\n }\n return DEFAULT_LOGO_ASPECT_RATIO\n}\n\nfunction replaceScopedMedia (deck: Deck, input: PptxCustomThemeInput): Deck {\n if (!deck.slides?.length) return deck\n\n const slideWidth = deck.width ?? FALLBACK_SLIDE_WIDTH\n const slideHeight = deck.height ?? FALLBACK_SLIDE_HEIGHT\n const backgroundInput = input.backgroundImage\n const logoInput = input.logoImage\n const shouldClearBackground = Boolean(input.clearBackgroundImage)\n const shouldClearLogo = Boolean(input.clearLogoImage || shouldClearBackground)\n\n if (\n !backgroundInput?.src &&\n !logoInput?.src &&\n !shouldClearBackground &&\n !shouldClearLogo\n ) {\n return deck\n }\n\n const slides = deck.slides.map((slide, slideIndex) => {\n let nextElements = slide.elements ? [...slide.elements] : []\n let nextBackground = slide.background\n let changed = false\n\n if (shouldClearBackground) {\n const before = nextElements.length\n nextElements = nextElements.filter(\n element => !(element.type === 'image' && element.imageType === 'background')\n )\n if (nextElements.length !== before) {\n changed = true\n if (input.backgroundColor) {\n nextBackground = {\n ...(nextBackground ?? {}),\n type: 'solid',\n color: input.backgroundColor\n }\n }\n }\n }\n\n if (shouldClearLogo) {\n const before = nextElements.length\n nextElements = nextElements.filter(\n element => !(element.type === 'image' && element.imageType === 'logo')\n )\n if (nextElements.length !== before) {\n changed = true\n }\n }\n\n if (backgroundInput?.src && isSlideInScope(slide, backgroundInput.scope)) {\n const withoutBackground = nextElements.filter(\n element => !(element.type === 'image' && element.imageType === 'background')\n )\n nextElements = [\n buildBackgroundElement(\n backgroundInput.src,\n slideWidth,\n slideHeight,\n slideIndex\n ),\n ...withoutBackground\n ]\n changed = true\n\n if (input.backgroundColor) {\n nextBackground = {\n ...(nextBackground ?? {}),\n type: 'solid',\n color: toHalfOpacityColor(input.backgroundColor)\n }\n }\n }\n\n if (logoInput?.src && isSlideInScope(slide, logoInput.scope)) {\n const withoutLogo = nextElements.filter(\n element => !(element.type === 'image' && element.imageType === 'logo')\n )\n nextElements = [\n ...withoutLogo,\n buildLogoElement(\n logoInput.src,\n slideWidth,\n slideHeight,\n logoInput.position,\n slideIndex,\n logoInput.width,\n logoInput.height\n )\n ]\n changed = true\n }\n\n if (!changed && nextBackground === slide.background) return slide\n\n return {\n ...slide,\n ...(changed ? { elements: nextElements } : {}),\n ...(nextBackground ? { background: nextBackground } : {})\n }\n })\n\n return { ...deck, slides }\n}\n\nexport function applyCustomTheme (\n deck: Deck,\n input: PptxCustomThemeInput\n): Deck {\n const normalizedDeck = parseDocument(deck) as unknown as Deck\n const withColors = applyTheme2Json(normalizedDeck, input)\n const withMedia = replaceScopedMedia(withColors, input)\n return parseDocument(withMedia) as unknown as Deck\n}\n\nexport { applyTheme2Json }\n","import type { ColorMapping, RGB } from './types'\n\nexport function normalizeHexColor (value: string): string | null {\n const raw = value.trim()\n const withHash = raw.startsWith('#') ? raw.slice(1) : raw\n if (withHash.length !== 3 && withHash.length !== 6) return null\n if (!/^[0-9a-fA-F]+$/.test(withHash)) return null\n const expanded =\n withHash.length === 3\n ? withHash\n .split('')\n .map((char) => char + char)\n .join('')\n : withHash\n return `#${expanded.toUpperCase()}`\n}\n\nexport function parseColorToRgb (\n value: string\n): (RGB & { alpha?: number }) | null {\n const hex = normalizeHexColor(value)\n if (hex) {\n const raw = hex.slice(1)\n const r = Number.parseInt(raw.slice(0, 2), 16)\n const g = Number.parseInt(raw.slice(2, 4), 16)\n const b = Number.parseInt(raw.slice(4, 6), 16)\n return { r, g, b }\n }\n\n const match = value.match(\n /rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)/i\n )\n if (!match) return null\n const r = Math.round(Number(match[1]))\n const g = Math.round(Number(match[2]))\n const b = Math.round(Number(match[3]))\n const alpha = match[4] !== undefined ? Number(match[4]) : undefined\n return {\n r,\n g,\n b,\n ...(Number.isFinite(alpha) ? { alpha } : {})\n }\n}\n\nexport function normalizeThemeColor (value: string): string | null {\n const hex = normalizeHexColor(value)\n if (hex) return hex\n const parsed = parseColorToRgb(value)\n if (!parsed) return null\n if (parsed.alpha !== undefined) {\n return `rgba(${parsed.r},${parsed.g},${parsed.b},${parsed.alpha})`\n }\n return `rgb(${parsed.r},${parsed.g},${parsed.b})`\n}\n\nexport function isPureColorString (value: string): boolean {\n const trimmed = value.trim()\n if (!trimmed) return false\n if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(trimmed)) return true\n return /^rgba?\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*,\\s*([0-9.]+)\\s*(?:,\\s*([0-9.]+)\\s*)?\\)$/i.test(\n trimmed\n )\n}\n\nfunction normalizeColorKey (value?: string): string | null {\n if (!value) return null\n const trimmed = value.trim()\n if (!trimmed) return null\n const parsed = parseColorToRgb(trimmed)\n if (parsed) {\n return `${parsed.r},${parsed.g},${parsed.b},${parsed.alpha ?? 'none'}`\n }\n const hex = normalizeHexColor(trimmed)\n if (hex) return hex\n return trimmed.toLowerCase()\n}\n\nexport function colorsEqual (a: string, b: string): boolean {\n const aKey = normalizeColorKey(a)\n const bKey = normalizeColorKey(b)\n if (!aKey || !bKey) return false\n return aKey === bKey\n}\n\nexport function isWhiteColor (value?: string): boolean {\n const key = normalizeColorKey(value)\n if (!key) return false\n return (\n key === '#FFFFFF' ||\n key === '255,255,255,none' ||\n key === '255,255,255,1'\n )\n}\n\nexport function rgbToString (rgb: RGB): string {\n return `rgb(${rgb.r},${rgb.g},${rgb.b})`\n}\n\nexport function findMappingForColor (\n value: string,\n mappings: ColorMapping[]\n): ColorMapping | undefined {\n const parsed = parseColorToRgb(value)\n if (!parsed) return undefined\n return mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n}\n","import { normalizeHexColor, parseColorToRgb } from './color-utils'\nimport type { ColorMapping } from './types'\n\nexport function buildColorMappings (\n previous: string[],\n next: string[]\n): ColorMapping[] {\n const mappings: ColorMapping[] = []\n const length = Math.min(previous.length, next.length)\n for (let i = 0; i < length; i += 1) {\n const fromParsed = parseColorToRgb(previous[i])\n const toParsed = parseColorToRgb(next[i])\n if (!fromParsed || !toParsed) continue\n const toHex = normalizeHexColor(next[i]) ?? undefined\n mappings.push({\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n })\n }\n return mappings\n}\n\nexport function buildSingleMapping (\n from?: string,\n to?: string\n): ColorMapping | null {\n if (!from || !to) return null\n const fromParsed = parseColorToRgb(from)\n const toParsed = parseColorToRgb(to)\n if (!fromParsed || !toParsed) return null\n const toHex = normalizeHexColor(to) ?? undefined\n return {\n fromRgb: { r: fromParsed.r, g: fromParsed.g, b: fromParsed.b },\n toRgb: { r: toParsed.r, g: toParsed.g, b: toParsed.b },\n toHex\n }\n}\n","import type { Slide, SlideElement } from '../types'\nimport {\n findMappingForColor,\n isPureColorString,\n normalizeThemeColor,\n parseColorToRgb,\n rgbToString\n} from './color-utils'\nimport type { ColorMapping } from './types'\n\nfunction applyFontColorToHtml (value: string, fontColor: string): string {\n if (!value || !fontColor) return value\n const normalized = normalizeThemeColor(fontColor) ?? fontColor\n const hasStyleColor = /\\bcolor\\s*:/i.test(value)\n if (hasStyleColor) {\n return value.replace(/color\\s*:\\s*([^;\"']+)/gi, () => `color: ${normalized}`)\n }\n return value.replace(\n /(<[^>]+style\\s*=\\s*[\"'])([^\"']*)([\"'])/gi,\n (_match, start, styles, end) => {\n if (/\\bcolor\\s*:/i.test(styles)) return _match\n const nextStyles = styles.trim()\n ? `${styles.trim()}; color: ${normalized}`\n : `color: ${normalized}`\n return `${start}${nextStyles}${end}`\n }\n )\n}\n\nfunction replaceColorValue (value: string, mappings: ColorMapping[]): string {\n const mapping = findMappingForColor(value, mappings)\n if (!mapping) return value\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n if (parsed.alpha !== undefined) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceRgbaString (value: string, mappings: ColorMapping[]): string {\n const parsed = parseColorToRgb(value)\n if (!parsed) return value\n const mapping = mappings.find(\n (item) =>\n item.fromRgb.r === parsed.r &&\n item.fromRgb.g === parsed.g &&\n item.fromRgb.b === parsed.b\n )\n if (!mapping) return value\n if (parsed.alpha !== undefined || value.toLowerCase().startsWith('rgba')) {\n return `rgba(${mapping.toRgb.r},${mapping.toRgb.g},${mapping.toRgb.b},${parsed.alpha ?? 1})`\n }\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n}\n\nfunction replaceColorsInText (value: string, mappings: ColorMapping[]): string {\n let next = value\n next = next.replace(/#([0-9a-f]{3}|[0-9a-f]{6})/gi, (match) => {\n const mapping = findMappingForColor(match, mappings)\n if (!mapping) return match\n return mapping.toHex ?? rgbToString(mapping.toRgb)\n })\n next = next.replace(/rgba?\\([^)]*\\)/gi, (match) =>\n replaceRgbaString(match, mappings)\n )\n return next\n}\n\nfunction replaceColorsDeep (value: unknown, mappings: ColorMapping[]): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim()\n const pureColor = isPureColorString(trimmed)\n if (pureColor) {\n const replaced = replaceColorValue(trimmed, mappings)\n return value === trimmed ? replaced : value.replace(trimmed, replaced)\n }\n return replaceColorsInText(value, mappings)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => replaceColorsDeep(item, mappings))\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n const next: Record<string, unknown> = {}\n for (const [key, item] of entries) {\n next[key] = replaceColorsDeep(item, mappings)\n }\n return next\n }\n\n return value\n}\n\nfunction replaceTextElementColors (\n element: SlideElement,\n fontMappings: ColorMapping[],\n fontColor: string\n): SlideElement {\n const next = replaceColorsDeep(element, fontMappings) as SlideElement\n const normalizedFontColor = normalizeThemeColor(fontColor) ?? fontColor\n const withDefault =\n normalizedFontColor && 'defaultColor' in next\n ? { ...next, defaultColor: normalizedFontColor }\n : next\n if (!('content' in withDefault) || typeof withDefault.content !== 'string') {\n return withDefault\n }\n return {\n ...withDefault,\n content: applyFontColorToHtml(withDefault.content, normalizedFontColor)\n }\n}\n\nexport function replaceSlideColors (\n slide: Slide,\n themeMappings: ColorMapping[],\n fontMappings: ColorMapping[],\n fontColor: string\n): Slide {\n const { elements, ...rest } = slide\n const nextSlide = replaceColorsDeep(rest, themeMappings) as Slide\n if (!elements) return nextSlide\n\n const nextElements: SlideElement[] = elements.map((element) => {\n if (element && typeof element === 'object' && element.type === 'text') {\n return replaceTextElementColors(element, fontMappings, fontColor)\n }\n return replaceColorsDeep(element, themeMappings) as SlideElement\n })\n\n return { ...nextSlide, elements: nextElements }\n}\n","import type { Deck, PptxCustomThemeInput } from '../types'\nimport { colorsEqual, isWhiteColor } from './color-utils'\nimport { buildColorMappings, buildSingleMapping } from './mappings'\nimport { replaceSlideColors } from './replacers'\n\nexport function applyTheme2Json (deck: Deck, update: PptxCustomThemeInput): Deck {\n const previousTheme = deck.theme ?? {}\n const themeColors = update.themeColors.slice(0, 6)\n const themeMappings = buildColorMappings(\n previousTheme.themeColors ?? [],\n themeColors\n )\n const fontMapping = buildSingleMapping(\n previousTheme.fontColor,\n update.fontColor\n )\n const fontMappings = fontMapping ? [fontMapping] : []\n\n const nextBackground = update.backgroundColor ?? previousTheme.backgroundColor\n const prevBackground = previousTheme.backgroundColor\n const slides = deck.slides?.map((slide) => {\n const nextSlide = replaceSlideColors(\n slide,\n themeMappings,\n fontMappings,\n update.fontColor\n )\n if (!nextBackground) return nextSlide\n const currentColor = nextSlide.background?.color\n const shouldUpdate =\n !currentColor ||\n (prevBackground && colorsEqual(currentColor, prevBackground)) ||\n (!prevBackground && isWhiteColor(currentColor))\n if (!shouldUpdate) return nextSlide\n return {\n ...nextSlide,\n background: {\n ...(nextSlide.background ?? {}),\n type: nextSlide.background?.type ?? 'solid',\n color: nextBackground\n }\n }\n })\n\n return {\n ...deck,\n theme: {\n ...previousTheme,\n themeColors,\n fontColor: update.fontColor,\n backgroundColor: update.backgroundColor ?? previousTheme.backgroundColor\n },\n slides\n }\n}\n"],"mappings":"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","names":["parseDocument","r","g","b","FALLBACK_SLIDE_WIDTH","FALLBACK_SLIDE_HEIGHT","LOGO_MARGIN_X","LOGO_MARGIN_Y","LOGO_MAX_WIDTH_RATIO","LOGO_MAX_HEIGHT_RATIO","parseDocument"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pptx-custom",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Custom content and theme utilities for PPTX JSON templates.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.cjs",
@@ -38,7 +38,7 @@
38
38
  "prepublishOnly": "pnpm run build"
39
39
  },
40
40
  "dependencies": {
41
- "json2pptx-schema": "0.1.0"
41
+ "json2pptx-schema": "0.1.1"
42
42
  },
43
43
  "devDependencies": {
44
44
  "tsup": "^8.5.1",