From 431a03690ed131e4bb925cec465d91adfb0d9421 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 30 Sep 2024 18:26:59 -0400
Subject: fixed so that you can't set the author field from the schema view.
 fixed schema view to not trigger cell updates after cells have been unmounted
 (e.g, so that dragging a tab over a schema vew doesn't crash)

---
 .../views/nodes/DataVizBox/DocCreatorMenu.tsx      | 2115 +++++++++++---------
 1 file changed, 1129 insertions(+), 986 deletions(-)

(limited to 'src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx')

diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
index 5d5c35dce..32aded9de 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
@@ -1,50 +1,42 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { Colors } from 'browndash-components';
+import { action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
+import { IDisposer } from 'mobx-utils';
 import * as React from 'react';
-import { ClientUtils, returnAll, returnFalse, returnNone, returnOne, returnZero, setupMoveUpEvents } from '../../../../ClientUtils';
+import ReactLoading from 'react-loading';
+import { ClientUtils, returnFalse, setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction } from '../../../../Utils';
 import { Doc, NumListCast, StrListCast } from '../../../../fields/Doc';
-import { DocCast, ImageCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { Id } from '../../../../fields/FieldSymbols';
+import { DocCast, ImageCast, StrCast } from '../../../../fields/Types';
 import { ImageField } from '../../../../fields/URLField';
-import { emptyFunction } from '../../../../Utils';
+import { Networking } from '../../../Network';
+import { GPTCallType, gptAPICall, gptImageCall } from '../../../apis/gpt/GPT';
+import { Docs } from '../../../documents/Documents';
+import { DragManager } from '../../../util/DragManager';
+import { MakeTemplate } from '../../../util/DropConverter';
 import { SnappingManager } from '../../../util/SnappingManager';
 import { UndoManager, undoable } from '../../../util/UndoManager';
+import { LightboxView } from '../../LightboxView';
 import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView';
 import { DocumentView, DocumentViewInternal } from '../DocumentView';
+import { FieldViewProps } from '../FieldView';
+import { OpenWhere } from '../OpenWhere';
 import { DataVizBox } from './DataVizBox';
 import './DocCreatorMenu.scss';
-import { Id } from '../../../../fields/FieldSymbols';
-import { Colors, IconButton, Size } from 'browndash-components';
-import { MakeTemplate } from '../../../util/DropConverter';
-import { DragManager } from '../../../util/DragManager';
-import { GPTCallType, gptAPICall, gptImageCall } from '../../../apis/gpt/GPT';
-import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView';
-import { Docs } from '../../../documents/Documents';
-import { OpenWhere } from '../OpenWhere';
-import { IDisposer } from 'mobx-utils';
-import { LightboxView } from '../../LightboxView';
-import ReactLoading from 'react-loading';
-import { CollectionStackingView } from '../../collections/CollectionStackingView';
-import { FieldViewProps } from '../FieldView';
-import { CollectionViewType } from '../../../documents/DocumentTypes';
-import { dropActionType } from '../../../util/DropActionTypes';
-import { ImageBox } from '../ImageBox';
-import { a } from '@react-spring/web';
-import { RichTextMenu } from '../formattedText/RichTextMenu';
-import e from 'cors';
-import { Networking } from '../../../Network';
 
 export enum LayoutType {
-    Stacked = 'stacked', 
-    Grid = 'grid', 
-    Row = 'row', 
-    Column = 'column', 
-    Custom = 'custom'
+    Stacked = 'stacked',
+    Grid = 'grid',
+    Row = 'row',
+    Column = 'column',
+    Custom = 'custom',
 }
 
 @observer
 export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
-
     static Instance: DocCreatorMenu;
 
     private _disposers: { [name: string]: IDisposer } = {};
@@ -54,13 +46,13 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     @observable _templateDocs: Doc[] = [];
     @observable _selectedTemplate: Doc | undefined = undefined;
     @observable _columns: Col[] = [];
-    @observable _selectedCols: {title: string, type: string, desc: string}[] | undefined = [];
+    @observable _selectedCols: { title: string; type: string; desc: string }[] | undefined = [];
 
-    @observable _layout: {type: LayoutType, yMargin: number, xMargin: number, columns?: number, repeat: number} = {type: LayoutType.Grid, yMargin: 0, xMargin: 0, repeat: 0};
+    @observable _layout: { type: LayoutType; yMargin: number; xMargin: number; columns?: number; repeat: number } = { type: LayoutType.Grid, yMargin: 0, xMargin: 0, repeat: 0 };
     @observable _layoutPreview: boolean = true;
     @observable _layoutPreviewScale: number = 1;
     @observable _savedLayouts: DataVizTemplateLayout[] = [];
-    @observable _expandedPreview: {icon: ImageField, doc: Doc} | undefined = undefined;
+    @observable _expandedPreview: { icon: ImageField; doc: Doc } | undefined = undefined;
 
     @observable _suggestedTemplates: Doc[] = [];
     @observable _GPTOpt: boolean = false;
@@ -76,7 +68,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     @observable _hoveredLayoutPreview: number | undefined = undefined;
     @observable _mouseX: number = -1;
     @observable _mouseY: number = -1;
-    @observable _startPos?: {x: number, y: number};
+    @observable _startPos?: { x: number; y: number };
     @observable _shouldDisplay: boolean = false;
 
     @observable _menuContent: 'templates' | 'options' | 'saved' | 'dashboard' = 'templates';
@@ -87,10 +79,10 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     @observable _snapPt: any;
     @observable _resizeHdlId: string = '';
     @observable _resizing: boolean = false;
-    @observable _offset: {x: number, y: number} = {x: 0, y: 0};
+    @observable _offset: { x: number; y: number } = { x: 0, y: 0 };
     @observable _resizeUndo: UndoManager.Batch | undefined = undefined;
-    @observable _initDimensions: {width: number, height: number, x?: number, y?: number} = {width: 300, height: 400, x: undefined, y: undefined};
-    @observable _menuDimensions: {width: number, height: number} = {width: 400, height: 400};
+    @observable _initDimensions: { width: number; height: number; x?: number; y?: number } = { width: 300, height: 400, x: undefined, y: undefined };
+    @observable _menuDimensions: { width: number; height: number } = { width: 400, height: 400 };
     @observable _editing: boolean = false;
 
     constructor(props: any) {
@@ -100,32 +92,40 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         //setTimeout(() => this.generateTemplates(''));
     }
 
-    @action setDataViz = (dataViz: DataVizBox) => { this._dataViz = dataViz };
-    @action setTemplateDocs = (docs: Doc[]) => {this._templateDocs = docs.map(doc => doc.annotationOn ? DocCast(doc.annotationOn):doc)};
-    @action setGSuggestedTemplates = (docs: Doc[]) => {this._suggestedTemplates = docs};
+    @action setDataViz = (dataViz: DataVizBox) => {
+        this._dataViz = dataViz;
+    };
+    @action setTemplateDocs = (docs: Doc[]) => {
+        this._templateDocs = docs.map(doc => (doc.annotationOn ? DocCast(doc.annotationOn) : doc));
+    };
+    @action setGSuggestedTemplates = (docs: Doc[]) => {
+        this._suggestedTemplates = docs;
+    };
 
     @computed get docsToRender() {
         return this._selectedTemplate ? NumListCast(this._dataViz?.layoutDoc.dataViz_selectedRows) : [];
     }
 
-    @computed get rowsCount(){
+    @computed get rowsCount() {
         switch (this._layout.type) {
-            case LayoutType.Row: case LayoutType.Stacked: 
+            case LayoutType.Row:
+            case LayoutType.Stacked:
                 return 1;
             case LayoutType.Column:
                 return this.docsToRender.length;
             case LayoutType.Grid:
                 return Math.ceil(this.docsToRender.length / (this._layout.columns ?? 1)) ?? 0;
-            default: 
+            default:
                 return 0;
         }
     }
 
-    @computed get columnsCount(){
+    @computed get columnsCount() {
         switch (this._layout.type) {
             case LayoutType.Row:
                 return this.docsToRender.length;
-            case LayoutType.Column: case LayoutType.Stacked: 
+            case LayoutType.Column:
+            case LayoutType.Stacked:
                 return 1;
             case LayoutType.Grid:
                 return this._layout.columns ?? 0;
@@ -140,31 +140,33 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
     @computed get fieldsInfos(): Col[] {
         const colInfo = this._dataViz?.colsInfo;
-        return this.selectedFields.map(field => {
-            const fieldInfo = colInfo?.get(field);
-
-            const col: Col = {
-                title: field,
-                type: fieldInfo?.type ?? TemplateFieldType.UNSET,
-                desc: fieldInfo?.desc ?? '',
-                sizes: fieldInfo?.sizes ?? [TemplateFieldSize.MEDIUM]
-            };
-
-            if (fieldInfo?.defaultContent !== undefined) {
-                col.defaultContent = fieldInfo.defaultContent;
-            }
+        return this.selectedFields
+            .map(field => {
+                const fieldInfo = colInfo?.get(field);
+
+                const col: Col = {
+                    title: field,
+                    type: fieldInfo?.type ?? TemplateFieldType.UNSET,
+                    desc: fieldInfo?.desc ?? '',
+                    sizes: fieldInfo?.sizes ?? [TemplateFieldSize.MEDIUM],
+                };
+
+                if (fieldInfo?.defaultContent !== undefined) {
+                    col.defaultContent = fieldInfo.defaultContent;
+                }
 
-            return col;
-        }).concat(this._columns);
+                return col;
+            })
+            .concat(this._columns);
     }
 
-    @computed get canMakeDocs(){
+    @computed get canMakeDocs() {
         return this._selectedTemplate !== undefined && this._layout !== undefined;
     }
 
-    get bounds(): {t: number, b: number, l: number, r: number} {
+    get bounds(): { t: number; b: number; l: number; r: number } {
         const rect = this._ref?.getBoundingClientRect();
-        const bounds = {t: rect?.top ?? 0, b: rect?.bottom ?? 0, l: rect?.left ?? 0, r: rect?.right ?? 0};
+        const bounds = { t: rect?.top ?? 0, b: rect?.bottom ?? 0, l: rect?.left ?? 0, r: rect?.right ?? 0 };
         return bounds;
     }
 
@@ -179,8 +181,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                 clickEv.preventDefault();
                 func();
             }, 'create docs')
-        )
-    }
+        );
+    };
 
     @action
     onPointerDown = (e: PointerEvent) => {
@@ -214,10 +216,21 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     componentDidMount() {
         document.addEventListener('pointerdown', this.onPointerDown, true);
         document.addEventListener('pointerup', this.onPointerUp);
-        this._disposers.templates = reaction(() => this._templateDocs.slice(), (docs) => docs.map(this.getIcon));
-        this._disposers.gpt = reaction(() => this._suggestedTemplates.slice(), (docs) => docs.map(this.getIcon));
+        this._disposers.templates = reaction(
+            () => this._templateDocs.slice(),
+            docs => docs.map(this.getIcon)
+        );
+        this._disposers.gpt = reaction(
+            () => this._suggestedTemplates.slice(),
+            docs => docs.map(this.getIcon)
+        );
         //this._disposers.columns = reaction(() => this._dataViz?.layoutDoc._dataViz_axes, () => {this.generateTemplates('')})
-        this._disposers.lightbox = reaction(() => LightboxView.LightboxDoc(), doc => { doc ? this._shouldDisplay && this.closeMenu() : !this._shouldDisplay && this.openMenu()});
+        this._disposers.lightbox = reaction(
+            () => LightboxView.LightboxDoc(),
+            doc => {
+                doc ? this._shouldDisplay && this.closeMenu() : !this._shouldDisplay && this.openMenu();
+            }
+        );
         //this._disposers.fields = reaction(() => this._dataViz?.axes, cols => this._selectedCols = cols?.map(col => { return {title: col, type: '', desc: ''}}))
     }
 
@@ -227,12 +240,14 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         document.removeEventListener('pointerup', this.onPointerUp);
     }
 
-    updateIcons = (docs: Doc[]) => { docs.map(this.getIcon) }
+    updateIcons = (docs: Doc[]) => {
+        docs.map(this.getIcon);
+    };
 
     @action
     updateSelectedCols = (cols: string[]) => {
-        this._selectedCols
-    }
+        this._selectedCols;
+    };
 
     @action
     toggleDisplay = (x: number, y: number) => {
@@ -246,10 +261,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     };
 
     @action
-    closeMenu = () => { this._shouldDisplay = false };
+    closeMenu = () => {
+        this._shouldDisplay = false;
+    };
 
     @action
-    openMenu = () => { 
+    openMenu = () => {
         const allTemplates = this._templateDocs.concat(this._suggestedTemplates);
         this._shouldDisplay = true;
         this.updateIcons(allTemplates);
@@ -285,7 +302,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         await new Promise<any>(res => { setTimeout(() => { res(this._interactionLock = undefined)})});
         }); // prettier-ignore
         return true;
-    }
+    };
 
     @action
     onDrag = (e: any): boolean => {
@@ -294,12 +311,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         this._initDimensions.x = this._pageX;
         this._initDimensions.y = this._pageY;
         return true;
-    }
+    };
 
     getResizeVals = (thisPt: { x: number; y: number }, dragHdl: string) => {
         const [w, h] = [this._initDimensions.width, this._initDimensions.height];
         const [moveX, moveY] = [thisPt.x - this._snapPt.x, thisPt.y - this._snapPt.y];
-        let vals: {scale: {x: number, y: number}, refPt: [number, number], transl: {x: number, y: number}};
+        let vals: { scale: { x: number; y: number }; refPt: [number, number]; transl: { x: number; y: number } };
         switch (dragHdl) {
             case 'topLeft':    vals = { scale: { x: 1 - moveX / w, y: 1 -moveY / h },  refPt: [this.bounds.r, this.bounds.b], transl: {x: moveX, y: moveY } }; break;
             case 'topRight':   vals = { scale: { x: 1 + moveX / w, y: 1 -moveY / h },  refPt: [this.bounds.l, this.bounds.b], transl: {x: 0, y: moveY } }; break;
@@ -314,11 +331,11 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         return vals;
     };
 
-    resizeView = (refPt: number[], scale: { x: number; y: number }, translation: {x: number, y: number}) => {
-        const refCent = [refPt[0], refPt[1]] // fixed reference point for resize (ie, a point that doesn't move)
+    resizeView = (refPt: number[], scale: { x: number; y: number }, translation: { x: number; y: number }) => {
+        const refCent = [refPt[0], refPt[1]]; // fixed reference point for resize (ie, a point that doesn't move)
         if (this._initDimensions.x === undefined) this._initDimensions.x = this._pageX;
         if (this._initDimensions.y === undefined) this._initDimensions.y = this._pageY;
-        const {height, width, x, y} = this._initDimensions;
+        const { height, width, x, y } = this._initDimensions;
 
         this._menuDimensions.width = Math.max(300, scale.x * width);
         this._menuDimensions.height = Math.max(200, scale.y * height);
@@ -330,10 +347,10 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const docView = DocumentView.getDocumentView(doc);
         if (docView) {
             docView.ComponentView?.updateIcon?.();
-            return new Promise<ImageField | undefined>(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 500));;
+            return new Promise<ImageField | undefined>(res => setTimeout(() => res(ImageCast(docView.Document.icon)), 500));
         }
         return undefined;
-    };
+    }
 
     @action updateSelectedTemplate = (template: Doc) => {
         if (this._selectedTemplate === template) {
@@ -353,10 +370,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     };
 
     isSelectedLayout = (layout: DataVizTemplateLayout) => {
-        return this._layout.xMargin === layout.layout.xMargin
-        && this._layout.yMargin === layout.layout.yMargin 
-        && this._layout.type === layout.layout.type 
-        && this._layout.columns === layout.columns;
+        return this._layout.xMargin === layout.layout.xMargin && this._layout.yMargin === layout.layout.yMargin && this._layout.type === layout.layout.type && this._layout.columns === layout.columns;
     };
 
     @action
@@ -365,7 +379,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const origCount = this._callCount;
 
         let prompt: string = `(#${origCount}) Please generate for the fields:`;
-        this.selectedFields?.forEach(field => prompt += ` ${field},`)
+        this.selectedFields?.forEach(field => (prompt += ` ${field},`));
         prompt += ` (-----NOT A FIELD-----) Additional prompt: ${inputText}`;
 
         this._GPTLoading = true;
@@ -375,37 +389,43 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
             if (res && this._callCount === origCount) {
                 this._suggestedTemplates = [];
-                const templates: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[] = JSON.parse(res);
+                const templates: { template_type: string; fieldVals: { title: string; tlx: string; tly: string; brx: string; bry: string }[] }[] = JSON.parse(res);
                 this.createGeneratedTemplates(templates, 500, 500);
             }
         } catch (err) {
             console.error(err);
-        } 
+        }
     };
 
     @action
-    createGeneratedTemplates = (layouts: {template_type: string, fieldVals: {title: string, tlx: string, tly: string, brx: string, bry: string}[]}[], tempWidth: number, tempHeight: number) => { 
+    createGeneratedTemplates = (layouts: { template_type: string; fieldVals: { title: string; tlx: string; tly: string; brx: string; bry: string }[] }[], tempWidth: number, tempHeight: number) => {
         const mainCollection = this._dataViz?.DocumentView?.().containerViewPath?.().lastElement()?.ComponentView as CollectionFreeFormView;
         const GPTTemplates: Doc[] = [];
 
         layouts.forEach(layout => {
             const fields: Doc[] = layout.fieldVals.map(field => {
-                const left: number = Number(field.tlx) * tempWidth / 2;    const top: number = Number(field.tly) * tempHeight / 2; //prettier-ignore
-                const right: number = Number(field.brx) * tempWidth / 2;   const bottom: number = Number(field.bry) * tempHeight / 2; //prettier-ignore
-                const height = bottom - top; 
-                const width = right - left; 
-                const doc = !field.title.includes('$$') ? Docs.Create.TextDocument('', { _height: height, _width: width, title: field.title, x: left, y: top, _text_fontSize: `${height/2}` }) : Docs.Create.ImageDocument('', { _height: height, _width: width, title: field.title.replace(/\$\$/g, ''), x: left, y: top });
+                const left: number = (Number(field.tlx) * tempWidth) / 2;
+                const top: number = Number(field.tly) * tempHeight / 2; //prettier-ignore
+                const right: number = (Number(field.brx) * tempWidth) / 2;
+                const bottom: number = Number(field.bry) * tempHeight / 2; //prettier-ignore
+                const height = bottom - top;
+                const width = right - left;
+                const doc = !field.title.includes('$$')
+                    ? Docs.Create.TextDocument('', { _height: height, _width: width, title: field.title, x: left, y: top, _text_fontSize: `${height / 2}` })
+                    : Docs.Create.ImageDocument('', { _height: height, _width: width, title: field.title.replace(/\$\$/g, ''), x: left, y: top });
                 return doc;
             });
 
             const template = Docs.Create.FreeformDocument(fields, { _height: tempHeight, _width: tempWidth, title: layout.template_type, x: 400000, y: 400000 });
 
             mainCollection.addDocument(template);
-            
+
             GPTTemplates.push(template);
         });
 
-        setTimeout(() => {this.setGSuggestedTemplates(GPTTemplates); /*GPTTemplates.forEach(template => mainCollection.removeDocument(template))*/}, 100);
+        setTimeout(() => {
+            this.setGSuggestedTemplates(GPTTemplates); /*GPTTemplates.forEach(template => mainCollection.removeDocument(template))*/
+        }, 100);
 
         this.forceUpdate();
     };
@@ -421,9 +441,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         this._templateDocs.splice(this._templateDocs.indexOf(doc), 1);
     };
 
-
-
-    testTemplate = async() => { 
+    testTemplate = async () => {
         // const temp = TemplateLayouts.FourField001;
         // const title: Doc = FieldFuncs.TextField({tl: temp.fields[0].tl, br: temp.fields[0].br}, temp.height, temp.width, 'title', 'Title', {backgroundColor: 'transparent'});
         // const image: Doc = FieldFuncs.ImageField({tl: temp.fields[1].tl, br: temp.fields[1].br}, temp.height, temp.width, 'title', '', {borderColor: '#159fe4', borderWidth: '10', cornerRounding: 10, rotation: 40});
@@ -453,7 +471,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         try {
             const res = await gptImageCall('Image of panda eating a cookie');
 
-            if (res){
+            if (res) {
                 const result = await Networking.PostToServer('/uploadRemoteImage', { sources: res });
 
                 console.log(result);
@@ -461,15 +479,14 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         } catch (e) {
             console.log(e);
         }
-        
     };
 
     @action addField = () => {
-        const newFields: Col[] = this._columns.concat([{title: '', type: TemplateFieldType.UNSET, desc: '', sizes: []}])
+        const newFields: Col[] = this._columns.concat([{ title: '', type: TemplateFieldType.UNSET, desc: '', sizes: [] }]);
         this._columns = newFields;
     };
 
-    @action removeField = (field: {title: string, type: string, desc: string}) => {
+    @action removeField = (field: { title: string; type: string; desc: string }) => {
         if (this._dataViz?.axes.includes(field.title)) {
             this._dataViz.selectAxes(this._dataViz.axes.filter(col => col !== field.title));
         } else {
@@ -483,11 +500,11 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             }
 
             if (this._columns.length === 1) {
-                this._columns = []  
+                this._columns = [];
             } else {
                 this._columns.splice(this._columns.indexOf(toRemove[0]), 1);
             }
-        }   
+        }
     };
 
     @action setColTitle = (column: Col, title: string) => {
@@ -530,13 +547,13 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         this.forceUpdate();
     };
 
-    generateGPTImage = async(prompt: string): Promise<string | undefined> => {
-        console.log(prompt)
+    generateGPTImage = async (prompt: string): Promise<string | undefined> => {
+        console.log(prompt);
 
         try {
             const res = await gptImageCall(prompt);
 
-            if (res){
+            if (res) {
                 const result = await Networking.PostToServer('/uploadRemoteImage', { sources: res });
                 const source = ClientUtils.prepend(result[0].accessPaths.agnostic.client);
                 return source;
@@ -544,12 +561,16 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         } catch (e) {
             console.log(e);
         }
-    }
+    };
 
     matchesForTemplate = (template: TemplateDocInfos, cols: Col[]): number[][] => {
-        const colMatchesField = (col: Col, field : Field) => { return field.sizes?.some(size => col.sizes?.includes(size)) && field.types?.includes(col.type) };
+        const colMatchesField = (col: Col, field: Field) => {
+            return field.sizes?.some(size => col.sizes?.includes(size)) && field.types?.includes(col.type);
+        };
 
-        const matches: number[][] = Array(template.fields.length).fill([]).map(() => []);
+        const matches: number[][] = Array(template.fields.length)
+            .fill([])
+            .map(() => []);
 
         template.fields.forEach((field, i) => {
             cols.forEach((col, v) => {
@@ -576,8 +597,8 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                 }
             }
             return false;
-        }
-    
+        };
+
         for (let v = 0; v < fieldsCt; ++v) {
             used.fill(false);
             augmentingPath(v);
@@ -592,7 +613,6 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         return count;
     };
 
-
     findValidTemplates = (cols: Col[], templates: TemplateDocInfos[]) => {
         let validTemplates: any[] = [];
         templates.forEach(template => {
@@ -602,7 +622,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             if (this.maxMatches(numFields, matches) === numFields) {
                 validTemplates.push(template.title);
             }
-        })
+        });
 
         validTemplates = validTemplates.map(title => TemplateLayouts.getTemplateByTitle(title));
 
@@ -613,12 +633,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
     //     if (field.subfields) {
     //         const doc = FieldFuncs.FreeformField({
-    //             tl: field.tl, 
-    //             br: field.br }, 
-    //             template.height, 
-    //             template.width, 
-    //             column.title, 
-    //             '', 
+    //             tl: field.tl,
+    //             br: field.br },
+    //             template.height,
+    //             template.width,
+    //             column.title,
+    //             '',
     //             field.opts
     //         );
 
@@ -634,10 +654,10 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     /**
      * Populates a preset template framework with content from a datavizbox or any AI-generated content.
      * @param template the preloaded template framework being filled in
-     * @param assignments a list of template field numbers (from top to bottom) and their assigned columns from the linked dataviz 
+     * @param assignments a list of template field numbers (from top to bottom) and their assigned columns from the linked dataviz
      * @returns a doc containing the fully rendered template
      */
-    fillPresetTemplate = async(template: TemplateDocInfos, assignments: {[field: string]: Col}): Promise<Doc> => {
+    fillPresetTemplate = async (template: TemplateDocInfos, assignments: { [field: string]: Col }): Promise<Doc> => {
         const wordLimit = (size: TemplateFieldSize) => {
             switch (size) {
                 case TemplateFieldSize.TINY:
@@ -650,44 +670,43 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                     return 50;
                 case TemplateFieldSize.HUGE:
                     return 100;
-                default: 
+                default:
                     return 10;
             }
-        }
+        };
 
-        const renderTextCalls = async(): Promise<Doc[]> => {
+        const renderTextCalls = async (): Promise<Doc[]> => {
             const rendered: Doc[] = [];
 
             if (GPTTextCalls.length) {
-
                 try {
                     const prompt = fieldContent + GPTTextAssignment;
-    
+
                     const res = await gptAPICall(prompt, GPTCallType.FILL);
-    
-                    if (res){
-    
-                        const assignments: {[title: string]: {number: string, content: string}} = JSON.parse(res);
+
+                    if (res) {
+                        const assignments: { [title: string]: { number: string; content: string } } = JSON.parse(res);
                         //console.log('assignments', GPTAssignments, 'assignment string', GPTAssignmentString, 'field content', fieldContent, 'response', res, 'assignments', assignments);
                         Object.entries(assignments).forEach(([title, info]) => {
                             const field: Field = template.fields[Number(info.number)];
                             const col = this.getColByTitle(title);
-    
-                            const doc = FieldUtils.TextField({
-                                tl: field.tl, 
-                                br: field.br }, 
-                                template.height, 
-                                template.width, 
-                                col.title, 
-                                info.content ?? '', 
+
+                            const doc = FieldUtils.TextField(
+                                {
+                                    tl: field.tl,
+                                    br: field.br,
+                                },
+                                template.height,
+                                template.width,
+                                col.title,
+                                info.content ?? '',
                                 field.opts
                             );
-    
+
                             rendered.push(doc);
                         });
-    
                     }
-                } catch(err) {
+                } catch (err) {
                     console.log(err);
                 }
             }
@@ -695,23 +714,25 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             return rendered;
         };
 
-        const createGeneratedImage = async(fieldNum: string, col: Col, prompt: string) => {
+        const createGeneratedImage = async (fieldNum: string, col: Col, prompt: string) => {
             const url = await this.generateGPTImage(prompt);
             const field: Field = template.fields[Number(fieldNum)];
-            const doc = FieldUtils.ImageField({
-                tl: field.tl, 
-                br: field.br }, 
-                template.height, 
-                template.width, 
-                col.title, 
-                url ?? '', 
+            const doc = FieldUtils.ImageField(
+                {
+                    tl: field.tl,
+                    br: field.br,
+                },
+                template.height,
+                template.width,
+                col.title,
+                url ?? '',
                 field.opts
             );
 
             return doc;
-        }
+        };
 
-        const renderImageCalls = async(): Promise<Doc[]> => {
+        const renderImageCalls = async (): Promise<Doc[]> => {
             const rendered: Doc[] = [];
             const calls = GPTIMGCalls;
 
@@ -719,24 +740,28 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
                 try {
                     const renderedImages: Doc[] = await Promise.all(
                         calls.map(async ([fieldNum, col]) => {
-                            const sysPrompt = 'Your job is to create a prompt for an AI image generator to help it generate an image based on existing content in a template and a user prompt. Your prompt should focus heavily on visual elements to help the image generator; avoid unecessary info that might distract it. ONLY INCLUDE THE PROMPT, NO OTHER TEXT OR EXPLANATION. The existing content is as follows: ' + fieldContent + ' **** The user prompt is: ' + col.desc;
-                            
+                            const sysPrompt =
+                                'Your job is to create a prompt for an AI image generator to help it generate an image based on existing content in a template and a user prompt. Your prompt should focus heavily on visual elements to help the image generator; avoid unecessary info that might distract it. ONLY INCLUDE THE PROMPT, NO OTHER TEXT OR EXPLANATION. The existing content is as follows: ' +
+                                fieldContent +
+                                ' **** The user prompt is: ' +
+                                col.desc;
+
                             const prompt = await gptAPICall(sysPrompt, GPTCallType.COMPLETEPROMPT);
                             console.log(sysPrompt, prompt);
-                            
+
                             return createGeneratedImage(fieldNum, col, prompt);
                         })
                     );
-                
+
                     const renderedTemplates: Doc[] = await Promise.all(renderedImages);
                     renderedTemplates.forEach(doc => rendered.push(doc));
-                } catch (e){
+                } catch (e) {
                     console.log(e);
                 }
             }
 
             return rendered;
-        }
+        };
 
         const fields: Doc[] = [];
 
@@ -748,9 +773,9 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const stringifyGPTInfo = (calls: [string, Col][]): string => {
             let string: string = '*** COLUMN INFO:';
             calls.forEach(([fieldNum, col]) => {
-                string += `--- title: ${col.title}, prompt: ${col.desc}, word limit: ${wordLimit(col.sizes[0])} words, assigned field: ${fieldNum} ---`
+                string += `--- title: ${col.title}, prompt: ${col.desc}, word limit: ${wordLimit(col.sizes[0])} words, assigned field: ${fieldNum} ---`;
             });
-            return string += ' ***';
+            return (string += ' ***');
         };
 
         const GPTTextAssignment = stringifyGPTInfo(GPTTextCalls);
@@ -761,45 +786,49 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             const field: Field = template.fields[Number(f)];
             const col = strCol[1];
 
-            const doc = (col.type === TemplateFieldType.VISUAL ? FieldUtils.ImageField : FieldUtils.TextField)({
-                tl: field.tl, 
-                br: field.br }, 
-                template.height, 
-                template.width, 
-                col.title, 
-                col.defaultContent ?? '', 
+            const doc = (col.type === TemplateFieldType.VISUAL ? FieldUtils.ImageField : FieldUtils.TextField)(
+                {
+                    tl: field.tl,
+                    br: field.br,
+                },
+                template.height,
+                template.width,
+                col.title,
+                col.defaultContent ?? '',
                 field.opts
             );
 
-            fieldContent += `--- Field #${f} (title: ${col.title}): ${col.defaultContent ?? ''} ---`
+            fieldContent += `--- Field #${f} (title: ${col.title}): ${col.defaultContent ?? ''} ---`;
 
             fields.push(doc);
         });
 
         template.decorations.forEach(dec => {
-            const doc = FieldUtils.FreeformField({
-                tl: dec.tl, 
-                br: dec.br }, 
-                template.height, 
-                template.width, 
-                '', 
-                '', 
-                dec.opts,
+            const doc = FieldUtils.FreeformField(
+                {
+                    tl: dec.tl,
+                    br: dec.br,
+                },
+                template.height,
+                template.width,
+                '',
+                '',
+                dec.opts
             );
 
             fields.push(doc);
         });
 
         const createMainDoc = (): Doc => {
-            const main = Docs.Create.FreeformDocument(fields, { 
-                _height: template.height, 
-                _width: template.width, 
-                title: template.title, 
+            const main = Docs.Create.FreeformDocument(fields, {
+                _height: template.height,
+                _width: template.width,
+                title: template.title,
                 backgroundColor: template.opts.backgroundColor,
-                _layout_borderRounding: `${template.opts.cornerRounding}px` ?? '0px', 
+                _layout_borderRounding: `${template.opts.cornerRounding}px` ?? '0px',
                 borderWidth: template.opts.borderWidth,
                 borderColor: template.opts.borderColor,
-                x: 40000, 
+                x: 40000,
                 y: 40000,
             });
 
@@ -807,40 +836,46 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             mainCollection.addDocument(main);
 
             return main;
-        }
+        };
 
         const textCalls = await renderTextCalls();
         const imageCalls = await renderImageCalls();
 
-        textCalls.forEach(doc => {fields.push(doc)});
-        imageCalls.forEach(doc => {fields.push(doc)});
+        textCalls.forEach(doc => {
+            fields.push(doc);
+        });
+        imageCalls.forEach(doc => {
+            fields.push(doc);
+        });
 
         return createMainDoc();
-    }
+    };
 
     compileFieldDescriptions = (templates: TemplateDocInfos[]): string => {
         let descriptions: string = '';
         templates.forEach(template => {
-            descriptions += `----------  NEW TEMPLATE TO INCLUDE: Description of template ${template.title}'s fields: `
+            descriptions += `----------  NEW TEMPLATE TO INCLUDE: Description of template ${template.title}'s fields: `;
             template.fields.forEach((field, index) => {
-                descriptions += `{Field #${index}: ${field.description}} `
+                descriptions += `{Field #${index}: ${field.description}} `;
             });
         });
 
         return descriptions;
     };
 
-    compileColDescriptions = (cols: Col[]): string =>  {
+    compileColDescriptions = (cols: Col[]): string => {
         let descriptions: string = ' ------------- COL DESCRIPTIONS START HERE:';
-        cols.forEach(col => descriptions += `{title: ${col.title}, sizes: ${String(col.sizes)}, type: ${col.type}, descreiption: ${col.desc}} `);
+        cols.forEach(col => (descriptions += `{title: ${col.title}, sizes: ${String(col.sizes)}, type: ${col.type}, descreiption: ${col.desc}} `));
 
         return descriptions;
     };
 
-    getColByTitle = (title: string) => { return this.fieldsInfos.filter(col => col.title === title)[0]; };
+    getColByTitle = (title: string) => {
+        return this.fieldsInfos.filter(col => col.title === title)[0];
+    };
 
     @action
-    assignColsToFields = async(templates: TemplateDocInfos[], cols: Col[]): Promise<[TemplateDocInfos, {[field: number]: Col}][]> => {
+    assignColsToFields = async (templates: TemplateDocInfos[], cols: Col[]): Promise<[TemplateDocInfos, { [field: number]: Col }][]> => {
         const fieldDescriptions: string = this.compileFieldDescriptions(templates);
         const colDescriptions: string = this.compileColDescriptions(cols);
 
@@ -857,24 +892,26 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             const res = await gptAPICall(prompt, GPTCallType.TEMPLATE);
 
             if (res && this._callCount === origCount) {
-
-                const assignments: {[templateTitle: string]: {[field: string]: string}} = JSON.parse(res);
-                const brokenDownAssignments: [TemplateDocInfos, {[field: number]: Col}][] = [];
+                const assignments: { [templateTitle: string]: { [field: string]: string } } = JSON.parse(res);
+                const brokenDownAssignments: [TemplateDocInfos, { [field: number]: Col }][] = [];
 
                 Object.entries(assignments).forEach(([tempTitle, assignment]) => {
                     const template = TemplateLayouts.getTemplateByTitle(tempTitle);
                     if (!template) return;
-                    const toObj = Object.entries(assignment).reduce((a, [fieldNum, colTitle]) => {
-                        a[Number(fieldNum)] = this.getColByTitle(colTitle);
-                        return a;
-                    }, {} as { [field: number]: Col }); 
-                    brokenDownAssignments.push([template, toObj])
-                })
+                    const toObj = Object.entries(assignment).reduce(
+                        (a, [fieldNum, colTitle]) => {
+                            a[Number(fieldNum)] = this.getColByTitle(colTitle);
+                            return a;
+                        },
+                        {} as { [field: number]: Col }
+                    );
+                    brokenDownAssignments.push([template, toObj]);
+                });
                 return brokenDownAssignments;
             }
         } catch (err) {
             console.error(err);
-        } 
+        }
 
         return [];
     };
@@ -884,178 +921,200 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
         const cols = this.fieldsInfos;
         const templates = this.findValidTemplates(cols, TemplateLayouts.allTemplates);
-        
+
         const assignments: [TemplateDocInfos, { [field: number]: Col }][] = await this.assignColsToFields(templates, cols);
-        
-        const renderedTemplatePromises: Promise<Doc>[] = assignments.map(([template, assignments]) => 
-            this.fillPresetTemplate(template, assignments)
-        );
-    
+
+        const renderedTemplatePromises: Promise<Doc>[] = assignments.map(([template, assignments]) => this.fillPresetTemplate(template, assignments));
+
         const renderedTemplates: Doc[] = await Promise.all(renderedTemplatePromises);
-        
-        setTimeout(() => { this.setGSuggestedTemplates(renderedTemplates); this._GPTLoading = false });
+
+        setTimeout(() => {
+            this.setGSuggestedTemplates(renderedTemplates);
+            this._GPTLoading = false;
+        });
     };
 
-    @action setExpandedView = (info: {icon: ImageField, doc: Doc} | undefined) => {
+    @action setExpandedView = (info: { icon: ImageField; doc: Doc } | undefined) => {
         this._expandedPreview = info;
-    }
+    };
 
-    get templatesPreviewContents(){
+    get templatesPreviewContents() {
         const renderedTemplates: Doc[] = [];
 
-        const GPTOptions = 
-            <div></div>
+        const GPTOptions = <div></div>;
 
-            //<img className='docCreatorMenu-preview-image expanded' src={this._expandedPreview.icon!.url.href.replace(".png", "_o.png")} />
+        //<img className='docCreatorMenu-preview-image expanded' src={this._expandedPreview.icon!.url.href.replace(".png", "_o.png")} />
 
         return (
             <div className={`docCreatorMenu-templates-view`}>
-                {this._expandedPreview ? 
-                <div className='docCreatorMenu-expanded-template-preview'>
-                    <img className='docCreatorMenu-preview-image expanded' src={this._expandedPreview.icon!.url.href.replace(".png", "_o.png")} />
-                    <div className='right-buttons-panel'>
-                        <button className='docCreatorMenu-menu-button section-reveal-options top-right' onPointerDown={e => this.setUpButtonClick(e, () => this.setExpandedView(undefined))}> 
-                            <FontAwesomeIcon icon='minimize'/>
-                        </button>
-                        <button className='docCreatorMenu-menu-button section-reveal-options top-right-lower' onPointerDown={e => this.setUpButtonClick(e, () => this._expandedPreview && this._templateDocs.push(this._expandedPreview.doc))}>
-                            <FontAwesomeIcon icon='plus' color='white'/>
-                        </button>
-                    </div>
-                </div> 
-                :
-                <div>
-                    <div className='docCreatorMenu-section' style={{height: this._GPTOpt ? 200 : 200}}>
-                        <div className='docCreatorMenu-section-topbar'>
-                            <div className='docCreatorMenu-section-title'>Suggested Templates</div>
-                            <button className='docCreatorMenu-menu-button section-reveal-options' onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._menuContent = 'dashboard'))}>
-                                <FontAwesomeIcon icon='gear'/>
+                {this._expandedPreview ? (
+                    <div className="docCreatorMenu-expanded-template-preview">
+                        <img className="docCreatorMenu-preview-image expanded" src={this._expandedPreview.icon!.url.href.replace('.png', '_o.png')} />
+                        <div className="right-buttons-panel">
+                            <button className="docCreatorMenu-menu-button section-reveal-options top-right" onPointerDown={e => this.setUpButtonClick(e, () => this.setExpandedView(undefined))}>
+                                <FontAwesomeIcon icon="minimize" />
+                            </button>
+                            <button className="docCreatorMenu-menu-button section-reveal-options top-right-lower" onPointerDown={e => this.setUpButtonClick(e, () => this._expandedPreview && this._templateDocs.push(this._expandedPreview.doc))}>
+                                <FontAwesomeIcon icon="plus" color="white" />
                             </button>
                         </div>
-                        <div className='docCreatorMenu-templates-preview-window' style={{justifyContent: this._GPTLoading || this._menuDimensions.width > 400 ? 'center' : ''}}>
-                            {this._GPTLoading ? (
-                                <div className="loading-spinner">
-                                    <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
-                                </div>
-                            ) : (
-                            this._suggestedTemplates?.map(doc => 
-                                ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info =>
-                                    <div 
-                                    className='docCreatorMenu-preview-window'
-                                    style={{
-                                        border: this._selectedTemplate === info.doc ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
-                                        boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : ''
-                                    }}
-                                    onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}>
-                                        <button className='option-button left' onPointerDown={e => this.setUpButtonClick(e, () => {this.setExpandedView(info)})}>
-                                            <FontAwesomeIcon icon='magnifying-glass' color='white'/>
-                                        </button>   
-                                        <button className='option-button right' onPointerDown={e => this.setUpButtonClick(e, () => this._templateDocs.push(info.doc))}>
-                                            <FontAwesomeIcon icon='plus' color='white'/>
-                                        </button>
-                                        <img className='docCreatorMenu-preview-image' src={info.icon!.url.href.replace(".png", "_o.png")} />
-                                    </div>
-                            ))}
-                        </div>
-                        <div className='docCreatorMenu-GPT-options'>
-                            <div className='docCreatorMenu-GPT-options-container'>
-                                <button className='docCreatorMenu-menu-button' onPointerDown={e => this.setUpButtonClick(e, () => this.generatePresetTemplates())}>
-                                    <FontAwesomeIcon icon='arrows-rotate'/>
+                    </div>
+                ) : (
+                    <div>
+                        <div className="docCreatorMenu-section" style={{ height: this._GPTOpt ? 200 : 200 }}>
+                            <div className="docCreatorMenu-section-topbar">
+                                <div className="docCreatorMenu-section-title">Suggested Templates</div>
+                                <button className="docCreatorMenu-menu-button section-reveal-options" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._menuContent = 'dashboard')))}>
+                                    <FontAwesomeIcon icon="gear" />
                                 </button>
                             </div>
-                            {this._GPTOpt ? GPTOptions : null }
-                        </div>
-                </div>
-                <hr className='docCreatorMenu-option-divider full no-margin'/>
-                <div className='docCreatorMenu-section'>
-                    <div className='docCreatorMenu-section-topbar'>
-                        <div className='docCreatorMenu-section-title'>Your Templates</div>
-                        <button className='docCreatorMenu-menu-button section-reveal-options' onPointerDown={e => this.setUpButtonClick(e, () => this._GPTOpt = !this._GPTOpt)}>
-                            <FontAwesomeIcon icon='gear'/>
-                        </button>
-                    </div>
-                    <div className='docCreatorMenu-templates-preview-window' style={{justifyContent: this._menuDimensions.width > 400 ? 'center' : ''}}>
-                        <div className='docCreatorMenu-preview-window empty' onPointerDown={e => this.testTemplate()}>
-                            <FontAwesomeIcon icon='plus' color='rgb(160, 160, 160)'/>
+                            <div className="docCreatorMenu-templates-preview-window" style={{ justifyContent: this._GPTLoading || this._menuDimensions.width > 400 ? 'center' : '' }}>
+                                {this._GPTLoading ? (
+                                    <div className="loading-spinner">
+                                        <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} height={30} width={30} />
+                                    </div>
+                                ) : (
+                                    this._suggestedTemplates
+                                        ?.map(doc => ({ icon: ImageCast(doc.icon), doc }))
+                                        .filter(info => info.icon && info.doc)
+                                        .map(info => (
+                                            <div
+                                                className="docCreatorMenu-preview-window"
+                                                style={{
+                                                    border: this._selectedTemplate === info.doc ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
+                                                    boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '',
+                                                }}
+                                                onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}>
+                                                <button
+                                                    className="option-button left"
+                                                    onPointerDown={e =>
+                                                        this.setUpButtonClick(e, () => {
+                                                            this.setExpandedView(info);
+                                                        })
+                                                    }>
+                                                    <FontAwesomeIcon icon="magnifying-glass" color="white" />
+                                                </button>
+                                                <button className="option-button right" onPointerDown={e => this.setUpButtonClick(e, () => this._templateDocs.push(info.doc))}>
+                                                    <FontAwesomeIcon icon="plus" color="white" />
+                                                </button>
+                                                <img className="docCreatorMenu-preview-image" src={info.icon!.url.href.replace('.png', '_o.png')} />
+                                            </div>
+                                        ))
+                                )}
+                            </div>
+                            <div className="docCreatorMenu-GPT-options">
+                                <div className="docCreatorMenu-GPT-options-container">
+                                    <button className="docCreatorMenu-menu-button" onPointerDown={e => this.setUpButtonClick(e, () => this.generatePresetTemplates())}>
+                                        <FontAwesomeIcon icon="arrows-rotate" />
+                                    </button>
+                                </div>
+                                {this._GPTOpt ? GPTOptions : null}
+                            </div>
                         </div>
-                        {this._templateDocs.map(doc => ({icon: ImageCast(doc.icon), doc})).filter(info => info.icon && info.doc).map(info => {
-                            if (renderedTemplates.includes(info.doc)) return undefined;
-                            renderedTemplates.push(info.doc);
-                            return (<div 
-                            className='docCreatorMenu-preview-window'
-                            style={{
-                                border: this._selectedTemplate === info.doc ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
-                                boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : ''
-                            }}
-                            onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}>
-                                <button className='option-button left' onPointerDown={e => this.setUpButtonClick(e, () => {this.editTemplate(info.doc)})}>
-                                    <FontAwesomeIcon icon='pencil' color='black'/>
-                                </button>
-                                <button className='option-button right' onPointerDown={e => this.setUpButtonClick(e, () => {this.removeTemplate(info.doc)})}>
-                                    <FontAwesomeIcon icon='trash' color='black'/>
+                        <hr className="docCreatorMenu-option-divider full no-margin" />
+                        <div className="docCreatorMenu-section">
+                            <div className="docCreatorMenu-section-topbar">
+                                <div className="docCreatorMenu-section-title">Your Templates</div>
+                                <button className="docCreatorMenu-menu-button section-reveal-options" onPointerDown={e => this.setUpButtonClick(e, () => (this._GPTOpt = !this._GPTOpt))}>
+                                    <FontAwesomeIcon icon="gear" />
                                 </button>
-                                <img className='docCreatorMenu-preview-image' src={info.icon!.url.href.replace(".png", "_o.png")} />
                             </div>
-                        )})}
+                            <div className="docCreatorMenu-templates-preview-window" style={{ justifyContent: this._menuDimensions.width > 400 ? 'center' : '' }}>
+                                <div className="docCreatorMenu-preview-window empty" onPointerDown={e => this.testTemplate()}>
+                                    <FontAwesomeIcon icon="plus" color="rgb(160, 160, 160)" />
+                                </div>
+                                {this._templateDocs
+                                    .map(doc => ({ icon: ImageCast(doc.icon), doc }))
+                                    .filter(info => info.icon && info.doc)
+                                    .map(info => {
+                                        if (renderedTemplates.includes(info.doc)) return undefined;
+                                        renderedTemplates.push(info.doc);
+                                        return (
+                                            <div
+                                                className="docCreatorMenu-preview-window"
+                                                style={{
+                                                    border: this._selectedTemplate === info.doc ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
+                                                    boxShadow: this._selectedTemplate === info.doc ? `0 0 15px rgba(68, 118, 247, .8)` : '',
+                                                }}
+                                                onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedTemplate(info.doc)))}>
+                                                <button
+                                                    className="option-button left"
+                                                    onPointerDown={e =>
+                                                        this.setUpButtonClick(e, () => {
+                                                            this.editTemplate(info.doc);
+                                                        })
+                                                    }>
+                                                    <FontAwesomeIcon icon="pencil" color="black" />
+                                                </button>
+                                                <button
+                                                    className="option-button right"
+                                                    onPointerDown={e =>
+                                                        this.setUpButtonClick(e, () => {
+                                                            this.removeTemplate(info.doc);
+                                                        })
+                                                    }>
+                                                    <FontAwesomeIcon icon="trash" color="black" />
+                                                </button>
+                                                <img className="docCreatorMenu-preview-image" src={info.icon!.url.href.replace('.png', '_o.png')} />
+                                            </div>
+                                        );
+                                    })}
+                            </div>
                         </div>
                     </div>
-                </div>
-                }
+                )}
             </div>
         );
     }
 
-    get savedLayoutsPreviewContents(){
+    get savedLayoutsPreviewContents() {
         return (
-            <div className='docCreatorMenu-preview-container'>
-               {this._savedLayouts.map((layout, index) => 
-                <div 
-                    className='docCreatorMenu-preview-window'
-                    style={{
-                        border: this.isSelectedLayout(layout) ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
-                        boxShadow: this.isSelectedLayout(layout) ? `0 0 15px rgba(68, 118, 247, .8)` : ''
-                    }}
-                    onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedSavedLayout(layout)))}
-                    >
-                    {this.layoutPreviewContents(87, layout, true, index)}
-                </div>
-               )}
+            <div className="docCreatorMenu-preview-container">
+                {this._savedLayouts.map((layout, index) => (
+                    <div
+                        className="docCreatorMenu-preview-window"
+                        style={{
+                            border: this.isSelectedLayout(layout) ? `solid 3px ${Colors.MEDIUM_BLUE}` : '',
+                            boxShadow: this.isSelectedLayout(layout) ? `0 0 15px rgba(68, 118, 247, .8)` : '',
+                        }}
+                        onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this.updateSelectedSavedLayout(layout)))}>
+                        {this.layoutPreviewContents(87, layout, true, index)}
+                    </div>
+                ))}
             </div>
         );
     }
 
-    @action updateXMargin = (input: string) => { this._layout.xMargin = Number(input) };
-    @action updateYMargin = (input: string) => { this._layout.yMargin = Number(input) };
-    @action updateColumns = (input: string) => { this._layout.columns = Number(input) };
+    @action updateXMargin = (input: string) => {
+        this._layout.xMargin = Number(input);
+    };
+    @action updateYMargin = (input: string) => {
+        this._layout.yMargin = Number(input);
+    };
+    @action updateColumns = (input: string) => {
+        this._layout.columns = Number(input);
+    };
 
     get layoutConfigOptions() {
         const optionInput = (icon: string, func: Function, def?: number, key?: string, noMargin?: boolean) => {
             return (
-                <div className='docCreatorMenu-option-container small no-margin' key={key} style={{marginTop: noMargin ? '0px' : ''}}
-                >
-                    <div className='docCreatorMenu-option-title config layout-config'>
-                        <FontAwesomeIcon icon={icon as any}/>
+                <div className="docCreatorMenu-option-container small no-margin" key={key} style={{ marginTop: noMargin ? '0px' : '' }}>
+                    <div className="docCreatorMenu-option-title config layout-config">
+                        <FontAwesomeIcon icon={icon as any} />
                     </div>
-                    <input defaultValue={def} onInput={(e) => func(e.currentTarget.value)} className='docCreatorMenu-input config layout-config'/>
+                    <input defaultValue={def} onInput={e => func(e.currentTarget.value)} className="docCreatorMenu-input config layout-config" />
                 </div>
             );
-        }
+        };
 
         switch (this._layout.type) {
             case LayoutType.Row:
-                return (
-                    <div className='docCreatorMenu-configuration-bar'>
-                        {optionInput('arrows-left-right', this.updateXMargin, this._layout.xMargin, '0')}
-                    </div>
-                    );
+                return <div className="docCreatorMenu-configuration-bar">{optionInput('arrows-left-right', this.updateXMargin, this._layout.xMargin, '0')}</div>;
             case LayoutType.Column:
-                return (
-                    <div className='docCreatorMenu-configuration-bar'>
-                        {optionInput('arrows-up-down', this.updateYMargin, this._layout.yMargin, '1')}
-                    </div>
-                    );
+                return <div className="docCreatorMenu-configuration-bar">{optionInput('arrows-up-down', this.updateYMargin, this._layout.yMargin, '1')}</div>;
             case LayoutType.Grid:
                 return (
-                    <div className='docCreatorMenu-configuration-bar'>
+                    <div className="docCreatorMenu-configuration-bar">
                         {optionInput('arrows-up-down', this.updateYMargin, this._layout.xMargin, '2')}
                         {optionInput('arrows-left-right', this.updateXMargin, this._layout.xMargin, '3')}
                         {optionInput('table-columns', this.updateColumns, this._layout.columns, '4', true)}
@@ -1072,9 +1131,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
     //     return Docs.Create.FreeformDocument([], { _height: 200, _width: 200, title: 'title'});
     // }
 
-    screenToLocalTransform = () =>
-    this._props
-        .ScreenToLocalTransform();
+    screenToLocalTransform = () => this._props.ScreenToLocalTransform();
 
     layoutPreviewContents = (outerSpan: number, altLayout?: DataVizTemplateLayout, small: boolean = false, id?: number) => {
         const doc: Doc | undefined = altLayout ? altLayout.template : this._selectedTemplate;
@@ -1084,10 +1141,12 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
 
         const docWidth: number = Number(doc._width);
         const docHeight: number = Number(doc._height);
-        const horizontalSpan: number = (docWidth + layout.xMargin) * (altLayout ? altLayout.columns : this.columnsCount) - layout.xMargin;;
+        const horizontalSpan: number = (docWidth + layout.xMargin) * (altLayout ? altLayout.columns : this.columnsCount) - layout.xMargin;
         const verticalSpan: number = (docHeight + layout.yMargin) * (altLayout ? altLayout.rows : this.rowsCount) - layout.yMargin;
         const largerSpan: number = horizontalSpan > verticalSpan ? horizontalSpan : verticalSpan;
-        const scaledDown = (input: number) => {return input / (largerSpan / outerSpan * this._layoutPreviewScale)}
+        const scaledDown = (input: number) => {
+            return input / ((largerSpan / outerSpan) * this._layoutPreviewScale);
+        };
         const fontSize = Math.min(scaledDown(docWidth / 3), scaledDown(docHeight / 3));
 
         return (
@@ -1114,220 +1173,275 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
             //         {null}
             //     </CollectionFreeFormView>
             // </div>
-            <div className='docCreatorMenu-layout-preview-window-wrapper' id={String(id) ?? undefined}>
-                <div className='docCreatorMenu-zoom-button-container'>
-                    <button 
-                        className='docCreatorMenu-zoom-button'
-                        onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._layoutPreviewScale *= 1.25))}>
-                            <FontAwesomeIcon icon={'minus'}/>
+            <div className="docCreatorMenu-layout-preview-window-wrapper" id={String(id) ?? undefined}>
+                <div className="docCreatorMenu-zoom-button-container">
+                    <button className="docCreatorMenu-zoom-button" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._layoutPreviewScale *= 1.25)))}>
+                        <FontAwesomeIcon icon={'minus'} />
                     </button>
-                    <button 
-                        className='docCreatorMenu-zoom-button zoom-in'
-                        onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._layoutPreviewScale *= .75))}>
-                            <FontAwesomeIcon icon={'plus'}/>
+                    <button className="docCreatorMenu-zoom-button zoom-in" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._layoutPreviewScale *= 0.75)))}>
+                        <FontAwesomeIcon icon={'plus'} />
                     </button>
-                    {altLayout ? <button 
-                        className='docCreatorMenu-zoom-button trash'
-                        onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._savedLayouts.splice(this._savedLayouts.indexOf(altLayout), 1)))}>
-                            <FontAwesomeIcon icon={'trash'}/>
-                    </button> : null}
+                    {altLayout ? (
+                        <button className="docCreatorMenu-zoom-button trash" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._savedLayouts.splice(this._savedLayouts.indexOf(altLayout), 1)))}>
+                            <FontAwesomeIcon icon={'trash'} />
+                        </button>
+                    ) : null}
                 </div>
-                {<div 
-                id={String(id) ?? undefined}
-                className={`docCreatorMenu-layout-preview-window ${small ? 'small' : ''}`}
-                style={{
-                    gridTemplateColumns: `repeat(${altLayout ? altLayout.columns : this.columnsCount}, ${scaledDown(docWidth)}px`,
-                    gridTemplateRows: `${scaledDown(docHeight)}px`,
-                    gridAutoRows: `${scaledDown(docHeight)}px`,
-                    rowGap: `${scaledDown(layout.yMargin)}px`,
-                    columnGap: `${scaledDown(layout.xMargin)}px` 
-                }}>
-                    {this._layout.type === LayoutType.Stacked ? 
-                    <div 
-                    className='docCreatorMenu-layout-preview-item'
-                    style={{
-                        width: scaledDown(docWidth), 
-                        height: scaledDown(docHeight),
-                        fontSize: fontSize,
-                    }}
-                    >
-                        All
-                    </div> : 
-                    this.docsToRender.map(num => 
-                        <div 
-                        onMouseEnter={() => this._dataViz?.setSpecialHighlightedRow(num)}
-                        onMouseLeave={() => this._dataViz?.setSpecialHighlightedRow(undefined)}
-                        className='docCreatorMenu-layout-preview-item'
+                {
+                    <div
+                        id={String(id) ?? undefined}
+                        className={`docCreatorMenu-layout-preview-window ${small ? 'small' : ''}`}
                         style={{
-                            width: scaledDown(docWidth), 
-                            height: scaledDown(docHeight),
-                            fontSize: fontSize,
-                        }}
-                        >
-                            {num}
-                        </div>
-                    )}
-
-                </div>}
+                            gridTemplateColumns: `repeat(${altLayout ? altLayout.columns : this.columnsCount}, ${scaledDown(docWidth)}px`,
+                            gridTemplateRows: `${scaledDown(docHeight)}px`,
+                            gridAutoRows: `${scaledDown(docHeight)}px`,
+                            rowGap: `${scaledDown(layout.yMargin)}px`,
+                            columnGap: `${scaledDown(layout.xMargin)}px`,
+                        }}>
+                        {this._layout.type === LayoutType.Stacked ? (
+                            <div
+                                className="docCreatorMenu-layout-preview-item"
+                                style={{
+                                    width: scaledDown(docWidth),
+                                    height: scaledDown(docHeight),
+                                    fontSize: fontSize,
+                                }}>
+                                All
+                            </div>
+                        ) : (
+                            this.docsToRender.map(num => (
+                                <div
+                                    onMouseEnter={() => this._dataViz?.setSpecialHighlightedRow(num)}
+                                    onMouseLeave={() => this._dataViz?.setSpecialHighlightedRow(undefined)}
+                                    className="docCreatorMenu-layout-preview-item"
+                                    style={{
+                                        width: scaledDown(docWidth),
+                                        height: scaledDown(docHeight),
+                                        fontSize: fontSize,
+                                    }}>
+                                    {num}
+                                </div>
+                            ))
+                        )}
+                    </div>
+                }
             </div>
         );
-    }
-
-    get optionsMenuContents(){
-        const layoutEquals = (layout: DataVizTemplateLayout) => {
+    };
 
-        } //TODO: ADD LATER
+    get optionsMenuContents() {
+        const layoutEquals = (layout: DataVizTemplateLayout) => {}; //TODO: ADD LATER
 
         const layoutOption = (option: LayoutType, optStyle?: {}, specialFunc?: Function) => {
             return (
-                <div 
-                    className="docCreatorMenu-dropdown-option" 
+                <div
+                    className="docCreatorMenu-dropdown-option"
                     style={optStyle}
-                    onPointerDown={e => this.setUpButtonClick(e, () => {specialFunc?.(); runInAction(() => this._layout.type = option)})}>
+                    onPointerDown={e =>
+                        this.setUpButtonClick(e, () => {
+                            specialFunc?.();
+                            runInAction(() => (this._layout.type = option));
+                        })
+                    }>
                     {option}
                 </div>
             );
-        }
+        };
 
         const selectionBox = (width: number, height: number, icon: string, specClass?: string, options?: JSX.Element[], manual?: boolean): JSX.Element => {
-            return (<div className='docCreatorMenu-option-container'>
-                <div className={`docCreatorMenu-option-title config ${specClass}`} style={{width: width * .4, height: height}}>
-                    <FontAwesomeIcon icon={icon as any}/>
+            return (
+                <div className="docCreatorMenu-option-container">
+                    <div className={`docCreatorMenu-option-title config ${specClass}`} style={{ width: width * 0.4, height: height }}>
+                        <FontAwesomeIcon icon={icon as any} />
+                    </div>
+                    {manual ? (
+                        <input className={`docCreatorMenu-input config ${specClass}`} style={{ width: width * 0.6, height: height }} />
+                    ) : (
+                        <select className={`docCreatorMenu-input config ${specClass}`} style={{ width: width * 0.6, height: height }}>
+                            {options}
+                        </select>
+                    )}
                 </div>
-                {manual ? <input className={`docCreatorMenu-input config ${specClass}`} style={{width: width * .6, height: height}}/> :
-                <select className={`docCreatorMenu-input config ${specClass}`} style={{width: width * .6, height: height}}>
-                    {options}
-                </select>
-                }
-            </div>);
-        }
+            );
+        };
 
         const repeatOptions = [0, 1, 2, 3, 4, 5];
 
         return (
-            <div className='docCreatorMenu-menu-container'>
-                <div className='docCreatorMenu-option-container layout'>
-                    <div className='docCreatorMenu-dropdown-hoverable'>
+            <div className="docCreatorMenu-menu-container">
+                <div className="docCreatorMenu-option-container layout">
+                    <div className="docCreatorMenu-dropdown-hoverable">
                         <div className="docCreatorMenu-option-title">{this._layout.type ? this._layout.type.toUpperCase() : 'Choose Layout'}</div>
                         <div className="docCreatorMenu-dropdown-content">
                             {layoutOption(LayoutType.Stacked)}
-                            {layoutOption(LayoutType.Grid, undefined, () => {if (!this._layout.columns) this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length))})}
+                            {layoutOption(LayoutType.Grid, undefined, () => {
+                                if (!this._layout.columns) this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length));
+                            })}
                             {layoutOption(LayoutType.Row)}
                             {layoutOption(LayoutType.Column)}
-                            {layoutOption(LayoutType.Custom, {borderBottom: `0px`})}
+                            {layoutOption(LayoutType.Custom, { borderBottom: `0px` })}
                         </div>
                     </div>
-                    <button 
-                        className='docCreatorMenu-menu-button preview-toggle'
-                        onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._layoutPreview = !this._layoutPreview))}>
-                        <FontAwesomeIcon icon={this._layoutPreview ? 'minus' : 'magnifying-glass'}/>
+                    <button className="docCreatorMenu-menu-button preview-toggle" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._layoutPreview = !this._layoutPreview)))}>
+                        <FontAwesomeIcon icon={this._layoutPreview ? 'minus' : 'magnifying-glass'} />
                     </button>
                 </div>
-                {this._layout.type ? this.layoutConfigOptions: null}
-                {this._layoutPreview ? this.layoutPreviewContents(this._menuDimensions.width * .75) : null}
-                {selectionBox(60, 20, 'repeat', undefined, repeatOptions.map(num => <option onPointerDown={e => this._layout.repeat = num}>{`${num}x`}</option>))}
-                <hr className='docCreatorMenu-option-divider'/>
-                <div className='docCreatorMenu-general-options-container'>
+                {this._layout.type ? this.layoutConfigOptions : null}
+                {this._layoutPreview ? this.layoutPreviewContents(this._menuDimensions.width * 0.75) : null}
+                {selectionBox(
+                    60,
+                    20,
+                    'repeat',
+                    undefined,
+                    repeatOptions.map(num => <option onPointerDown={e => (this._layout.repeat = num)}>{`${num}x`}</option>)
+                )}
+                <hr className="docCreatorMenu-option-divider" />
+                <div className="docCreatorMenu-general-options-container">
                     <button
-                        className='docCreatorMenu-save-layout-button'
-                        onPointerDown={e => setupMoveUpEvents( this, e, returnFalse, emptyFunction,
-                            undoable(clickEv => {
-                                clickEv.stopPropagation();
-                                if (!this._selectedTemplate) return;
-                                const layout: DataVizTemplateLayout = {template: this._selectedTemplate, layout: {type: this._layout.type, xMargin: this._layout.xMargin, yMargin:this._layout.yMargin, repeat: 0}, columns: this.columnsCount, rows: this.rowsCount, docsNumList: this.docsToRender};
-                                if (!this._savedLayouts.includes(layout)) { this._savedLayouts.push(layout) };
-                            }, 'make docs') 
-                        )
-                    }>
-                        <FontAwesomeIcon icon='floppy-disk'/>
+                        className="docCreatorMenu-save-layout-button"
+                        onPointerDown={e =>
+                            setupMoveUpEvents(
+                                this,
+                                e,
+                                returnFalse,
+                                emptyFunction,
+                                undoable(clickEv => {
+                                    clickEv.stopPropagation();
+                                    if (!this._selectedTemplate) return;
+                                    const layout: DataVizTemplateLayout = {
+                                        template: this._selectedTemplate,
+                                        layout: { type: this._layout.type, xMargin: this._layout.xMargin, yMargin: this._layout.yMargin, repeat: 0 },
+                                        columns: this.columnsCount,
+                                        rows: this.rowsCount,
+                                        docsNumList: this.docsToRender,
+                                    };
+                                    if (!this._savedLayouts.includes(layout)) {
+                                        this._savedLayouts.push(layout);
+                                    }
+                                }, 'make docs')
+                            )
+                        }>
+                        <FontAwesomeIcon icon="floppy-disk" />
                     </button>
-                    <button 
-                        className='docCreatorMenu-create-docs-button'
-                        style={{backgroundColor: this.canMakeDocs ? '' : 'rgb(155, 155, 155)', border: this.canMakeDocs ? '' : 'solid 2px rgb(180, 180, 180)'}}
-                        onPointerDown={e => setupMoveUpEvents( this, e, returnFalse, emptyFunction,
+                    <button
+                        className="docCreatorMenu-create-docs-button"
+                        style={{ backgroundColor: this.canMakeDocs ? '' : 'rgb(155, 155, 155)', border: this.canMakeDocs ? '' : 'solid 2px rgb(180, 180, 180)' }}
+                        onPointerDown={e =>
+                            setupMoveUpEvents(
+                                this,
+                                e,
+                                returnFalse,
+                                emptyFunction,
                                 undoable(clickEv => {
                                     clickEv.stopPropagation();
                                     if (!this._selectedTemplate) return;
-                                    const templateInfo: DataVizTemplateInfo = {doc: this._selectedTemplate, layout: this._layout, referencePos: {x: this._pageX + 450, y: this._pageY}, columns: this.columnsCount};
+                                    const templateInfo: DataVizTemplateInfo = { doc: this._selectedTemplate, layout: this._layout, referencePos: { x: this._pageX + 450, y: this._pageY }, columns: this.columnsCount };
                                     this._dataViz?.createDocsFromTemplate(templateInfo);
-                                }, 'make docs') 
+                                }, 'make docs')
                             )
                         }>
-                         <FontAwesomeIcon icon='plus'/>
+                        <FontAwesomeIcon icon="plus" />
                     </button>
                 </div>
             </div>
         );
     }
 
-    get dashboardContents(){
+    get dashboardContents() {
         const sizes: string[] = ['tiny', 'small', 'medium', 'large', 'huge'];
 
         const fieldPanel = (field: Col) => {
             return (
-                <div className='field-panel'> 
-                    <div className='top-bar'>
-                        <span className='field-title'>{`${field.title} Field`}</span>
-                        <button className='docCreatorMenu-menu-button section-reveal-options no-margin' onPointerDown={e => this.setUpButtonClick(e, this.addField)} style={{position: 'absolute', right: '0px'}}>
-                            <FontAwesomeIcon icon='minus'/>
+                <div className="field-panel">
+                    <div className="top-bar">
+                        <span className="field-title">{`${field.title} Field`}</span>
+                        <button className="docCreatorMenu-menu-button section-reveal-options no-margin" onPointerDown={e => this.setUpButtonClick(e, this.addField)} style={{ position: 'absolute', right: '0px' }}>
+                            <FontAwesomeIcon icon="minus" />
                         </button>
                     </div>
-                    <div className='opts-bar'> 
-                        <div className='opt-box'>
-                            <div className='top-bar'> Title </div>
-                            <textarea className='content' style={{width: '100%', height: 'calc(100% - 20px)'}} defaultValue={field.title} placeholder={'Enter title'} onChange={(e) => this.setColTitle(field, e.target.value)}/>
+                    <div className="opts-bar">
+                        <div className="opt-box">
+                            <div className="top-bar"> Title </div>
+                            <textarea className="content" style={{ width: '100%', height: 'calc(100% - 20px)' }} defaultValue={field.title} placeholder={'Enter title'} onChange={e => this.setColTitle(field, e.target.value)} />
                         </div>
-                        <div className='opt-box'>
-                            <div className='top-bar'> Type </div>
-                            <div className='content'>
-                                <span className='type-display'>{field.type === TemplateFieldType.TEXT ? 'Text Field' : field.type === TemplateFieldType.VISUAL ? 'File Field' : ''}</span>
-                                <div className='bubbles'>
-                                    <input className='bubble' type="radio" name="type" onClick={() => {this.setColType(field, TemplateFieldType.TEXT)}}/> 
-                                    <div className='text'>Text</div>
-                                    <input className='bubble' type="radio" name="type" onClick={() => {this.setColType(field, TemplateFieldType.VISUAL)}}/> 
-                                    <div className='text'>File</div>
+                        <div className="opt-box">
+                            <div className="top-bar"> Type </div>
+                            <div className="content">
+                                <span className="type-display">{field.type === TemplateFieldType.TEXT ? 'Text Field' : field.type === TemplateFieldType.VISUAL ? 'File Field' : ''}</span>
+                                <div className="bubbles">
+                                    <input
+                                        className="bubble"
+                                        type="radio"
+                                        name="type"
+                                        onClick={() => {
+                                            this.setColType(field, TemplateFieldType.TEXT);
+                                        }}
+                                    />
+                                    <div className="text">Text</div>
+                                    <input
+                                        className="bubble"
+                                        type="radio"
+                                        name="type"
+                                        onClick={() => {
+                                            this.setColType(field, TemplateFieldType.VISUAL);
+                                        }}
+                                    />
+                                    <div className="text">File</div>
                                 </div>
                             </div>
                         </div>
                     </div>
-                    <div className='sizes-box'>
-                        <div className='top-bar'> Valid Sizes </div>
-                        <div className='content'>
-                            <div className='bubbles'>
-                                {sizes.map(size => <>
-                                    <input className='bubble' type="checkbox" name="type" checked={field.sizes.includes(size as TemplateFieldSize)} onChange={(e) => {this.modifyColSizes(field, size as TemplateFieldSize, e.target.checked)}}/> 
-                                    <div className='text'>{size}</div>
-                                </>)}
+                    <div className="sizes-box">
+                        <div className="top-bar"> Valid Sizes </div>
+                        <div className="content">
+                            <div className="bubbles">
+                                {sizes.map(size => (
+                                    <>
+                                        <input
+                                            className="bubble"
+                                            type="checkbox"
+                                            name="type"
+                                            checked={field.sizes.includes(size as TemplateFieldSize)}
+                                            onChange={e => {
+                                                this.modifyColSizes(field, size as TemplateFieldSize, e.target.checked);
+                                            }}
+                                        />
+                                        <div className="text">{size}</div>
+                                    </>
+                                ))}
                             </div>
                         </div>
                     </div>
-                    <div className='desc-box'>
-                        <div className='top-bar'> Description </div>
-                        <textarea className='content' onChange={(e) => this.setColDesc(field, e.target.value)} defaultValue={field.desc === this._dataViz?.GPTSummary?.get(field.title)?.desc ? '' : field.desc } placeholder={this._dataViz?.GPTSummary?.get(field.title)?.desc ?? 'Add a description to help with template generation.'} />
+                    <div className="desc-box">
+                        <div className="top-bar"> Description </div>
+                        <textarea
+                            className="content"
+                            onChange={e => this.setColDesc(field, e.target.value)}
+                            defaultValue={field.desc === this._dataViz?.GPTSummary?.get(field.title)?.desc ? '' : field.desc}
+                            placeholder={this._dataViz?.GPTSummary?.get(field.title)?.desc ?? 'Add a description to help with template generation.'}
+                        />
                     </div>
                 </div>
-            )
-        }    
+            );
+        };
 
         return (
-        <div className='docCreatorMenu-dashboard-view'>
-            <div className='topbar'>
-                <button className='docCreatorMenu-menu-button section-reveal-options' onPointerDown={e => this.setUpButtonClick(e, this.addField)}>
-                    <FontAwesomeIcon icon='plus'/>
-                </button>
-                <button className='docCreatorMenu-menu-button section-reveal-options float-right' onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => this._menuContent = 'templates'))}>
-                    <FontAwesomeIcon icon='arrow-left'/>
-                </button>
-            </div>
-            <div className='panels-container'>
-                {this.fieldsInfos.map(field => fieldPanel(field))}
+            <div className="docCreatorMenu-dashboard-view">
+                <div className="topbar">
+                    <button className="docCreatorMenu-menu-button section-reveal-options" onPointerDown={e => this.setUpButtonClick(e, this.addField)}>
+                        <FontAwesomeIcon icon="plus" />
+                    </button>
+                    <button className="docCreatorMenu-menu-button section-reveal-options float-right" onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => (this._menuContent = 'templates')))}>
+                        <FontAwesomeIcon icon="arrow-left" />
+                    </button>
+                </div>
+                <div className="panels-container">{this.fieldsInfos.map(field => fieldPanel(field))}</div>
             </div>
-        </div>
         );
     }
 
-    get renderSelectedViewType(){
-        switch (this._menuContent){
+    get renderSelectedViewType() {
+        switch (this._menuContent) {
             case 'templates':
                 return this.templatesPreviewContents;
             case 'options':
@@ -1341,7 +1455,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         }
     }
 
-    get resizePanes(){
+    get resizePanes() {
         const ref = this._ref?.getBoundingClientRect();
         const height: number = ref?.height ?? 0;
         const width: number = ref?.width ?? 0;
@@ -1362,90 +1476,96 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
         const topButton = (icon: string, opt: string, func: Function, tag: string) => {
             return (
                 <div className={`top-button-container ${tag} ${opt === this._menuContent ? 'selected' : ''}`}>
-                    <div 
+                    <div
                         className="top-button-content"
-                        onPointerDown={e => this.setUpButtonClick(e, () => runInAction(() => {func()}))}>
-                        <FontAwesomeIcon icon={icon as any}/>
+                        onPointerDown={e =>
+                            this.setUpButtonClick(e, () =>
+                                runInAction(() => {
+                                    func();
+                                })
+                            )
+                        }>
+                        <FontAwesomeIcon icon={icon as any} />
                     </div>
                 </div>
             );
-        }
+        };
 
-        const onPreviewSelected = () => {this._menuContent = 'templates'}
-        const onSavedSelected = () => {this._menuContent = 'dashboard'}
+        const onPreviewSelected = () => {
+            this._menuContent = 'templates';
+        };
+        const onSavedSelected = () => {
+            this._menuContent = 'dashboard';
+        };
         const onOptionsSelected = () => {
             this._menuContent = 'options';
             if (!this._layout.columns) this._layout.columns = Math.ceil(Math.sqrt(this.docsToRender.length));
-        }
-
+        };
 
         return (
-            <div className='docCreatorMenu'>
-                {!this._shouldDisplay ? undefined : 
-                <div
-                    className="docCreatorMenu-cont"
-                    ref={r => this._ref = r}
-                    style={{
-                        display: '',
-                        left: this._pageX,
-                        top: this._pageY,
-                        width: this._menuDimensions.width,
-                        height: this._menuDimensions.height,
-                        background: SnappingManager.userBackgroundColor,
-                        color: SnappingManager.userColor,
-                    }}>
+            <div className="docCreatorMenu">
+                {!this._shouldDisplay ? undefined : (
+                    <div
+                        className="docCreatorMenu-cont"
+                        ref={r => (this._ref = r)}
+                        style={{
+                            display: '',
+                            left: this._pageX,
+                            top: this._pageY,
+                            width: this._menuDimensions.width,
+                            height: this._menuDimensions.height,
+                            background: SnappingManager.userBackgroundColor,
+                            color: SnappingManager.userColor,
+                        }}>
                         {this.resizePanes}
-                        <div 
-                        className='docCreatorMenu-menu'
-                        onPointerDown={e =>
-                            setupMoveUpEvents(
-                                this,
-                                e,
-                                (e) => {
-                                    this._dragging = true;
-                                    this._startPos = {x: 0, y: 0};
-                                    this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0);
-                                    this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0);
-                                    document.addEventListener('pointermove', this.onDrag);
-                                    return true;
-                                },
-                                emptyFunction,
-                                undoable(clickEv => {
-                                    clickEv.stopPropagation();
-                                }, 'drag menu')
-                            )
-                        }
-                        >
-                            <div className='docCreatorMenu-top-buttons-container'>
+                        <div
+                            className="docCreatorMenu-menu"
+                            onPointerDown={e =>
+                                setupMoveUpEvents(
+                                    this,
+                                    e,
+                                    e => {
+                                        this._dragging = true;
+                                        this._startPos = { x: 0, y: 0 };
+                                        this._startPos.x = e.pageX - (this._ref?.getBoundingClientRect().left ?? 0);
+                                        this._startPos.y = e.pageY - (this._ref?.getBoundingClientRect().top ?? 0);
+                                        document.addEventListener('pointermove', this.onDrag);
+                                        return true;
+                                    },
+                                    emptyFunction,
+                                    undoable(clickEv => {
+                                        clickEv.stopPropagation();
+                                    }, 'drag menu')
+                                )
+                            }>
+                            <div className="docCreatorMenu-top-buttons-container">
                                 {topButton('table-cells', 'templates', onPreviewSelected, 'left')}
                                 {topButton('bars', 'options', onOptionsSelected, 'middle')}
                                 {topButton('floppy-disk', 'saved', onSavedSelected, 'right')}
                             </div>
-                            <button 
-                                className='docCreatorMenu-menu-button close-menu'
-                                onPointerDown={e => this.setUpButtonClick(e, this.closeMenu)}>
-                                <FontAwesomeIcon icon={'minus'}/>
+                            <button className="docCreatorMenu-menu-button close-menu" onPointerDown={e => this.setUpButtonClick(e, this.closeMenu)}>
+                                <FontAwesomeIcon icon={'minus'} />
                             </button>
                         </div>
                         {this.renderSelectedViewType}
-                </div>
-                }
+                    </div>
+                )}
             </div>
-            )
-        }
+        );
+    }
 }
 
 export interface DataVizTemplateInfo {
     doc: Doc;
-    layout: {type: LayoutType, xMargin: number, yMargin: number, repeat: number};
+    layout: { type: LayoutType; xMargin: number; yMargin: number; repeat: number };
     columns: number;
-    referencePos: {x: number, y: number};
+    referencePos: { x: number; y: number };
 }
 
 export interface DataVizTemplateLayout {
     template: Doc;
     docsNumList: number[];
-    layout: {type: LayoutType, xMargin: number, yMargin: number, repeat: number};
+    layout: { type: LayoutType; xMargin: number; yMargin: number; repeat: number };
     columns: number;
     rows: number;
 }
@@ -1453,7 +1573,7 @@ export interface DataVizTemplateLayout {
 export enum TemplateFieldType {
     TEXT = 'text',
     VISUAL = 'visual',
-    UNSET = 'unset'
+    UNSET = 'unset',
 }
 
 export enum TemplateFieldSize {
@@ -1461,17 +1581,16 @@ export enum TemplateFieldSize {
     SMALL = 'small',
     MEDIUM = 'medium',
     LARGE = 'large',
-    HUGE = 'huge'
+    HUGE = 'huge',
 }
 
-
 export type Col = {
     sizes: TemplateFieldSize[];
     desc: string;
     title: string;
     type: TemplateFieldType;
     defaultContent?: string;
-}
+};
 
 type Field = {
     tl: [number, number];
@@ -1482,7 +1601,7 @@ type Field = {
     sizes?: TemplateFieldSize[];
     isDecoration?: boolean;
     description?: string;
-}
+};
 
 // class ContentField implements Field {
 //     tl: [number, number];
@@ -1493,10 +1612,10 @@ type Field = {
 //     sizes?: TemplateFieldSize[];
 //     description?: string;
 
-//     constructor( tl: [number, number], br: [number, number], 
-//                         opts: FieldOpts, subfields?: Field[], 
-//                         types?: TemplateFieldType[], 
-//                         sizes?: TemplateFieldSize[], 
+//     constructor( tl: [number, number], br: [number, number],
+//                         opts: FieldOpts, subfields?: Field[],
+//                         types?: TemplateFieldType[],
+//                         sizes?: TemplateFieldSize[],
 //                         description?: string) {
 //         this.tl = tl;
 //         this.br = br;
@@ -1514,9 +1633,7 @@ type Field = {
 
 type DecorationField = Field;
 
-type InkDecoration = {
-
-}
+type InkDecoration = {};
 
 type TemplateDecorations = Field | InkDecoration;
 
@@ -1545,85 +1662,86 @@ export interface FieldOpts {
     fieldViewType?: 'freeform' | 'stacked';
 }
 
-interface TemplateOpts extends FieldOpts {
-
-}
+interface TemplateOpts extends FieldOpts {}
 
 export class FieldUtils {
-
     public static contentFields = (fields: Field[]) => {
         let toRet: Field[] = [];
         fields.forEach(field => {
-            if (!field.isDecoration) { toRet.push(field) };
+            if (!field.isDecoration) {
+                toRet.push(field);
+            }
             toRet = toRet.concat(FieldUtils.contentFields(field.subfields ?? []));
         });
 
         return toRet;
-    }
+    };
 
     public static calculateFontSize = (contWidth: number, contHeight: number, text: string, uppercase: boolean): number => {
         const words: string[] = text.split(/\s+/).filter(Boolean);
 
-        let currFontSize = 1; 
+        let currFontSize = 1;
         let rowsCount = 1;
         let currTextHeight = currFontSize * rowsCount * 2;
-    
+
         while (currTextHeight <= contHeight) {
             let wordIndex = 0;
             let currentRowWidth = 0;
             let wordsInCurrRow = 0;
             rowsCount = 1;
-    
+
             while (wordIndex < words.length) {
                 const word = words[wordIndex];
-                const wordWidth = word.length * currFontSize * .5;
+                const wordWidth = word.length * currFontSize * 0.5;
                 //console.log(wordWidth)
-    
+
                 if (currentRowWidth + wordWidth <= contWidth) {
                     currentRowWidth += wordWidth;
                     ++wordsInCurrRow;
                 } else {
-                    if (words.length !== 1 && words.length > wordsInCurrRow){ 
+                    if (words.length !== 1 && words.length > wordsInCurrRow) {
                         rowsCount++;
-                        currentRowWidth = wordWidth; 
+                        currentRowWidth = wordWidth;
                         wordsInCurrRow = 1;
                     } else {
                         break;
                     }
                 }
-    
-                wordIndex++;    
+
+                wordIndex++;
             }
-    
+
             currTextHeight = rowsCount * currFontSize * 2;
             //console.log(rowsCount, currFontSize, currTextHeight)
-    
+
             currFontSize += 1;
         }
-        
+
         return currFontSize - 1;
     };
 
-    private static getDimensions = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number): {width: number, height: number, coord: {x: number, y: number}} => {
-        const l = coords.tl[0] * parentHeight / 2; const t = coords.tl[1] * parentWidth / 2; //prettier-ignore
-        const r = coords.br[0] * parentHeight / 2; const b = coords.br[1] * parentWidth / 2; //prettier-ignore
+    private static getDimensions = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number): { width: number; height: number; coord: { x: number; y: number } } => {
+        const l = (coords.tl[0] * parentHeight) / 2;
+        const t = coords.tl[1] * parentWidth / 2; //prettier-ignore
+        const r = (coords.br[0] * parentHeight) / 2;
+        const b = coords.br[1] * parentWidth / 2; //prettier-ignore
         const width = r - l;
         const height = b - t;
-        const coord = {x: l, y: t};
+        const coord = { x: l, y: t };
         //console.log(coords, parentWidth, parentHeight, height);
-        return {width, height, coord};
-    }
+        return { width, height, coord };
+    };
 
-    public static FreeformField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
-        const {width, height, coord} = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
+    public static FreeformField = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
+        const { width, height, coord } = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
 
-        const docWithBasicOpts = (Docs.Create.FreeformDocument)([], {  
-            isDefaultTemplateDoc: true, 
-            _height: height, 
-            _width: width, 
-            title: title, 
-            x: coord.x, 
-            y: coord.y, 
+        const docWithBasicOpts = Docs.Create.FreeformDocument([], {
+            isDefaultTemplateDoc: true,
+            _height: height,
+            _width: width,
+            title: title,
+            x: coord.x,
+            y: coord.y,
             backgroundColor: opts.backgroundColor ?? '',
             _layout_borderRounding: `${opts.cornerRounding}px` ?? '0px',
             borderColor: opts.borderColor,
@@ -1634,21 +1752,21 @@ export class FieldUtils {
         });
 
         return docWithBasicOpts;
-    }
+    };
 
-    public static TextField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
-        const {width, height, coord} = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
+    public static TextField = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
+        const { width, height, coord } = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
 
         const bool = true;
 
-        const docWithBasicOpts = (Docs.Create.TextDocument)(content, {   
+        const docWithBasicOpts = Docs.Create.TextDocument(content, {
             isDefaultTemplateDoc: true,
-            _height: height, 
-            _width: width, 
-            title: title, 
-            x: coord.x, 
-            y: coord.y, 
-            _text_fontSize: `${FieldUtils.calculateFontSize(width, height, content, true)}` ,
+            _height: height,
+            _width: width,
+            title: title,
+            x: coord.x,
+            y: coord.y,
+            _text_fontSize: `${FieldUtils.calculateFontSize(width, height, content, true)}`,
             backgroundColor: opts.backgroundColor ?? '',
             text_fontColor: opts.color,
             contentBold: opts.fontBold,
@@ -1665,17 +1783,17 @@ export class FieldUtils {
         docWithBasicOpts._layout_hideScroll = true;
 
         return docWithBasicOpts;
-    }
+    };
 
-    public static ImageField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
-        const {width, height, coord} = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
+    public static ImageField = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number, title: string, content: string, opts: FieldOpts) => {
+        const { width, height, coord } = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
 
-        const doc = Docs.Create.ImageDocument(content, {  
-            isDefaultTemplateDoc: true, 
-            _height: height, 
-            _width: width, 
-            title: title, 
-            x: coord.x, 
+        const doc = Docs.Create.ImageDocument(content, {
+            isDefaultTemplateDoc: true,
+            _height: height,
+            _width: width,
+            title: title,
+            x: coord.x,
             y: coord.y,
             _layout_fitWidth: false,
             backgroundColor: opts.backgroundColor ?? '',
@@ -1689,28 +1807,24 @@ export class FieldUtils {
         //setTimeout(() => {doc._height = height; doc._width = width}, 10);
 
         return doc;
-    }
+    };
 
-    public static CarouselField = (coords: {tl: [number, number], br: [number, number]}, parentWidth: number, parentHeight: number, title: string, fields: Doc[]) => {
-        const {width, height, coord} = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
+    public static CarouselField = (coords: { tl: [number, number]; br: [number, number] }, parentWidth: number, parentHeight: number, title: string, fields: Doc[]) => {
+        const { width, height, coord } = FieldUtils.getDimensions(coords, parentWidth, parentHeight);
 
-        const doc = Docs.Create.Carousel3DDocument(fields, { _height: height, _width: width, title: title, x: coord.x, y: coord.y, _text_fontSize: `${height/2}` })
+        const doc = Docs.Create.Carousel3DDocument(fields, { _height: height, _width: width, title: title, x: coord.x, y: coord.y, _text_fontSize: `${height / 2}` });
 
         return doc;
-    }
-    
+    };
 }
 
 export class TemplateLayouts {
-
     public static get allTemplates(): TemplateDocInfos[] {
-        return Object.values(TemplateLayouts).filter(
-            value => typeof value === 'object' && value !== null && 'title' in value
-        ) as TemplateDocInfos[];
+        return Object.values(TemplateLayouts).filter(value => typeof value === 'object' && value !== null && 'title' in value) as TemplateDocInfos[];
     }
 
     public static getTemplateByTitle = (title: string): TemplateDocInfos | undefined => {
-        switch (title){
+        switch (title) {
             case 'fourfield1':
                 return TemplateLayouts.FourField001;
             case 'fourfield2':
@@ -1728,173 +1842,187 @@ export class TemplateLayouts {
         }
 
         return undefined;
-    }
+    };
 
     public static FourField001: TemplateDocInfos = {
         title: 'fourfield1',
-        width: 416, 
-        height: 700, 
+        width: 416,
+        height: 700,
         opts: {
             backgroundColor: '#C0B887',
             cornerRounding: 20,
             borderColor: '#6B461F',
             borderWidth: '12',
         },
-        fields: [{
-            tl: [-.95, -1], 
-            br: [.95, -.85], 
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.TINY],
-            description: 'A title field for very short text that contextualizes the content.',
-            opts: {
-                backgroundColor: 'transparent',
-                color: '#F1F0E9',
-                contentXCentering: 'h-center',
-                fontBold: true,
-            }
-        }, {
-            tl: [-.87, -.83], 
-            br: [.87, .2], 
-            types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
-            sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
-            description: 'The main focus of the template; could be an image, long text, etc.',
-            opts: {
-                cornerRounding: 20,
-                borderColor: '#8F5B25',
-                borderWidth: '6',
-                backgroundColor: '#CECAB9',
-            }
-        }, {
-            tl: [-.8, .2], 
-            br: [.8, .3],  
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
-            description: 'A caption for field #2, very short to short text that contextualizes the content of field #2',
-            opts: {
-                backgroundColor: 'transparent',
-                contentXCentering: 'h-center',
-                color: '#F1F0E9',
-            }
-        }, {
-            tl: [-.87, .37], 
-            br: [.87, .96], 
-            types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
-            sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
-            description: 'A medium-sized field for medium/long text.',
-            opts: {
-                cornerRounding: 15,
-                borderColor: '#8F5B25', 
-                borderWidth: '6',
-                backgroundColor: '#CECAB9',
-            }
-        }],
+        fields: [
+            {
+                tl: [-0.95, -1],
+                br: [0.95, -0.85],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.TINY],
+                description: 'A title field for very short text that contextualizes the content.',
+                opts: {
+                    backgroundColor: 'transparent',
+                    color: '#F1F0E9',
+                    contentXCentering: 'h-center',
+                    fontBold: true,
+                },
+            },
+            {
+                tl: [-0.87, -0.83],
+                br: [0.87, 0.2],
+                types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
+                sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+                description: 'The main focus of the template; could be an image, long text, etc.',
+                opts: {
+                    cornerRounding: 20,
+                    borderColor: '#8F5B25',
+                    borderWidth: '6',
+                    backgroundColor: '#CECAB9',
+                },
+            },
+            {
+                tl: [-0.8, 0.2],
+                br: [0.8, 0.3],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
+                description: 'A caption for field #2, very short to short text that contextualizes the content of field #2',
+                opts: {
+                    backgroundColor: 'transparent',
+                    contentXCentering: 'h-center',
+                    color: '#F1F0E9',
+                },
+            },
+            {
+                tl: [-0.87, 0.37],
+                br: [0.87, 0.96],
+                types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
+                sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+                description: 'A medium-sized field for medium/long text.',
+                opts: {
+                    cornerRounding: 15,
+                    borderColor: '#8F5B25',
+                    borderWidth: '6',
+                    backgroundColor: '#CECAB9',
+                },
+            },
+        ],
         decorations: [],
     };
 
     public static FourField002: TemplateDocInfos = {
         title: 'fourfield2',
-        width: 425, 
-        height: 778, 
+        width: 425,
+        height: 778,
         opts: {
-            backgroundColor: '#242425'
+            backgroundColor: '#242425',
         },
-        fields: [{
-            tl: [-.83, -.95], 
-            br: [.83, -.2], 
-            types: [TemplateFieldType.VISUAL, TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
-            description: 'A medium to large-sized field suitable for an image or longer text that should be the main focus.',
-            opts: {
-                borderWidth: '8',
-                borderColor: '#F8E71C',
-            }
-        }, {
-            tl: [-.65, -.2], 
-            br: [.65, -.02], 
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.TINY],
-            description: 'A tiny field for just a word or two of plain text.',
-            opts: {
-                backgroundColor: 'transparent',
-                color: 'white',
-                contentXCentering: 'h-center',
-                fontTransform: 'uppercase'
-            }
-        }, {
-            tl: [-.65, 0], 
-            br: [.65, .18], 
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.TINY],
-            description: 'A tiny field for just a word or two of plain text.',
-            opts: {
-                backgroundColor: 'transparent',
-                color: 'white',
-                contentXCentering: 'h-center',
-                fontTransform: 'uppercase'
-            }
-        }, {
-            tl: [-.83, .2], 
-            br: [.83, .95], 
-            types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
-            sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
-            description: 'A medium to large-sized field suitable for an image or longer text that should be the main focus, or share focus with field 1.',
-            opts: {
-                borderWidth: '8',
-                borderColor: '#F8E71C',
-                color: 'white',
-                backgroundColor: '#242425',
-            }
-        }],
-        decorations: [{
-            tl: [-.8, -.075], 
-            br: [-.525, .075], 
-            opts: {
-                backgroundColor: '#F8E71C',
-                rotation: 45
-            }
-        }, {
-            tl: [-.3075, -.0245], 
-            br: [-.2175, .0245], 
-            opts: {
-                backgroundColor: '#F8E71C',
-                rotation: 45
-            }
-        }, {
-            tl: [-.045, -.0245], 
-            br: [.045, .0245], 
-            opts: {
-                backgroundColor: '#F8E71C',
-                rotation: 45
-            }
-        }, {
-            tl: [.2175, -.0245], 
-            br: [.3075, .0245], 
-            opts: {
-                backgroundColor: '#F8E71C',
-                rotation: 45
-            }
-        }, {
-            tl: [.525, -.075], 
-            br: [.8, .075], 
-            opts: {
-                backgroundColor: '#F8E71C',
-                rotation: 45
-            }
-        }
-
-        ]
+        fields: [
+            {
+                tl: [-0.83, -0.95],
+                br: [0.83, -0.2],
+                types: [TemplateFieldType.VISUAL, TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
+                description: 'A medium to large-sized field suitable for an image or longer text that should be the main focus.',
+                opts: {
+                    borderWidth: '8',
+                    borderColor: '#F8E71C',
+                },
+            },
+            {
+                tl: [-0.65, -0.2],
+                br: [0.65, -0.02],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.TINY],
+                description: 'A tiny field for just a word or two of plain text.',
+                opts: {
+                    backgroundColor: 'transparent',
+                    color: 'white',
+                    contentXCentering: 'h-center',
+                    fontTransform: 'uppercase',
+                },
+            },
+            {
+                tl: [-0.65, 0],
+                br: [0.65, 0.18],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.TINY],
+                description: 'A tiny field for just a word or two of plain text.',
+                opts: {
+                    backgroundColor: 'transparent',
+                    color: 'white',
+                    contentXCentering: 'h-center',
+                    fontTransform: 'uppercase',
+                },
+            },
+            {
+                tl: [-0.83, 0.2],
+                br: [0.83, 0.95],
+                types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
+                sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+                description: 'A medium to large-sized field suitable for an image or longer text that should be the main focus, or share focus with field 1.',
+                opts: {
+                    borderWidth: '8',
+                    borderColor: '#F8E71C',
+                    color: 'white',
+                    backgroundColor: '#242425',
+                },
+            },
+        ],
+        decorations: [
+            {
+                tl: [-0.8, -0.075],
+                br: [-0.525, 0.075],
+                opts: {
+                    backgroundColor: '#F8E71C',
+                    rotation: 45,
+                },
+            },
+            {
+                tl: [-0.3075, -0.0245],
+                br: [-0.2175, 0.0245],
+                opts: {
+                    backgroundColor: '#F8E71C',
+                    rotation: 45,
+                },
+            },
+            {
+                tl: [-0.045, -0.0245],
+                br: [0.045, 0.0245],
+                opts: {
+                    backgroundColor: '#F8E71C',
+                    rotation: 45,
+                },
+            },
+            {
+                tl: [0.2175, -0.0245],
+                br: [0.3075, 0.0245],
+                opts: {
+                    backgroundColor: '#F8E71C',
+                    rotation: 45,
+                },
+            },
+            {
+                tl: [0.525, -0.075],
+                br: [0.8, 0.075],
+                opts: {
+                    backgroundColor: '#F8E71C',
+                    rotation: 45,
+                },
+            },
+        ],
     };
 
     // public static FourField003: TemplateDocInfos = {
     //     title: 'fourfield3',
-    //     width: 477, 
-    //     height: 662, 
+    //     width: 477,
+    //     height: 662,
     //     opts: {
     //         backgroundColor: '#9E9C95'
     //     },
     //     fields: [{
-    //         tl: [-.875, -.9], 
-    //         br: [.875, .7], 
+    //         tl: [-.875, -.9],
+    //         br: [.875, .7],
     //         types: [TemplateFieldType.VISUAL],
     //         sizes: [TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
     //         description: '',
@@ -1903,8 +2031,8 @@ export class TemplateLayouts {
     //             borderColor: '#E0E0DA',
     //         }
     //     }, {
-    //         tl: [-.95, .8], 
-    //         br: [-.1, .95], 
+    //         tl: [-.95, .8],
+    //         br: [-.1, .95],
     //         types: [TemplateFieldType.TEXT],
     //         sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
     //         description: '',
@@ -1914,8 +2042,8 @@ export class TemplateLayouts {
     //             contentXCentering: 'h-right',
     //         }
     //     }, {
-    //         tl: [.1, .8], 
-    //         br: [.95, .95], 
+    //         tl: [.1, .8],
+    //         br: [.95, .95],
     //         types: [TemplateFieldType.TEXT],
     //         sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
     //         description: '',
@@ -1926,8 +2054,8 @@ export class TemplateLayouts {
     //             contentXCentering: 'h-left'
     //         }
     //     }, {
-    //         tl: [0, -.9], 
-    //         br: [.85, -.66], 
+    //         tl: [0, -.9],
+    //         br: [.85, -.66],
     //         types: [TemplateFieldType.TEXT, TemplateFieldType.VISUAL],
     //         sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
     //         description: '',
@@ -1937,8 +2065,8 @@ export class TemplateLayouts {
     //         }
     //     }],
     //     decorations: [{
-    //         tl: [-.025, .8], 
-    //         br: [.025, .95], 
+    //         tl: [-.025, .8],
+    //         br: [.025, .95],
     //         opts: {
     //             backgroundColor: '#E0E0DA',
     //         }
@@ -1947,242 +2075,257 @@ export class TemplateLayouts {
 
     public static FourField004: TemplateDocInfos = {
         title: 'fourfield4',
-        width: 414, 
-        height: 583, 
+        width: 414,
+        height: 583,
         opts: {
             backgroundColor: '#6CCAF0',
             borderColor: '#1088C3',
-            borderWidth: '10'
+            borderWidth: '10',
         },
-        fields: [{
-            tl: [-.86, -.92], 
-            br: [-.075, -.77], 
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.TINY],
-            description: 'A tiny field for just a word or two of plain text.',
-            opts: {
-                backgroundColor: '#E2B4F5',
-                borderWidth: '9',
-                borderColor: '#9222F1',
-                contentXCentering: 'h-center'
-            }
-        }, {
-            tl: [.075, -.92], 
-            br: [.86, -.77], 
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.TINY],
-            description: 'A tiny field for just a word or two of plain text.',
-            opts: {
-                backgroundColor: '#F5B4DD',
-                borderWidth: '9',
-                borderColor: '#E260F3',
-                contentXCentering: 'h-center'
-            }
-        }, {
-            tl: [-.81, -.64], 
-            br: [.81, .48], 
-            types: [TemplateFieldType.VISUAL],
-            sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
-            description: 'A large to huge field for visual content that is the main content of the template.',
-            opts: {
-                borderWidth: '16',
-                borderColor: '#A2BD77',
-            }
-        }, {
-            tl: [-.86, .6], 
-            br: [.86, .92], 
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
-            description: 'A medium to large field for text that describes the visual content above',
-            opts: {
-                borderWidth: '9',
-                borderColor: '#F0D601',
-                backgroundColor: '#F3F57D',
-            }
-        }],
-        decorations: [{
-            tl: [-.852, -.67], 
-            br: [.852, .51], 
-            opts: {
-                backgroundColor: 'transparent',
-                borderColor: '#007C0C',
-                borderWidth: '10',
-            }
-        }]
+        fields: [
+            {
+                tl: [-0.86, -0.92],
+                br: [-0.075, -0.77],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.TINY],
+                description: 'A tiny field for just a word or two of plain text.',
+                opts: {
+                    backgroundColor: '#E2B4F5',
+                    borderWidth: '9',
+                    borderColor: '#9222F1',
+                    contentXCentering: 'h-center',
+                },
+            },
+            {
+                tl: [0.075, -0.92],
+                br: [0.86, -0.77],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.TINY],
+                description: 'A tiny field for just a word or two of plain text.',
+                opts: {
+                    backgroundColor: '#F5B4DD',
+                    borderWidth: '9',
+                    borderColor: '#E260F3',
+                    contentXCentering: 'h-center',
+                },
+            },
+            {
+                tl: [-0.81, -0.64],
+                br: [0.81, 0.48],
+                types: [TemplateFieldType.VISUAL],
+                sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+                description: 'A large to huge field for visual content that is the main content of the template.',
+                opts: {
+                    borderWidth: '16',
+                    borderColor: '#A2BD77',
+                },
+            },
+            {
+                tl: [-0.86, 0.6],
+                br: [0.86, 0.92],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
+                description: 'A medium to large field for text that describes the visual content above',
+                opts: {
+                    borderWidth: '9',
+                    borderColor: '#F0D601',
+                    backgroundColor: '#F3F57D',
+                },
+            },
+        ],
+        decorations: [
+            {
+                tl: [-0.852, -0.67],
+                br: [0.852, 0.51],
+                opts: {
+                    backgroundColor: 'transparent',
+                    borderColor: '#007C0C',
+                    borderWidth: '10',
+                },
+            },
+        ],
     };
 
     public static ThreeField001: TemplateDocInfos = {
         title: 'threefield1',
-        width: 575, 
-        height: 770, 
+        width: 575,
+        height: 770,
         opts: {
-            backgroundColor: '#DDD3A9'
+            backgroundColor: '#DDD3A9',
         },
-        fields: [{
-            tl: [-.66, -.747], 
-            br: [.66, .247], 
-            types: [TemplateFieldType.VISUAL],
-            sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
-            description: 'A medium to large field for visual content that is the central focus.',
-            opts: {
-                borderColor: 'yellow',
-                borderWidth: '8',
-                rotation: 45,
+        fields: [
+            {
+                tl: [-0.66, -0.747],
+                br: [0.66, 0.247],
+                types: [TemplateFieldType.VISUAL],
+                sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+                description: 'A medium to large field for visual content that is the central focus.',
+                opts: {
+                    borderColor: 'yellow',
+                    borderWidth: '8',
+                    rotation: 45,
+                },
             },
-        }, {
-            tl: [-.7, .2], 
-            br: [.7, .46], 
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
-            description: 'A very small text field for one to a few words. A good caption for the image.',
-            opts: {
-                backgroundColor: 'transparent',
-                contentXCentering: 'h-center',
-            }
-        }, {
-            tl: [-.95, .5], 
-            br: [.95, .95], 
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
-            description: 'A medium to large text field for a thorough description of the image. ',
-            opts: {
-                backgroundColor: 'transparent',
-                color: 'white'
-            }
-        }],
-        decorations: [{
-            tl: [.2, -1.32], 
-            br: [1.8, -.66], 
-            opts: {
-                backgroundColor: '#CEB155',
-                rotation: 45,
-            }
-        }, {
-            tl: [-1.8, -1.32], 
-            br: [-.2, -.66], 
-            opts: {
-                backgroundColor: '#CEB155',
-                rotation: 135,
-            }
-        }, {
-            tl: [.33, .75], 
-            br: [1.66, 1.25], 
-            opts: {
-                backgroundColor: '#CEB155',
-                rotation: 135,
-            }
-        }, {
-            tl: [-1.66, .75], 
-            br: [-.33, 1.25], 
-            opts: {
-                backgroundColor: '#CEB155',
-                rotation: 45,
-            }
-        }]
+            {
+                tl: [-0.7, 0.2],
+                br: [0.7, 0.46],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
+                description: 'A very small text field for one to a few words. A good caption for the image.',
+                opts: {
+                    backgroundColor: 'transparent',
+                    contentXCentering: 'h-center',
+                },
+            },
+            {
+                tl: [-0.95, 0.5],
+                br: [0.95, 0.95],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE],
+                description: 'A medium to large text field for a thorough description of the image. ',
+                opts: {
+                    backgroundColor: 'transparent',
+                    color: 'white',
+                },
+            },
+        ],
+        decorations: [
+            {
+                tl: [0.2, -1.32],
+                br: [1.8, -0.66],
+                opts: {
+                    backgroundColor: '#CEB155',
+                    rotation: 45,
+                },
+            },
+            {
+                tl: [-1.8, -1.32],
+                br: [-0.2, -0.66],
+                opts: {
+                    backgroundColor: '#CEB155',
+                    rotation: 135,
+                },
+            },
+            {
+                tl: [0.33, 0.75],
+                br: [1.66, 1.25],
+                opts: {
+                    backgroundColor: '#CEB155',
+                    rotation: 135,
+                },
+            },
+            {
+                tl: [-1.66, 0.75],
+                br: [-0.33, 1.25],
+                opts: {
+                    backgroundColor: '#CEB155',
+                    rotation: 45,
+                },
+            },
+        ],
     };
 
     public static ThreeField002: TemplateDocInfos = {
         title: 'threefield2',
-        width: 477, 
-        height: 662, 
+        width: 477,
+        height: 662,
         opts: {
-            backgroundColor: '#9E9C95'
+            backgroundColor: '#9E9C95',
         },
-        fields: [{
-            tl: [-.875, -.9], 
-            br: [.875, .7], 
-            types: [TemplateFieldType.VISUAL],
-            sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
-            description: 'A medium to large visual field for the main content of the template',
-            opts: {
-                borderWidth: '15',
-                borderColor: '#E0E0DA',
-            }
-        }, {
-            tl: [.1, .775], 
-            br: [.95, .975], 
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
-            description: 'A very small text field for one to a few words. The content should represent a general categorization of the image.',
-            opts: {
-                backgroundColor: 'transparent',
-                color: '#AF0D0D',
-                fontTransform: 'uppercase',
-                fontBold: true,
-                contentXCentering: 'h-left'
-            }
-        }, {
-            tl: [-.95, .775], 
-            br: [-.1, .975],
-            types: [TemplateFieldType.TEXT],
-            sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
-            description: 'A very small text field for one to a few words. The content should contextualize field 2.',
-            opts: {
-                backgroundColor: 'transparent',
-                color: 'black',
-                contentXCentering: 'h-right'
-            }
-        }],
-        decorations: [{
-            tl: [-.025, .8], 
-            br: [.025, .95], 
-            opts: {
-                backgroundColor: '#E0E0DA',
-            }
-        }]
+        fields: [
+            {
+                tl: [-0.875, -0.9],
+                br: [0.875, 0.7],
+                types: [TemplateFieldType.VISUAL],
+                sizes: [TemplateFieldSize.MEDIUM, TemplateFieldSize.LARGE, TemplateFieldSize.HUGE],
+                description: 'A medium to large visual field for the main content of the template',
+                opts: {
+                    borderWidth: '15',
+                    borderColor: '#E0E0DA',
+                },
+            },
+            {
+                tl: [0.1, 0.775],
+                br: [0.95, 0.975],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
+                description: 'A very small text field for one to a few words. The content should represent a general categorization of the image.',
+                opts: {
+                    backgroundColor: 'transparent',
+                    color: '#AF0D0D',
+                    fontTransform: 'uppercase',
+                    fontBold: true,
+                    contentXCentering: 'h-left',
+                },
+            },
+            {
+                tl: [-0.95, 0.775],
+                br: [-0.1, 0.975],
+                types: [TemplateFieldType.TEXT],
+                sizes: [TemplateFieldSize.TINY, TemplateFieldSize.SMALL],
+                description: 'A very small text field for one to a few words. The content should contextualize field 2.',
+                opts: {
+                    backgroundColor: 'transparent',
+                    color: 'black',
+                    contentXCentering: 'h-right',
+                },
+            },
+        ],
+        decorations: [
+            {
+                tl: [-0.025, 0.8],
+                br: [0.025, 0.95],
+                opts: {
+                    backgroundColor: '#E0E0DA',
+                },
+            },
+        ],
     };
 
-
-
-//     public static FourField002: TemplateDocInfos = {
-//         width: 450, 
-//         height: 600, 
-//         fields: [{
-//             tl: [-.6, -.9], 
-//             br: [.6, -.8], 
-//             types: [FieldType.TEXT],
-//             sizes: [FieldSize.TINY]
-//         }, {
-//             tl: [-.9, -.7], 
-//             br: [.9, .2], 
-//             types: [FieldType.TEXT, FieldType.VISUAL],
-//             sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE]
-//         }, {
-//             tl: [-.9, .3], 
-//             br: [-.05, .9], 
-//             types: [FieldType.TEXT],
-//             sizes: [FieldSize.TINY]
-//         }, {
-//             tl: [.05, .3], 
-//             br: [.9, .9], 
-//             types: [FieldType.TEXT, FieldType.VISUAL],
-//             sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE]
-//         }]
-//     };
-
-//     public static TwoFieldPlusCarousel: TemplateDocInfos = {
-//         width: 500, 
-//         height: 600, 
-//         fields: [{
-//             tl: [-.9, -.99], 
-//             br: [.9, -.7], 
-//             types: [FieldType.TEXT],
-//             sizes: [FieldSize.TINY]
-//         }, {
-//             tl: [-.9, -.65], 
-//             br: [.9, .35], 
-//             types: [],
-//             sizes: []
-//         }, {
-//             tl: [-.9, .4], 
-//             br: [.9, .95], 
-//             types: [FieldType.TEXT],
-//             sizes: [FieldSize.TINY]
-//         }]
-//     };
-
+    //     public static FourField002: TemplateDocInfos = {
+    //         width: 450,
+    //         height: 600,
+    //         fields: [{
+    //             tl: [-.6, -.9],
+    //             br: [.6, -.8],
+    //             types: [FieldType.TEXT],
+    //             sizes: [FieldSize.TINY]
+    //         }, {
+    //             tl: [-.9, -.7],
+    //             br: [.9, .2],
+    //             types: [FieldType.TEXT, FieldType.VISUAL],
+    //             sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE]
+    //         }, {
+    //             tl: [-.9, .3],
+    //             br: [-.05, .9],
+    //             types: [FieldType.TEXT],
+    //             sizes: [FieldSize.TINY]
+    //         }, {
+    //             tl: [.05, .3],
+    //             br: [.9, .9],
+    //             types: [FieldType.TEXT, FieldType.VISUAL],
+    //             sizes: [FieldSize.MEDIUM, FieldSize.LARGE, FieldSize.HUGE]
+    //         }]
+    //     };
+
+    //     public static TwoFieldPlusCarousel: TemplateDocInfos = {
+    //         width: 500,
+    //         height: 600,
+    //         fields: [{
+    //             tl: [-.9, -.99],
+    //             br: [.9, -.7],
+    //             types: [FieldType.TEXT],
+    //             sizes: [FieldSize.TINY]
+    //         }, {
+    //             tl: [-.9, -.65],
+    //             br: [.9, .35],
+    //             types: [],
+    //             sizes: []
+    //         }, {
+    //             tl: [-.9, .4],
+    //             br: [.9, .95],
+    //             types: [FieldType.TEXT],
+    //             sizes: [FieldSize.TINY]
+    //         }]
+    //     };
 }
-
-export class ContentField extends Field {
-    
-}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2

