From 1536f8d6e5f44fd14954550e9bd670561727b417 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 28 Aug 2020 15:45:07 -0400
Subject: fixed undo for collection tabs. fixed treeview to support
 freezeChildren to prevent children from being removed from the tree.  Made
 _isBackground a layoutfield.  fixed formattedTextBox exceptions on undo from
 a tab.

---
 src/client/views/collections/collectionFreeForm/PropertiesView.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/collections/collectionFreeForm/PropertiesView.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index f9ffb4260..c316e1aad 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -148,7 +148,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                     &nbsp;
                 </div>);
                 } else {
-                    let contentElement = <EditableView key="editableView"
+                    const contentElement = <EditableView key="editableView"
                         contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
                         height={13}
                         fontSize={10}
-- 
cgit v1.2.3-70-g09d2


From 55f99f4bcc45b1dc797982273e93f49fb58403c3 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 28 Aug 2020 18:15:46 -0400
Subject: added explicit annotation mode for videos.  fixed annotation mode for
 webpages

---
 src/client/views/DocumentButtonBar.tsx             | 30 ++++----
 .../views/collections/CollectionDockingView.tsx    |  9 +--
 src/client/views/collections/CollectionMenu.tsx    | 12 ---
 .../views/collections/ParentDocumentSelector.tsx   | 41 ++++-------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 .../collectionFreeForm/PropertiesView.tsx          |  4 +-
 src/client/views/nodes/VideoBox.tsx                |  6 +-
 src/client/views/nodes/WebBox.scss                 | 66 +++--------------
 src/client/views/nodes/WebBox.tsx                  | 85 +++-------------------
 9 files changed, 63 insertions(+), 192 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/PropertiesView.tsx')

diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index ed5ba9e71..d342eb95f 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -5,7 +5,7 @@ import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { Doc } from "../../fields/Doc";
 import { RichTextField } from '../../fields/RichTextField';
-import { Cast, NumCast } from "../../fields/Types";
+import { Cast, NumCast, StrCast } from "../../fields/Types";
 import { emptyFunction, setupMoveUpEvents } from "../../Utils";
 import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
 import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
@@ -15,7 +15,6 @@ import { DragManager } from '../util/DragManager';
 import { SelectionManager } from '../util/SelectionManager';
 import { SharingManager } from '../util/SharingManager';
 import { CollectionDockingView, DockedFrameRenderer } from './collections/CollectionDockingView';
-import { ParentDocSelector } from './collections/ParentDocumentSelector';
 import './collections/ParentDocumentSelector.scss';
 import './DocumentButtonBar.scss';
 import { MetadataEntryMenu } from './MetadataEntryMenu';
@@ -25,6 +24,7 @@ import { GoogleRef } from "./nodes/formattedText/FormattedTextBox";
 import { TemplateMenu } from "./TemplateMenu";
 import { Template, Templates } from "./Templates";
 import React = require("react");
+import { DocumentType } from '../documents/DocumentTypes';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -211,6 +211,18 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
             </div></Tooltip >;
     }
 
+    @computed
+    get annotateButton() {
+        const targetDoc = this.view0?.props.Document;
+        const isAnnotating = targetDoc?.isAnnotating;
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{`${isAnnotating ? "Exit" : "Enter"} annotation mode`}</div></>}>
+            <div className="documentButtonBar-linker" style={{ backgroundColor: isAnnotating ? "white" : "", color: isAnnotating ? "black" : "white", }}
+                onClick={e => targetDoc.isAnnotating = !targetDoc.isAnnotating}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="edit"
+                />
+            </div></Tooltip >;
+    }
+
     @computed
     get moreButton() {
         const targetDoc = this.view0?.props.Document;
@@ -235,17 +247,6 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
                 </Flyout>
             </div></Tooltip>;
     }
-
-    @computed
-    get contextButton() {
-        return !this.view0 ? (null) : <ParentDocSelector Document={this.view0.props.Document} addDocTab={(doc, where) => {
-            where === "onRight" ? CollectionDockingView.AddRightSplit(doc) :
-                this.props.stack ? CollectionDockingView.Instance.AddTab(this.props.stack, doc) :
-                    this.view0?.props.addDocTab(doc, "onRight");
-            return true;
-        }} />;
-    }
-
     @observable _aliasDown = false;
     onAliasButtonDown = (e: React.PointerEvent): void => {
         setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction);
@@ -313,6 +314,9 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
             {!Doc.UserDoc()["documentLinksButton-hideEnd"] ? (null) : <div className="documentButtonBar-button">
                 {this.shareButton}
             </div>}
+            {![DocumentType.VID, DocumentType.WEB].includes(StrCast(this.view0.props.Document.type) as DocumentType) ? (null) : <div className="documentButtonBar-button">
+                {this.annotateButton}
+            </div>}
             <div className="documentButtonBar-button">
                 {this.moreButton}
             </div>
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 86d27acd5..816f784ff 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -5,8 +5,7 @@ import { action, computed, IReactionDisposer, Lambda, observable, reaction, runI
 import { observer } from "mobx-react";
 import * as ReactDOM from 'react-dom';
 import * as GoldenLayout from "../../../client/goldenLayout";
-import { DateField } from '../../../fields/DateField';
-import { DataSym, Doc, DocListCast, Field, Opt } from "../../../fields/Doc";
+import { DataSym, Doc, DocListCast, Opt } from "../../../fields/Doc";
 import { Id } from '../../../fields/FieldSymbols';
 import { InkTool } from '../../../fields/InkField';
 import { List } from '../../../fields/List';
@@ -14,9 +13,10 @@ import { FieldId } from "../../../fields/RefField";
 import { listSpec } from '../../../fields/Schema';
 import { Cast, NumCast, StrCast } from "../../../fields/Types";
 import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, Utils, returnEmptyDoclist } from "../../../Utils";
+import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, Utils } from "../../../Utils";
 import { DocServer } from "../../DocServer";
 import { Docs } from '../../documents/Documents';
+import { CurrentUserUtils } from '../../util/CurrentUserUtils';
 import { DocumentManager } from '../../util/DocumentManager';
 import { DragManager, dropActionType } from "../../util/DragManager";
 import { InteractionUtils } from '../../util/InteractionUtils';
@@ -29,11 +29,10 @@ import { DocumentView } from "../nodes/DocumentView";
 import { PresBox } from '../nodes/PresBox';
 import "./CollectionDockingView.scss";
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
-import { SubCollectionViewProps, CollectionSubView } from "./CollectionSubView";
+import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView";
 import { CollectionViewType } from './CollectionView';
 import { DockingViewButtonSelector } from './ParentDocumentSelector';
 import React = require("react");
-import { CurrentUserUtils } from '../../util/CurrentUserUtils';
 const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index f5d64ba0d..a41b5eaca 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -867,18 +867,6 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
                     </div>
                 </Tooltip> : null}
 
-                {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) :
-                    <Tooltip key="hypothesis" title={<div className="dash-tooltip">Toggle between native iframe and annotation modes</div>} placement="bottom">
-                        <button className={"antimodeMenu-button"} key="hypothesis"
-                            style={{
-                                backgroundColor: this.props.docView.layoutDoc.isAnnotating ? "121212" : undefined,
-                                borderRight: "1px solid gray"
-                            }}
-                            onClick={() => this.props.docView.layoutDoc.isAnnotating = !this.props.docView.layoutDoc.isAnnotating}>
-                            <FontAwesomeIcon icon={"edit"} size="lg" />    {/* ["fab", "hire-a-helper"]} size={"lg"} /> */}
-                        </button>
-                    </Tooltip>
-                }
                 {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) :
                     this.urlEditor
                 }
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index 6556e7889..f019ddfe6 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -1,6 +1,6 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { Tooltip } from "@material-ui/core";
-import { computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
+import { computed, IReactionDisposer, observable, reaction, runInAction, action } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
 import { Doc } from "../../../fields/Doc";
@@ -71,25 +71,6 @@ export class SelectorContextMenu extends React.Component<SelectorProps> {
         </div>;
     }
 }
-
-@observer
-export class ParentDocSelector extends React.Component<SelectorProps> {
-    render() {
-        const flyout = (
-            <div className="parentDocumentSelector-flyout" title=" ">
-                <SelectorContextMenu {...this.props} />
-            </div>
-        );
-        return <div title="Show Contexts" onPointerDown={e => e.stopPropagation()} className="parentDocumentSelector-linkFlyout">
-            <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={flyout}>
-                <span className="parentDocumentSelector-button" >
-                    <FontAwesomeIcon icon={"chevron-circle-up"} size={"lg"} />
-                </span>
-            </Flyout>
-        </div>;
-    }
-}
-
 @observer
 export class DockingViewButtonSelector extends React.Component<{ views: () => DocumentView[], Stack: any }> {
     customStylesheet(styles: any) {
@@ -111,18 +92,22 @@ export class DockingViewButtonSelector extends React.Component<{ views: () => Do
         );
     }
 
+    @observable _tooltipOpen: boolean = false;
     render() {
-        return <Tooltip title={<><div className="dash-tooltip">Tap for toolbar, drag to create alias in another pane</div></>} placement="bottom">
-            <span onPointerDown={e => {
-                if (getComputedStyle(this._ref.current!).width !== "100%") {
-                    e.stopPropagation(); e.preventDefault();
-                }
-                this.props.views()[0]?.select(false);
-            }} className="buttonSelector">
+        return <Tooltip open={this._tooltipOpen} onClose={action(() => this._tooltipOpen = false)} title={<><div className="dash-tooltip">Tap for toolbar, drag to create alias in another pane</div></>} placement="bottom">
+            <span className="buttonSelector"
+                onPointerEnter={action(() => !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))}
+                onPointerDown={action(e => {
+                    if (getComputedStyle(this._ref.current!).width !== "100%") {
+                        e.stopPropagation(); e.preventDefault();
+                    }
+                    this.props.views()[0]?.select(false);
+                    this._tooltipOpen = false;
+                })} >
                 <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.flyout} stylesheet={this.customStylesheet}>
                     <FontAwesomeIcon icon={"arrows-alt"} size={"sm"} />
                 </Flyout>
             </span>
-        </Tooltip>;
+        </Tooltip >;
     }
 }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b55dc467a..04c30c4f2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1637,7 +1637,7 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
             style={{
                 transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)`,
                 transition: this.props.transition,
-                willChange: "transform"
+                //willChange: "transform"
             }}>
             {this.props.children()}
             {this.presPaths}
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index c316e1aad..560f09931 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -22,11 +22,11 @@ import { ContentFittingDocumentView } from "../../nodes/ContentFittingDocumentVi
 import { KeyValueBox } from "../../nodes/KeyValueBox";
 import { PresBox } from "../../nodes/PresBox";
 import { PropertiesButtons } from "../../PropertiesButtons";
+import { CollectionDockingView } from "../CollectionDockingView";
+import { SelectorContextMenu } from "../ParentDocumentSelector";
 import { FormatShapePane } from "./FormatShapePane";
 import "./FormatShapePane.scss";
 import "./PropertiesView.scss";
-import { CollectionDockingView } from "../CollectionDockingView";
-import { ParentDocSelector, SelectorContextMenu } from "../ParentDocumentSelector";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 85d010aaa..578061344 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -275,13 +275,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
             this._youtubeReactionDisposer?.();
             this._reactionDisposer = reaction(() => this.layoutDoc._currentTimecode, () => !this._playing && this.Seek((this.layoutDoc._currentTimecode || 0)));
             this._youtubeReactionDisposer = reaction(
-                () => Doc.GetSelectedTool() === InkTool.None && this.props.isSelected(true) && !SnappingManager.GetIsDragging() && !DocumentDecorations.Instance.Interacting,
+                () => !this.props.Document.isAnnotating && Doc.GetSelectedTool() === InkTool.None && this.props.isSelected(true) && !SnappingManager.GetIsDragging() && !DocumentDecorations.Instance.Interacting,
                 (interactive) => iframe.style.pointerEvents = interactive ? "all" : "none", { fireImmediately: true });
         };
         this._youtubePlayer = new YT.Player(`${this.youtubeVideoId + this._youtubeIframeId}-player`, {
             events: {
-                'onReady': onYoutubePlayerReady,
-                'onStateChange': onYoutubePlayerStateChange,
+                'onReady': this.props.dontRegisterView ? undefined : onYoutubePlayerReady,
+                'onStateChange': this.props.dontRegisterView ? undefined : onYoutubePlayerStateChange,
             }
         });
 
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index 875142169..23a5ad824 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -70,7 +70,6 @@
         }
     }
 
-
     .webBox-overlay {
         width: 100%;
         height: 100%;
@@ -82,63 +81,22 @@
         background:lightGray;
         width: 100%;
     }
-    .webBox-freeze {
-        display: flex;
-        align-items: center; 
-        justify-content: center;
-        margin-right: 5px;
-        width: 30px;
-    }
-
-    .webBox-urlEditor {
-        position: relative;
-        opacity: 0.9;
+    .webBox-annotationToggle {
         z-index: 9001;
-        transition: top .5s;
-
-        .urlEditor {
-            display: grid;
-            grid-template-columns: 1fr auto;
-            padding-bottom: 10px;
-            overflow: hidden;
-
-            .editorBase {
-                display: flex;
-
-                .editor-collapse {
-                    transition: all .5s, opacity 0.3s;
-                    position: absolute;
-                    width: 40px;
-                    transform-origin: top left;
-                }
-
-                .switchToText {
-                    color: $main-accent;
-                }
-
-                .switchToText:hover {
-                    color: $dark-color;
-                }
-            }
-
-            button:hover {
-                transform: scale(1);
-            }
+        position: absolute;
+        top: 2;
+        left: 2;
+        box-shadow: black 0.3em 0.3em 1em;
+        border-radius: 5px;
+        display: flex;
+        width: 25px;
+        height: 25px;
+        align-items: center;
+        > svg {
+            margin: auto;
         }
     }
 
-    .webpage-urlInput {
-        padding: 12px 10px 11px 10px;
-        border: 0px;
-        color: grey;
-        letter-spacing: 2px;
-        outline-color: black;
-        background: rgb(238, 238, 238);
-        width: 100%;
-        margin-right: 10px;
-        height: 100%;
-    }
-
     .touch-iframe-overlay {
         width: 100%;
         height: 100%;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 7758b1815..290b4a720 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -31,6 +31,7 @@ import { FieldView, FieldViewProps } from './FieldView';
 import "./WebBox.scss";
 import "../pdf/PDFViewer.scss";
 import React = require("react");
+import { Tooltip } from '@material-ui/core';
 const htmlToText = require("html-to-text");
 
 type WebDocument = makeInterface<[typeof documentSchema]>;
@@ -235,81 +236,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
         e.stopPropagation();
     }
 
-    toggleAnnotationMode = () => {
-        this.layoutDoc.isAnnotating = !this.layoutDoc.isAnnotating;
-    }
-
-    urlEditor() {
-        return (
-            <div className="webBox-urlEditor"
-                onDrop={this.onUrlDrop}
-                onDragOver={this.onUrlDragover} style={{ top: this._collapsed ? -70 : 0 }}>
-                <div className="urlEditor">
-                    <div className="editorBase">
-                        <button className="editor-collapse"
-                            style={{
-                                top: this._collapsed ? 70 : 0,
-                                transform: `rotate(${this._collapsed ? 180 : 0}deg) scale(${this._collapsed ? 0.5 : 1}) translate(${this._collapsed ? "-100%, -100%" : "0, 0"})`,
-                                opacity: (this._collapsed && !this.props.isSelected()) ? 0 : 0.9,
-                                left: (this._collapsed ? 0 : "unset"),
-                            }}
-                            title="Collapse Url Editor" onClick={this.toggleCollapse}>
-                            <FontAwesomeIcon icon="caret-up" size="2x" />
-                        </button>
-                        <div className="webBox-buttons"
-                            onDrop={this.onUrlDrop}
-                            onDragOver={this.onUrlDragover} style={{ display: this._collapsed ? "none" : "flex" }}>
-                            <div className="webBox-freeze" title={"Annotate"} style={{ background: this.layoutDoc.isAnnotating ? "lightBlue" : "gray" }} onClick={this.toggleAnnotationMode} >
-                                <FontAwesomeIcon icon={faPen} size={"2x"} />
-                            </div>
-                            <div className="webBox-freeze" title={"Select"} style={{ background: !this.layoutDoc.isAnnotating ? "lightBlue" : "gray" }} onClick={this.toggleAnnotationMode} >
-                                <FontAwesomeIcon icon={faMousePointer} size={"2x"} />
-                            </div>
-                            <input className="webpage-urlInput"
-                                placeholder="ENTER URL"
-                                value={this._url}
-                                onDrop={this.onUrlDrop}
-                                onDragOver={this.onUrlDragover}
-                                onChange={this.onURLChange}
-                                onKeyDown={this.onValueKeyDown}
-                                onClick={(e) => {
-                                    this._keyInput.current!.select();
-                                    e.stopPropagation();
-                                }}
-                                ref={this._keyInput}
-                            />
-                            <div style={{
-                                display: "flex",
-                                flexDirection: "row",
-                                justifyContent: "space-between",
-                                maxWidth: "120px",
-                            }}>
-                                <button className="submitUrl" onClick={this.submitURL}
-                                    onDragOver={this.onUrlDragover} onDrop={this.onUrlDrop}>
-                                    GO
-                                </button>
-                                <button className="submitUrl" onClick={this.back}>
-                                    <FontAwesomeIcon icon="caret-left" size="lg"></FontAwesomeIcon>
-                                </button>
-                                <button className="submitUrl" onClick={this.forward}>
-                                    <FontAwesomeIcon icon="caret-right" size="lg"></FontAwesomeIcon>
-                                </button>
-                            </div>
-                        </div>
-                    </div>
-                </div>
+    editToggleBtn() {
+        return <Tooltip title={<div className="dash-tooltip" >{`${this.props.Document.isAnnotating ? "Exit" : "Enter"} annotation mode`}</div>}>
+            <div className="webBox-annotationToggle"
+                style={{ color: this.props.Document.isAnnotating ? "black" : "white", backgroundColor: this.props.Document.isAnnotating ? "white" : "black" }}
+                onClick={action(() => this.layoutDoc.isAnnotating = !this.layoutDoc.isAnnotating)}>
+                <FontAwesomeIcon icon="edit" size="lg" />
             </div>
-        );
+        </Tooltip>;
     }
 
-
-    @action
-    toggleCollapse = () => {
-        this._collapsed = !this._collapsed;
-    }
-
-
-
     _ignore = 0;
     onPreWheel = (e: React.WheelEvent) => {
         this._ignore = e.timeStamp;
@@ -474,7 +410,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                 style={{ width: Number.isFinite(this.props.ContentScaling()) ? `${Math.max(100, 100 / this.props.ContentScaling())}% ` : "100%" }}
                 onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
                 {view}
-            </div>;
+            </div>
             {!frozen ? (null) :
                 <div className="webBox-overlay" style={{ pointerEvents: this.layoutDoc._isBackground ? undefined : "all" }}
                     onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer}>
@@ -483,7 +419,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                         <div className="dragger" ref={this._iframeDragRef}></div>
                     </div>
                 </div>}
-            {this.urlEditor()}
         </>);
     }
 
@@ -741,6 +676,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
                 {this.annotationLayer}
                 <PdfViewerMarquee isMarqueeing={this.marqueeing} width={this.marqueeWidth} height={this.marqueeHeight} x={this.marqueeX} y={this.marqueeY} />
             </div >
+
+            {this.props.isSelected() ? this.editToggleBtn() : null}
         </div>);
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From f5a9d196a96f9a81436fa8de8659eaa51a131d81 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 29 Aug 2020 13:58:16 -0400
Subject: reorganized source files into proper directories.  split contents of
 ParendDocSelector into CollectionDockingViewMenu and
 PropetiesDocContextSelector

---
 src/client/views/DocumentButtonBar.tsx             |    3 +-
 src/client/views/DocumentDecorations.tsx           |    2 +-
 src/client/views/FormatShapePane.scss              |   68 ++
 src/client/views/FormatShapePane.tsx               |  545 ++++++++++
 src/client/views/GlobalKeyHandler.ts               |   10 +-
 src/client/views/InkingStroke.tsx                  |    2 +-
 src/client/views/MainView.tsx                      |   21 +-
 src/client/views/PropertiesButtons.tsx             |    1 -
 src/client/views/PropertiesDocContextSelector.scss |    0
 src/client/views/PropertiesDocContextSelector.tsx  |   58 ++
 src/client/views/PropertiesView.scss               |  779 ++++++++++++++
 src/client/views/PropertiesView.tsx                | 1089 +++++++++++++++++++
 .../views/collections/CollectionDockingView.tsx    |   13 +-
 .../collections/CollectionDockingViewMenu.scss     |   34 +
 .../collections/CollectionDockingViewMenu.tsx      |   51 +
 .../views/collections/ParentDocumentSelector.scss  |   63 --
 .../views/collections/ParentDocumentSelector.tsx   |  113 --
 .../collectionFreeForm/FormatShapePane.scss        |   68 --
 .../collectionFreeForm/FormatShapePane.tsx         |  545 ----------
 .../collectionFreeForm/PropertiesView.scss         |  779 --------------
 .../collectionFreeForm/PropertiesView.tsx          | 1090 --------------------
 src/client/views/nodes/DocumentView.tsx            |    2 +-
 src/client/views/nodes/LinkAnchorBox.scss          |    5 +
 src/client/views/nodes/LinkAnchorBox.tsx           |    2 +-
 24 files changed, 2653 insertions(+), 2690 deletions(-)
 create mode 100644 src/client/views/FormatShapePane.scss
 create mode 100644 src/client/views/FormatShapePane.tsx
 create mode 100644 src/client/views/PropertiesDocContextSelector.scss
 create mode 100644 src/client/views/PropertiesDocContextSelector.tsx
 create mode 100644 src/client/views/PropertiesView.scss
 create mode 100644 src/client/views/PropertiesView.tsx
 create mode 100644 src/client/views/collections/CollectionDockingViewMenu.scss
 create mode 100644 src/client/views/collections/CollectionDockingViewMenu.tsx
 delete mode 100644 src/client/views/collections/ParentDocumentSelector.scss
 delete mode 100644 src/client/views/collections/ParentDocumentSelector.tsx
 delete mode 100644 src/client/views/collections/collectionFreeForm/FormatShapePane.scss
 delete mode 100644 src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
 delete mode 100644 src/client/views/collections/collectionFreeForm/PropertiesView.scss
 delete mode 100644 src/client/views/collections/collectionFreeForm/PropertiesView.tsx

(limited to 'src/client/views/collections/collectionFreeForm/PropertiesView.tsx')

diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index d342eb95f..dd223390a 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -10,12 +10,12 @@ import { emptyFunction, setupMoveUpEvents } from "../../Utils";
 import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
 import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
 import { Docs } from '../documents/Documents';
+import { DocumentType } from '../documents/DocumentTypes';
 import { CurrentUserUtils } from '../util/CurrentUserUtils';
 import { DragManager } from '../util/DragManager';
 import { SelectionManager } from '../util/SelectionManager';
 import { SharingManager } from '../util/SharingManager';
 import { CollectionDockingView, DockedFrameRenderer } from './collections/CollectionDockingView';
-import './collections/ParentDocumentSelector.scss';
 import './DocumentButtonBar.scss';
 import { MetadataEntryMenu } from './MetadataEntryMenu';
 import { DocumentLinksButton } from './nodes/DocumentLinksButton';
@@ -24,7 +24,6 @@ import { GoogleRef } from "./nodes/formattedText/FormattedTextBox";
 import { TemplateMenu } from "./TemplateMenu";
 import { Template, Templates } from "./Templates";
 import React = require("react");
-import { DocumentType } from '../documents/DocumentTypes';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index fad6b1a0b..6c64a3714 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -18,9 +18,9 @@ import { SelectionManager } from "../util/SelectionManager";
 import { SnappingManager } from '../util/SnappingManager';
 import { undoBatch, UndoManager } from "../util/UndoManager";
 import { CollectionDockingView } from './collections/CollectionDockingView';
-import { FormatShapePane } from './collections/collectionFreeForm/FormatShapePane';
 import { DocumentButtonBar } from './DocumentButtonBar';
 import './DocumentDecorations.scss';
+import { FormatShapePane } from './FormatShapePane';
 import { DocumentView } from "./nodes/DocumentView";
 import React = require("react");
 import e = require('express');
diff --git a/src/client/views/FormatShapePane.scss b/src/client/views/FormatShapePane.scss
new file mode 100644
index 000000000..d49ab27fb
--- /dev/null
+++ b/src/client/views/FormatShapePane.scss
@@ -0,0 +1,68 @@
+.antimodeMenu-button {
+    width: 200px;
+    position: relative;
+    text-align: left;
+
+    .color-previewI {
+        width: 100%;
+        height: 40%;
+    }
+
+    .color-previewII {
+        width: 100%;
+        height: 100%;
+    }
+}
+
+.antimenu-Buttonup {
+    position: absolute;
+    width: 20;
+    height: 10;
+    right: 0;
+    padding: 0;
+}
+
+.formatShapePane-inputBtn {
+    width: inherit;
+    position: absolute;
+}
+
+.btn-group-palette {
+    .sketch-picker {
+        background: #323232;
+        width: 160px !important;
+        height: 80% !important;
+
+        .flexbox-fit {
+            background: #323232;
+        }
+    }
+}
+
+.btn-group {
+    display: grid;
+    grid-template-columns: auto auto auto auto;
+    /* Make the buttons appear below each other */
+}
+
+.btn-group-palette {
+    display: block;
+    /* Make the buttons appear below each other */
+}
+
+.btn-draw {
+    display: inline;
+    /* Make the buttons appear below each other */
+}
+
+.btn2-group {
+    display: block;
+    background: #323232;
+    grid-template-columns: auto;
+
+    /* Make the buttons appear below each other */
+    .antimodeMenu-button {
+        background: #323232;
+        display: block;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/FormatShapePane.tsx b/src/client/views/FormatShapePane.tsx
new file mode 100644
index 000000000..293a06dc0
--- /dev/null
+++ b/src/client/views/FormatShapePane.tsx
@@ -0,0 +1,545 @@
+import React = require("react");
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, computed, observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { ColorState, SketchPicker } from 'react-color';
+import { Doc, Field, Opt } from "../../fields/Doc";
+import { Document } from "../../fields/documentSchemas";
+import { InkField } from "../../fields/InkField";
+import { BoolCast, Cast, NumCast } from "../../fields/Types";
+import { DocumentType } from "../documents/DocumentTypes";
+import { SelectionManager } from "../util/SelectionManager";
+import { undoBatch } from "../util/UndoManager";
+import { AntimodeMenu, AntimodeMenuProps } from "./AntimodeMenu";
+import "./FormatShapePane.scss";
+
+@observer
+export class FormatShapePane extends AntimodeMenu<AntimodeMenuProps> {
+    static Instance: FormatShapePane;
+
+    private _lastFill = "#D0021B";
+    private _lastLine = "#D0021B";
+    private _lastDash = "2";
+    private _mode = ["fill-drip", "ruler-combined"];
+
+    @observable private _subOpen = [false, false];
+    @observable private _currMode = "fill-drip";
+    @observable _lock = false;
+    @observable private _fillBtn = false;
+    @observable private _lineBtn = false;
+    @observable _controlBtn = false;
+    @observable private _controlPoints: { X: number, Y: number }[] = [];
+    @observable _currPoint = -1;
+
+    getField(key: string) {
+        return this.selectedInk?.reduce((p, i) =>
+            (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt<string>);
+    }
+
+    @computed get selectedInk() {
+        const inks = SelectionManager.SelectedDocuments().filter(i => Document(i.rootDoc).type === DocumentType.INK);
+        return inks.length ? inks : undefined;
+    }
+    @computed get unFilled() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.fillColor ? true : false, true) || false; }
+    @computed get unStrokd() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.color ? true : false, true) || false; }
+    @computed get solidFil() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.fillColor ? true : false, true) || false; }
+    @computed get solidStk() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.color && (!i.rootDoc.strokeDash || i.rootDoc.strokeDash === "0") ? true : false, true) || false; }
+    @computed get dashdStk() { return !this.unStrokd && this.getField("strokeDash") || ""; }
+    @computed get colorFil() { const ccol = this.getField("fillColor") || ""; ccol && (this._lastFill = ccol); return ccol; }
+    @computed get colorStk() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; }
+    @computed get widthStk() { return this.getField("strokeWidth") || "1"; }
+    @computed get markHead() { return this.getField("strokeStartMarker") || ""; }
+    @computed get markTail() { return this.getField("strokeEndMarker") || ""; }
+    @computed get shapeHgt() { return this.getField("_height"); }
+    @computed get shapeWid() { return this.getField("_width"); }
+    @computed get shapeXps() { return this.getField("x"); }
+    @computed get shapeYps() { return this.getField("y"); }
+    @computed get shapeRot() { return this.getField("rotation"); }
+    set unFilled(value) { this.colorFil = value ? "" : this._lastFill; }
+    set solidFil(value) { this.unFilled = !value; }
+    set colorFil(value) { value && (this._lastFill = value); this.selectedInk?.forEach(i => i.rootDoc.fillColor = value ? value : undefined); }
+    set colorStk(value) { value && (this._lastLine = value); this.selectedInk?.forEach(i => i.rootDoc.color = value ? value : undefined); }
+    set markHead(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeStartMarker = value); }
+    set markTail(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeEndMarker = value); }
+    set unStrokd(value) { this.colorStk = value ? "" : this._lastLine; }
+    set solidStk(value) { this.dashdStk = ""; this.unStrokd = !value; }
+    set dashdStk(value) {
+        value && (this._lastDash = value) && (this.unStrokd = false);
+        this.selectedInk?.forEach(i => i.rootDoc.strokeDash = value ? this._lastDash : undefined);
+    }
+    set shapeXps(value) { this.selectedInk?.forEach(i => i.rootDoc.x = Number(value)); }
+    set shapeYps(value) { this.selectedInk?.forEach(i => i.rootDoc.y = Number(value)); }
+    set shapeRot(value) { this.selectedInk?.forEach(i => i.rootDoc.rotation = Number(value)); }
+    set widthStk(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeWidth = Number(value)); }
+    set shapeWid(value) {
+        this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
+            const oldWidth = NumCast(i.rootDoc._width);
+            i.rootDoc._width = Number(value);
+            this._lock && (i.rootDoc._height = (i.rootDoc._width * NumCast(i.rootDoc._height)) / oldWidth);
+        });
+    }
+    set shapeHgt(value) {
+        this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
+            const oldHeight = NumCast(i.rootDoc._height);
+            i.rootDoc._height = Number(value);
+            this._lock && (i.rootDoc._width = (i.rootDoc._height * NumCast(i.rootDoc._width)) / oldHeight);
+        });
+    }
+
+    constructor(props: Readonly<{}>) {
+        super(props);
+        FormatShapePane.Instance = this;
+        this._canFade = false;
+        runInAction(() => this.Pinned = BoolCast(Doc.UserDoc()["menuFormatShape-pinned"]));
+    }
+
+    @action
+    closePane = () => {
+        this.fadeOut(false);
+        this.Pinned = false;
+    }
+
+    @action
+    upDownButtons = (dirs: string, field: string) => {
+        switch (field) {
+            case "rot": this.rotate((dirs === "up" ? .1 : -.1)); break;
+            // case "rot": this.selectedInk?.forEach(i => i.rootDoc.rotation = NumCast(i.rootDoc.rotation) + (dirs === "up" ? 0.1 : -0.1)); break;
+            case "Xps": this.selectedInk?.forEach(i => i.rootDoc.x = NumCast(i.rootDoc.x) + (dirs === "up" ? 10 : -10)); break;
+            case "Yps": this.selectedInk?.forEach(i => i.rootDoc.y = NumCast(i.rootDoc.y) + (dirs === "up" ? 10 : -10)); break;
+            case "stk": this.selectedInk?.forEach(i => i.rootDoc.strokeWidth = NumCast(i.rootDoc.strokeWidth) + (dirs === "up" ? .1 : -.1)); break;
+            case "wid": this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
+                //redraw points
+                const oldWidth = NumCast(i.rootDoc._width);
+                const oldHeight = NumCast(i.rootDoc._height);
+                const oldX = NumCast(i.rootDoc.x);
+                const oldY = NumCast(i.rootDoc.y);
+                i.rootDoc._width = oldWidth + (dirs === "up" ? 10 : - 10);
+                this._lock && (i.rootDoc._height = (i.rootDoc._width / oldWidth * NumCast(i.rootDoc._height)));
+                const doc = Document(i.rootDoc);
+                if (doc.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    if (ink) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        ink.forEach(i => {
+                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
+                            const newX = ((doc.x || 0) - oldX) + (i.X * (doc._width || 0)) / oldWidth;
+                            const newY = ((doc.y || 0) - oldY) + (i.Y * (doc._height || 0)) / oldHeight;
+                            newPoints.push({ X: newX, Y: newY });
+                        });
+                        Doc.GetProto(doc).data = new InkField(newPoints);
+                    }
+                }
+            });
+                break;
+            case "hgt": this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
+                const oldWidth = NumCast(i.rootDoc._width);
+                const oldHeight = NumCast(i.rootDoc._height);
+                const oldX = NumCast(i.rootDoc.x);
+                const oldY = NumCast(i.rootDoc.y); i.rootDoc._height = oldHeight + (dirs === "up" ? 10 : - 10);
+                this._lock && (i.rootDoc._width = (i.rootDoc._height / oldHeight * NumCast(i.rootDoc._width)));
+                const doc = Document(i.rootDoc);
+                if (doc.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    if (ink) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        ink.forEach(i => {
+                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
+                            const newX = ((doc.x || 0) - oldX) + (i.X * (doc._width || 0)) / oldWidth;
+                            const newY = ((doc.y || 0) - oldY) + (i.Y * (doc._height || 0)) / oldHeight;
+                            newPoints.push({ X: newX, Y: newY });
+                        });
+                        Doc.GetProto(doc).data = new InkField(newPoints);
+                    }
+                }
+            });
+                break;
+        }
+    }
+
+    @undoBatch
+    @action
+    addPoints = (x: number, y: number, pts: { X: number, Y: number }[], index: number, control: { X: number, Y: number }[]) => {
+        this.selectedInk?.forEach(action(inkView => {
+            if (this.selectedInk?.length === 1) {
+                const doc = Document(inkView.rootDoc);
+                if (doc.type === DocumentType.INK) {
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    if (ink) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        var counter = 0;
+                        for (var k = 0; k < index; k++) {
+                            control.forEach(pt => (pts[k].X === pt.X && pts[k].Y === pt.Y) && counter++);
+                        }
+                        //decide where to put the new coordinate
+                        const spNum = Math.floor(counter / 2) * 4 + 2;
+
+                        for (var i = 0; i < spNum; i++) {
+                            ink[i] && newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+                        }
+                        for (var j = 0; j < 4; j++) {
+                            newPoints.push({ X: x, Y: y });
+
+                        }
+                        for (var i = spNum; i < ink.length; i++) {
+                            newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+                        }
+                        this._currPoint = -1;
+                        Doc.GetProto(doc).data = new InkField(newPoints);
+                    }
+                }
+            }
+        }));
+    }
+
+    @undoBatch
+    @action
+    deletePoints = () => {
+        this.selectedInk?.forEach(action(inkView => {
+            if (this.selectedInk?.length === 1 && this._currPoint !== -1) {
+                const doc = Document(inkView.rootDoc);
+                if (doc.type === DocumentType.INK) {
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    if (ink && ink.length > 4) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        const toRemove = Math.floor(((this._currPoint + 2) / 4));
+                        for (var i = 0; i < ink.length; i++) {
+                            if (Math.floor((i + 2) / 4) !== toRemove) {
+                                newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+                            }
+                        }
+                        this._currPoint = -1;
+                        Doc.GetProto(doc).data = new InkField(newPoints);
+                        if (newPoints.length === 4) {
+                            const newerPoints: { X: number, Y: number }[] = [];
+                            newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y });
+                            newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y });
+                            newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y });
+                            newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y });
+                            Doc.GetProto(doc).data = new InkField(newerPoints);
+
+                        }
+                    }
+                }
+            }
+        }));
+    }
+
+    @undoBatch
+    @action
+    rotate = (angle: number) => {
+        const _centerPoints: { X: number, Y: number }[] = [];
+        SelectionManager.SelectedDocuments().forEach(action(inkView => {
+            const doc = Document(inkView.rootDoc);
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                const ink = Cast(doc.data, InkField)?.inkData;
+                if (ink) {
+                    const xs = ink.map(p => p.X);
+                    const ys = ink.map(p => p.Y);
+                    const left = Math.min(...xs);
+                    const top = Math.min(...ys);
+                    const right = Math.max(...xs);
+                    const bottom = Math.max(...ys);
+                    _centerPoints.push({ X: left, Y: top });
+                }
+            }
+        }));
+
+        var index = 0;
+        SelectionManager.SelectedDocuments().forEach(action(inkView => {
+            const doc = Document(inkView.rootDoc);
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                doc.rotation = Number(doc.rotation) + Number(angle);
+                const ink = Cast(doc.data, InkField)?.inkData;
+                if (ink) {
+
+                    const newPoints: { X: number, Y: number }[] = [];
+                    ink.forEach(i => {
+                        const newX = Math.cos(angle) * (i.X - _centerPoints[index].X) - Math.sin(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].X;
+                        const newY = Math.sin(angle) * (i.X - _centerPoints[index].X) + Math.cos(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].Y;
+                        newPoints.push({ X: newX, Y: newY });
+                    });
+                    Doc.GetProto(doc).data = new InkField(newPoints);
+                    const xs = newPoints.map(p => p.X);
+                    const ys = newPoints.map(p => p.Y);
+                    const left = Math.min(...xs);
+                    const top = Math.min(...ys);
+                    const right = Math.max(...xs);
+                    const bottom = Math.max(...ys);
+
+                    doc._height = (bottom - top);
+                    doc._width = (right - left);
+                }
+                index++;
+            }
+        }));
+    }
+
+    @undoBatch
+    @action
+    control = (xDiff: number, yDiff: number, controlNum: number) => {
+        this.selectedInk?.forEach(action(inkView => {
+            if (this.selectedInk?.length === 1) {
+                const doc = Document(inkView.rootDoc);
+                if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    if (ink) {
+
+                        const newPoints: { X: number, Y: number }[] = [];
+                        const order = controlNum % 4;
+                        for (var i = 0; i < ink.length; i++) {
+                            if (controlNum === i ||
+                                (order === 0 && i === controlNum + 1) ||
+                                (order === 0 && controlNum !== 0 && i === controlNum - 2) ||
+                                (order === 0 && controlNum !== 0 && i === controlNum - 1) ||
+                                (order === 3 && i === controlNum - 1) ||
+                                (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 1) ||
+                                (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 2)
+                                || ((ink[0].X === ink[ink.length - 1].X) && (ink[0].Y === ink[ink.length - 1].Y) && (i === 0 || i === ink.length - 1) && (controlNum === 0 || controlNum === ink.length - 1))
+                            ) {
+                                newPoints.push({ X: ink[i].X - (xDiff * inkView.props.ScreenToLocalTransform().Scale), Y: ink[i].Y - (yDiff * inkView.props.ScreenToLocalTransform().Scale) });
+                            }
+                            else {
+                                newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+                            }
+                        }
+                        const oldx = doc.x;
+                        const oldy = doc.y;
+                        const xs = ink.map(p => p.X);
+                        const ys = ink.map(p => p.Y);
+                        const left = Math.min(...xs);
+                        const top = Math.min(...ys);
+                        Doc.GetProto(doc).data = new InkField(newPoints);
+                        const xs2 = newPoints.map(p => p.X);
+                        const ys2 = newPoints.map(p => p.Y);
+                        const left2 = Math.min(...xs2);
+                        const top2 = Math.min(...ys2);
+                        const right2 = Math.max(...xs2);
+                        const bottom2 = Math.max(...ys2);
+                        doc._height = (bottom2 - top2);
+                        doc._width = (right2 - left2);
+                        //if points move out of bounds
+
+                        doc.x = oldx - (left - left2);
+                        doc.y = oldy - (top - top2);
+
+                    }
+                }
+            }
+        }));
+    }
+
+    @undoBatch
+    @action
+    switchStk = (color: ColorState) => {
+        const val = String(color.hex);
+        this.colorStk = val;
+        return true;
+    }
+
+    @undoBatch
+    @action
+    switchFil = (color: ColorState) => {
+        const val = String(color.hex);
+        this.colorFil = val;
+        return true;
+    }
+
+
+    colorPicker(setter: (color: string) => {}, type: string) {
+        return <div className="btn-group-palette" key="colorpicker" style={{ width: 160, margin: 10 }}>
+            <SketchPicker onChange={type === "stk" ? this.switchStk : this.switchFil} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
+                color={type === "stk" ? this.colorStk : this.colorFil} />
+        </div>;
+    }
+    inputBox = (key: string, value: any, setter: (val: string) => {}) => {
+        return <>
+            <input style={{ color: "black", width: 40, position: "absolute", right: 20 }}
+                type="text" defaultValue={value}
+                onChange={undoBatch(action((e) => setter(e.target.value)))}
+                autoFocus />
+            <button className="antiMenu-Buttonup" key="up1" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))}>
+                ˄
+            </button>
+            <br />
+            <button className="antiMenu-Buttonup" key="down1" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} style={{ marginTop: -8 }}>
+                ˅
+            </button>
+        </>;
+    }
+
+    inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => {
+        return <>
+            {title1}
+            <p style={{ marginTop: -20, right: 70, position: "absolute" }}>{title2}</p>
+
+            <input style={{ color: "black", width: 40, position: "absolute", right: 130 }}
+                type="text" defaultValue={value}
+                onChange={e => setter(e.target.value)}
+                autoFocus />
+            <button className="antiMenu-Buttonup" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))} style={{ right: 110 }}>
+                ˄
+        </button>
+            <button className="antiMenu-Buttonup" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} style={{ marginTop: 12, right: 110 }}>
+                ˅
+        </button>
+            {title2 === "" ? "" : <>
+                <input style={{ color: "black", width: 40, position: "absolute", right: 20 }}
+                    type="text" defaultValue={value2}
+                    onChange={e => setter2(e.target.value)}
+                    autoFocus />
+                <button className="antiMenu-Buttonup" key="up3" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key2)))}>
+                    ˄
+      </button>
+                <br />
+                <button className="antiMenu-Buttonup" key="down3" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key2)))} style={{ marginTop: -8 }}>
+                    ˅
+      </button></>}
+        </>;
+    }
+
+
+    colorButton(value: string, setter: () => {}) {
+        return <>
+            <button className="antimodeMenu-button" key="color" onPointerDown={undoBatch(action(e => setter()))} style={{ position: "relative", marginTop: -5 }}>
+                <div className="color-previewII" style={{ backgroundColor: value ?? "121212" }} />
+                {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -23, position: "fixed" }}>☒</p> : ""}
+            </button>
+        </>;
+    }
+
+    controlPointsButton() {
+        return <>
+            <button className="antimodeMenu-button" title="Edit points" key="bezier" onPointerDown={action(() => this._controlBtn = this._controlBtn ? false : true)} style={{ position: "relative", marginTop: 10, backgroundColor: this._controlBtn ? "black" : "" }}>
+                <FontAwesomeIcon icon="bezier-curve" size="lg" />
+            </button>
+            <button className="antimodeMenu-button" title="Lock ratio" key="ratio" onPointerDown={action(() => this._lock = this._lock ? false : true)} style={{ position: "relative", marginTop: 10, backgroundColor: this._lock ? "black" : "" }}>
+                <FontAwesomeIcon icon="lock" size="lg" />
+
+            </button>
+            <button className="antimodeMenu-button" key="rotate" title="Rotate 90˚" onPointerDown={action(() => this.rotate(Math.PI / 2))} style={{ position: "relative", marginTop: 10, fontSize: 15 }}>
+                ⟲
+            </button>
+            <br /> <br />
+        </>;
+    }
+
+    lockRatioButton() {
+        return <>
+            <button className="antimodeMenu-button" key="lock" onPointerDown={action(() => this._lock = this._lock ? false : true)} style={{ position: "absolute", right: 80, backgroundColor: this._lock ? "black" : "" }}>
+                {/* <FontAwesomeIcon icon="bezier-curve" size="lg" /> */}
+                <FontAwesomeIcon icon="lock" size="lg" />
+
+            </button>
+            <br /> <br />
+        </>;
+    }
+
+    rotate90Button() {
+        return <>
+            <button className="antimodeMenu-button" key="rot" onPointerDown={action(() => this.rotate(Math.PI / 2))} style={{ position: "absolute", right: 80, }}>
+                {/* <FontAwesomeIcon icon="bezier-curve" size="lg" /> */}
+                ⟲
+            </button>
+            <br /> <br />
+        </>;
+    }
+    @computed get fillButton() { return this.colorButton(this.colorFil, () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; return true; }); }
+    @computed get lineButton() { return this.colorButton(this.colorStk, () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; return true; }); }
+
+    @computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color, "fil"); }
+    @computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color, "stk"); }
+
+    @computed get stkInput() { return this.inputBox("stk", this.widthStk, (val: string) => this.widthStk = val); }
+    @computed get dashInput() { return this.inputBox("dsh", this.widthStk, (val: string) => this.widthStk = val); }
+
+    @computed get hgtInput() { return this.inputBoxDuo("hgt", this.shapeHgt, (val: string) => this.shapeHgt = val, "H:", "wid", this.shapeWid, (val: string) => this.shapeWid = val, "W:"); }
+    @computed get widInput() { return this.inputBox("wid", this.shapeWid, (val: string) => this.shapeWid = val); }
+    @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; return true; }, "∠:", "rot", this.shapeRot, (val: string) => this.shapeRot = val, ""); }
+
+    @computed get YpsInput() { return this.inputBox("Yps", this.shapeYps, (val: string) => this.shapeYps = val); }
+
+    @computed get controlPoints() { return this.controlPointsButton(); }
+    @computed get lockRatio() { return this.lockRatioButton(); }
+    @computed get rotate90() { return this.rotate90Button(); }
+    @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); }
+
+
+    @computed get propertyGroupItems() {
+        const fillCheck = <div key="fill" style={{ display: (this._subOpen[0] && this.selectedInk && this.selectedInk.length >= 1) ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
+            Fill:
+            {this.fillButton}
+            <div style={{ float: "left", width: 100 }} >
+                Stroke:
+            {this.lineButton}
+            </div>
+
+            {this._fillBtn ? this.fillPicker : ""}
+            {this._lineBtn ? this.linePicker : ""}
+            {this._fillBtn || this._lineBtn ? "" : <br />}
+            {(this.solidStk || this.dashdStk) ? "Width" : ""}
+            {(this.solidStk || this.dashdStk) ? this.stkInput : ""}
+            {(this.solidStk || this.dashdStk) ? <input type="range" defaultValue={Number(this.widthStk)} min={1} max={100} onChange={undoBatch(action((e) => this.widthStk = e.target.value))} /> : (null)}
+            <br />
+            {(this.solidStk || this.dashdStk) ? <>
+                <p style={{ position: "absolute", fontSize: 12 }}>Arrow Head</p>
+                <input key="markHead" className="formatShapePane-inputBtn" type="checkbox" checked={this.markHead !== ""} onChange={undoBatch(action(() => this.markHead = this.markHead ? "" : "arrow"))} style={{ position: "absolute", right: 110, width: 20 }} />
+                <p style={{ position: "absolute", fontSize: 12, right: 30 }}>Arrow End</p>
+                <input key="markTail" className="formatShapePane-inputBtn" type="checkbox" checked={this.markTail !== ""} onChange={undoBatch(action(() => this.markTail = this.markTail ? "" : "arrow"))} style={{ position: "absolute", right: 0, width: 20 }} />
+                <br />
+            </> : ""}
+            Dash:
+            <input key="markHead" className="formatShapePane-inputBtn" type="checkbox" checked={this.dashdStk === "2"} onChange={undoBatch(action(() => this.dashdStk = this.dashdStk === "2" ? "0" : "2"))} style={{ position: "absolute", right: 110, width: 20 }} />
+        </div>;
+
+
+
+        const sizeCheck =
+
+            <div key="sizeCheck" style={{ display: (this._subOpen[1] && this.selectedInk && this.selectedInk.length >= 1) ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
+                {this.controlPoints}
+                {this.hgtInput}
+                {this.XpsInput}
+                {this.rotInput}
+
+            </div>;
+
+
+        const subMenus = this._currMode === "fill-drip" ? [`Appearance`, 'Transform'] : [];
+        const menuItems = this._currMode === "fill-drip" ? [fillCheck, sizeCheck] : [];
+        const indexOffset = 0;
+
+        return <div className="antimodeMenu-sub" key="submenu" style={{ position: "absolute", width: "inherit", top: 60 }}>
+            {subMenus.map((subMenu, i) =>
+                <div key={subMenu} style={{ width: "inherit" }}>
+                    <button className="antimodeMenu-button" onPointerDown={action(() => this._subOpen[i + indexOffset] = !this._subOpen[i + indexOffset])}
+                        style={{ backgroundColor: "121212", position: "relative", width: "inherit" }}>
+                        {this._subOpen[i + indexOffset] ? "▼" : "▶︎"}
+                        {subMenu}
+                    </button>
+                    {menuItems[i]}
+                </div>)}
+        </div>;
+    }
+
+    @computed get closeBtn() {
+        return <button className="antimodeMenu-button" key="close" onPointerDown={action(() => this.closePane())} style={{ position: "absolute", right: 0 }}>
+            X
+        </button>;
+    }
+
+    @computed get propertyGroupBtn() {
+        return <div className="antimodeMenu-button-tab" key="modes">
+            {this._mode.map(mode =>
+                <button className="antimodeMenu-button" key={mode} onPointerDown={action(() => this._currMode = mode)}
+                    style={{ backgroundColor: this._currMode === mode ? "121212" : "", position: "relative", top: 30 }}>
+                    <FontAwesomeIcon icon={mode as IconProp} size="lg" />
+                </button>)}
+        </div>;
+    }
+
+    render() {
+        return this.getElementVert([this.closeBtn,
+        this.propertyGroupItems]);
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 1cbbfd67b..2794a9f4e 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -11,19 +11,19 @@ import { DocServer } from "../DocServer";
 import { DocumentType } from "../documents/DocumentTypes";
 import { DictationManager } from "../util/DictationManager";
 import { DragManager } from "../util/DragManager";
+import { GroupManager } from "../util/GroupManager";
 import { SelectionManager } from "../util/SelectionManager";
 import { SharingManager } from "../util/SharingManager";
 import { undoBatch, UndoManager } from "../util/UndoManager";
 import { CollectionDockingView } from "./collections/CollectionDockingView";
+import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu";
+import { ContextMenu } from "./ContextMenu";
 import { DocumentDecorations } from "./DocumentDecorations";
+import { FormatShapePane } from "./FormatShapePane";
 import { MainView } from "./MainView";
-import { DocumentView } from "./nodes/DocumentView";
 import { DocumentLinksButton } from "./nodes/DocumentLinksButton";
+import { DocumentView } from "./nodes/DocumentView";
 import { PDFMenu } from "./pdf/PDFMenu";
-import { ContextMenu } from "./ContextMenu";
-import { GroupManager } from "../util/GroupManager";
-import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu";
-import { FormatShapePane } from "./collections/collectionFreeForm/FormatShapePane";
 
 const modifiers = ["control", "meta", "shift", "alt"];
 type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise<KeyControlInfo>;
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 18ecc225c..02628527f 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -11,9 +11,9 @@ import { CognitiveServices } from "../cognitive_services/CognitiveServices";
 import { InteractionUtils } from "../util/InteractionUtils";
 import { Scripting } from "../util/Scripting";
 import { UndoManager } from "../util/UndoManager";
-import { FormatShapePane } from "./collections/collectionFreeForm/FormatShapePane";
 import { ContextMenu } from "./ContextMenu";
 import { ViewBoxBaseComponent } from "./DocComponent";
+import { FormatShapePane } from "./FormatShapePane";
 import "./InkingStroke.scss";
 import { FieldView, FieldViewProps } from "./nodes/FieldView";
 import React = require("react");
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 3afda13c2..6a960f4d5 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -10,17 +10,15 @@ import * as ReactDOM from 'react-dom';
 import Measure from 'react-measure';
 import * as rp from 'request-promise';
 import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
-import { Id } from '../../fields/FieldSymbols';
 import { List } from '../../fields/List';
 import { PrefetchProxy } from '../../fields/Proxy';
 import { listSpec } from '../../fields/Schema';
-import { ScriptField } from '../../fields/ScriptField';
-import { BoolCast, Cast, FieldValue, NumCast, StrCast } from '../../fields/Types';
+import { BoolCast, Cast, FieldValue, StrCast } from '../../fields/Types';
 import { TraceMobx } from '../../fields/util';
 import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick, Utils } from '../../Utils';
 import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
 import { DocServer } from '../DocServer';
-import { Docs, DocumentOptions } from '../documents/Documents';
+import { Docs } from '../documents/Documents';
 import { DocumentType } from '../documents/DocumentTypes';
 import { Networking } from '../Network';
 import { CurrentUserUtils } from '../util/CurrentUserUtils';
@@ -38,19 +36,19 @@ import { SnappingManager } from '../util/SnappingManager';
 import { Transform } from '../util/Transform';
 import { TimelineMenu } from './animationtimeline/TimelineMenu';
 import { CollectionDockingView } from './collections/CollectionDockingView';
-import { FormatShapePane } from "./collections/collectionFreeForm/FormatShapePane";
 import { MarqueeOptionsMenu } from './collections/collectionFreeForm/MarqueeOptionsMenu';
-import { PropertiesView } from './collections/collectionFreeForm/PropertiesView';
 import { CollectionLinearView } from './collections/CollectionLinearView';
 import { CollectionMenu } from './collections/CollectionMenu';
-import { CollectionView, CollectionViewType } from './collections/CollectionView';
+import { CollectionViewType } from './collections/CollectionView';
 import { ContextMenu } from './ContextMenu';
 import { DictationOverlay } from './DictationOverlay';
 import { DocumentDecorations } from './DocumentDecorations';
+import { FormatShapePane } from "./FormatShapePane";
 import { GestureOverlay } from './GestureOverlay';
-import { ANTIMODEMENU_HEIGHT, SEARCH_PANEL_HEIGHT } from './globalCssVariables.scss';
+import { SEARCH_PANEL_HEIGHT } from './globalCssVariables.scss';
 import { KeyManager } from './GlobalKeyHandler';
 import { LinkMenu } from './linking/LinkMenu';
+import "./MainView.scss";
 import { AudioBox } from './nodes/AudioBox';
 import { DocumentLinksButton } from './nodes/DocumentLinksButton';
 import { DocumentView } from './nodes/DocumentView';
@@ -63,8 +61,8 @@ import { WebBox } from './nodes/WebBox';
 import { OverlayView } from './OverlayView';
 import { PDFMenu } from './pdf/PDFMenu';
 import { PreviewCursor } from './PreviewCursor';
+import { PropertiesView } from './PropertiesView';
 import { SearchBox } from './search/SearchBox';
-import "./MainView.scss";
 
 @observer
 export class MainView extends React.Component {
@@ -521,7 +519,7 @@ export class MainView extends React.Component {
         }}>
             <PropertiesView
                 width={this.propertiesWidth()}
-                height={this._panelHeight}
+                height={this.getContentsHeight()}
                 renderDepth={1}
                 ScreenToLocalTransform={Transform.Identity}
                 onDown={this.closeProperties}
@@ -567,8 +565,7 @@ export class MainView extends React.Component {
                             <FontAwesomeIcon icon={this.propertiesIcon} color="black" size="sm" /> </div>
                     </div>
                 }
-                {this.propertiesWidth() < 10 ? (null) :
-                    <div style={{ width: this.propertiesWidth(), height: "calc(100% - 35px)" }}> {this.propertiesView} </div>}
+                {this.propertiesWidth() < 10 ? (null) : this.propertiesView}
             </div>
         </>;
     }
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index f79a68b5a..e95b28d6c 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -16,7 +16,6 @@ import { DocumentType } from '../documents/DocumentTypes';
 import { SelectionManager } from '../util/SelectionManager';
 import { undoBatch } from '../util/UndoManager';
 import { CollectionDockingView } from './collections/CollectionDockingView';
-import './collections/ParentDocumentSelector.scss';
 import { GoogleRef } from "./nodes/formattedText/FormattedTextBox";
 import './PropertiesButtons.scss';
 import React = require("react");
diff --git a/src/client/views/PropertiesDocContextSelector.scss b/src/client/views/PropertiesDocContextSelector.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx
new file mode 100644
index 000000000..b382298f3
--- /dev/null
+++ b/src/client/views/PropertiesDocContextSelector.tsx
@@ -0,0 +1,58 @@
+import { IReactionDisposer, observable, reaction, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import * as React from "react";
+import { Doc } from "../../fields/Doc";
+import { Id } from "../../fields/FieldSymbols";
+import { NumCast, StrCast } from "../../fields/Types";
+import { CollectionViewType } from "./collections/CollectionView";
+import { CollectionDockingView } from "./collections/CollectionDockingView";
+import './PropertiesDocContextSelector.scss';
+import { SearchUtil } from "../util/SearchUtil";
+
+type PropertiesDocContextSelectorProps = {
+    Document: Doc,
+    Stack?: any,
+    hideTitle?: boolean,
+    addDocTab(doc: Doc, location: string): void
+};
+
+@observer
+export class PropertiesDocContextSelector extends React.Component<PropertiesDocContextSelectorProps> {
+    @observable private _docs: { col: Doc, target: Doc }[] = [];
+    @observable private _otherDocs: { col: Doc, target: Doc }[] = [];
+    _reaction: IReactionDisposer | undefined;
+
+    componentDidMount() { this._reaction = reaction(() => this.props.Document, () => this.fetchDocuments(), { fireImmediately: true }); }
+    componentWillUnmount() { this._reaction?.(); }
+    async fetchDocuments() {
+        const aliases = await SearchUtil.GetAliasesOfDocument(this.props.Document);
+        const containerProtoSets = await Promise.all(aliases.map(async alias => ((await SearchUtil.Search("", true, { fq: `data_l:"${alias[Id]}"` })).docs)));
+        const containerProtos = containerProtoSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set<Doc>());
+        const containerSets = await Promise.all(Array.from(containerProtos.keys()).map(async container => SearchUtil.GetAliasesOfDocument(container)));
+        const containers = containerSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set<Doc>());
+        const doclayoutSets = await Promise.all(Array.from(containers.keys()).map(async (dp) => SearchUtil.GetAliasesOfDocument(dp)));
+        const doclayouts = Array.from(doclayoutSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set<Doc>()).keys());
+        runInAction(() => {
+            this._docs = doclayouts.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).filter(doc => !Doc.IsSystem(doc)).map(doc => ({ col: doc, target: this.props.Document }));
+            this._otherDocs = [];
+        });
+    }
+
+    getOnClick = (col: Doc, target: Doc) => {
+        col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col;
+        if (col._viewType === CollectionViewType.Freeform) {
+            col._panX = NumCast(target.x) + NumCast(target._width) / 2;
+            col._panY = NumCast(target.y) + NumCast(target._height) / 2;
+        }
+        this.props.addDocTab(col, "inTab");
+    }
+
+    render() {
+        return <div>
+            {this.props.hideTitle ? (null) : <p key="contexts">Contexts:</p>}
+            {this._docs.map(doc => <p key={doc.col[Id] + doc.target[Id]}><a onClick={() => this.getOnClick(doc.col, doc.target)}>{StrCast(doc.col.title)}</a></p>)}
+            {this._otherDocs.length ? <hr key="hr" /> : null}
+            {this._otherDocs.map(doc => <p key={"p" + doc.col[Id] + doc.target[Id]}><a onClick={() => this.getOnClick(doc.col, doc.target)}>{StrCast(doc.col.title)}</a></p>)}
+        </div>;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
new file mode 100644
index 000000000..254afeb0a
--- /dev/null
+++ b/src/client/views/PropertiesView.scss
@@ -0,0 +1,779 @@
+.propertiesView {
+
+    background-color: rgb(205, 205, 205);
+    height: 100%;
+    font-family: "Noto Sans";
+    cursor: auto;
+
+    overflow-x: hidden;
+    overflow-y: scroll;
+
+    .propertiesView-title {
+        background-color: rgb(159, 159, 159);
+        text-align: center;
+        padding-top: 12px;
+        padding-bottom: 12px;
+        display: flex;
+        font-size: 18px;
+        font-weight: bold;
+        justify-content: center;
+
+        .propertiesView-title-icon {
+            width: 20px;
+            height: 20px;
+            padding-left: 38px;
+            margin-top: -5px;
+            align-items: flex-end;
+            margin-left: auto;
+            margin-right: 10px;
+
+            &:hover {
+                color: grey;
+                cursor: pointer;
+            }
+
+        }
+
+    }
+
+    .propertiesView-name {
+        border-bottom: 1px solid black;
+        padding: 8.5px;
+        font-size: 12.5px;
+
+        &:hover {
+            cursor: text;
+        }
+    }
+
+    .propertiesView-settings {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+        font-size: 12.5px;
+        font-weight: bold;
+
+        .propertiesView-settings-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            &:hover {
+                cursor: pointer;
+            }
+
+            .propertiesView-settings-title-icon {
+                float: right;
+                justify-items: right;
+                align-items: flex-end;
+                margin-left: auto;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-settings-content {
+            margin-left: 12px;
+            padding-bottom: 10px;
+            padding-top: 8px;
+        }
+
+    }
+
+    .propertiesView-sharing {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-sharing-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            &:hover {
+                cursor: pointer;
+            }
+
+            .propertiesView-sharing-title-icon {
+                float: right;
+                justify-items: right;
+                align-items: flex-end;
+                margin-left: auto;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-sharing-content {
+            font-size: 10px;
+            padding: 10px;
+            margin-left: 5px;
+
+            .propertiesView-acls-checkbox {
+                float: right;
+                height: 20px;
+                margin-top: -20px;
+                margin-right: -15;
+
+                .propertiesView-acls-checkbox-text {
+                    font-size: 7px;
+                    margin-top: -10px;
+                    margin-left: 6px;
+                }
+            }
+
+            .change-buttons {
+                display: flex;
+
+                button {
+                    width: 5;
+                    height: 5;
+                }
+
+                input {
+                    width: 100%;
+                }
+            }
+        }
+    }
+
+    .propertiesView-appearance {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-appearance-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            &:hover {
+                cursor: pointer;
+            }
+
+            .propertiesView-appearance-title-icon {
+                float: right;
+                justify-items: right;
+                align-items: flex-end;
+                margin-left: auto;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-appearance-content {
+            font-size: 10px;
+            padding: 10px;
+            margin-left: 5px;
+        }
+    }
+
+    .propertiesView-transform {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-transform-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            &:hover {
+                cursor: pointer;
+            }
+
+            .propertiesView-transform-title-icon {
+                float: right;
+                justify-items: right;
+                align-items: flex-end;
+                margin-left: auto;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-transform-content {
+            font-size: 10px;
+            padding: 10px;
+            margin-left: 5px;
+        }
+    }
+
+    .notify-button {
+        padding: 2px;
+        width: 12px;
+        height: 12px;
+        background-color: black;
+        border-radius: 10px;
+        padding-left: 2px;
+        padding-right: 2px;
+        margin-top: 2px;
+        margin-left: 3px;
+
+        .notify-button-icon {
+            width: 6px;
+            height: 6.5px;
+            margin-left: .5px;
+        }
+
+        &:hover {
+            background-color: rgb(158, 158, 158);
+            cursor: pointer;
+        }
+    }
+
+    .expansion-button-icon {
+        width: 11px;
+        height: 11px;
+        color: black;
+        margin-left: 27px;
+
+        &:hover {
+            color: rgb(131, 131, 131);
+            cursor: pointer;
+        }
+    }
+
+    .propertiesView-sharingTable {
+
+        // whatever's commented out - add it back in when adding the buttons
+
+        // border: 1.5px solid black;
+        border: 1px solid black;
+        padding: 5px; // remove when adding buttons
+        border-radius: 6px; // remove when adding buttons
+        margin-right: 10px; // remove when adding buttons
+        // width: 100%;
+        // display: inline-table;
+        background-color: #ececec;
+        max-height: 130px;
+        overflow-y: scroll;
+        width: 92%;
+
+        .propertiesView-sharingTable-item {
+
+            display: flex;
+            // padding: 5px;
+            padding: 3px;
+            align-items: center;
+            border-bottom: 0.5px solid grey;
+
+            &:hover .propertiesView-sharingTable-item-name {
+                overflow-x: unset;
+                white-space: unset;
+                overflow-wrap: break-word;
+            }
+
+            .propertiesView-sharingTable-item-name {
+                font-weight: bold;
+                width: 95px;
+                overflow-x: hidden;
+                display: inline-block;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+            }
+
+            .propertiesView-sharingTable-item-permission {
+                display: flex;
+                align-items: flex-end;
+                margin-left: auto;
+
+                .permissions-select {
+                    border: none;
+                    background-color: inherit;
+                    width: 75px;
+                    //text-align: justify; // for Edge
+                    //text-align-last: end;
+
+                    &:hover {
+                        cursor: pointer;
+                    }
+                }
+            }
+
+            &:last-child {
+                border-bottom: none;
+            }
+        }
+    }
+
+    .propertiesView-fields {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-fields-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            &:hover {
+                cursor: pointer;
+            }
+
+            .propertiesView-fields-title-icon {
+                float: right;
+                justify-items: right;
+                align-items: flex-end;
+                margin-left: auto;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+
+        }
+
+        .propertiesView-fields-checkbox {
+            float: right;
+            height: 20px;
+            margin-top: -9px;
+
+            .propertiesView-fields-checkbox-text {
+                font-size: 7px;
+                margin-top: -10px;
+                margin-left: 6px;
+            }
+        }
+
+        .propertiesView-fields-content {
+            font-size: 10px;
+            margin-left: 2px;
+            padding: 10px;
+
+            &:hover {
+                cursor: pointer;
+            }
+        }
+    }
+
+    .field {
+        display: flex;
+        font-size: 7px;
+        background-color: #e8e8e8;
+        padding-right: 3px;
+        border: 0.5px solid grey;
+        border-radius: 5px;
+        padding-left: 3px;
+    }
+
+    .uneditable-field {
+        display: flex;
+        overflow-y: visible;
+        margin-bottom: 2px;
+
+        &:hover {
+            cursor: auto;
+        }
+    }
+    .propertiesView-contexts {
+
+        .propertiesView-contexts-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            &:hover {
+                cursor: pointer;
+            }
+
+            .propertiesView-contexts-title-icon {
+                float: right;
+                justify-items: right;
+                align-items: flex-end;
+                margin-left: auto;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-contexts-content {
+            overflow: hidden;
+            padding: 10px;
+        }
+
+    }
+
+    .propertiesView-layout {
+
+        .propertiesView-layout-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            &:hover {
+                cursor: pointer;
+            }
+
+            .propertiesView-layout-title-icon {
+                float: right;
+                justify-items: right;
+                align-items: flex-end;
+                margin-left: auto;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-layout-content {
+            overflow: hidden;
+            padding: 10px;
+        }
+
+    }
+
+    .propertiesView-presTrails {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-presTrails-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            &:hover {
+                cursor: pointer;
+            }
+
+            .propertiesView-presTrails-title-icon {
+                float: right;
+                justify-items: right;
+                align-items: flex-end;
+                margin-left: auto;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-presTrails-content {
+            font-size: 10px;
+            padding: 10px;
+            margin-left: 5px;
+        }
+    }
+}
+
+.inking-button {
+
+    display: flex;
+
+    .inking-button-points {
+        background-color: #333333;
+        padding: 7px;
+        border-radius: 7px;
+        margin-right: 32px;
+        width: 32;
+        height: 32;
+        padding-top: 9px;
+        margin-left: 18px;
+
+        &:hover {
+            background: rgb(131, 131, 131);
+            transform: scale(1.05);
+            cursor: pointer;
+        }
+    }
+
+    .inking-button-lock {
+        background-color: #333333;
+        padding: 7px;
+        border-radius: 7px;
+        margin-right: 32px;
+        width: 32;
+        height: 32;
+        padding-top: 9px;
+        padding-left: 10px;
+
+        &:hover {
+            background: rgb(131, 131, 131);
+            transform: scale(1.05);
+            cursor: pointer;
+        }
+    }
+
+    .inking-button-rotate {
+        background-color: #333333;
+        padding: 7px;
+        border-radius: 7px;
+        width: 32;
+        height: 32;
+        padding-top: 9px;
+        padding-left: 10px;
+
+        &:hover {
+            background: rgb(131, 131, 131);
+            transform: scale(1.05);
+            cursor: pointer;
+        }
+    }
+}
+
+.inputBox-duo {
+    display: flex;
+}
+
+.inputBox {
+
+    margin-top: 10px;
+    display: flex;
+    height: 19px;
+    margin-right: 15px;
+
+    .inputBox-title {
+        font-size: 12px;
+        padding-right: 5px;
+    }
+
+    .inputBox-input {
+        font-size: 10px;
+        width: 50px;
+        margin-right: 1px;
+        border-radius: 3px;
+
+        &:hover {
+            cursor: pointer;
+        }
+    }
+
+    .inputBox-button {
+
+        .inputBox-button-up {
+            background-color: #333333;
+            height: 9px;
+            padding-left: 3px;
+            padding-right: 3px;
+            padding-top: 1px;
+            padding-bottom: 1px;
+            border-radius: 1.5px;
+
+            &:hover {
+                background: rgb(131, 131, 131);
+                transform: scale(1.05);
+                cursor: pointer;
+            }
+        }
+
+        .inputBox-button-down {
+            background-color: #333333;
+            height: 9px;
+            padding-left: 3px;
+            padding-right: 3px;
+            padding-top: 1px;
+            padding-bottom: 1px;
+            border-radius: 1.5px;
+
+            &:hover {
+                background: rgb(131, 131, 131);
+                transform: scale(1.05);
+                cursor: pointer;
+            }
+        }
+
+    }
+}
+
+.color-palette {
+    width: 160px;
+    height: 360;
+}
+
+.strokeAndFill {
+    display: flex;
+    margin-top: 10px;
+
+    .fill {
+        margin-right: 40px;
+        display: flex;
+        padding-bottom: 7px;
+        margin-left: 35px;
+
+        .fill-title {
+            font-size: 12px;
+            margin-right: 2px;
+        }
+
+        .fill-button {
+            padding-top: 2px;
+            margin-top: -1px;
+        }
+    }
+
+    .stroke {
+        display: flex;
+
+        .stroke-title {
+            font-size: 12px;
+        }
+
+        .stroke-button {
+            padding-top: 2px;
+            margin-left: 2px;
+            margin-top: -1px;
+        }
+    }
+}
+
+.propertiesView-presSelected {
+    border-top: solid 1px darkgrey;
+    width: 100%;
+    padding-top: 5px;
+    font-family: Roboto;
+    font-weight: 500;
+    display: inline-flex;
+
+    .propertiesView-selectedList {
+        border-left: solid 1px darkgrey;
+        margin-left: 10px;
+        padding-left: 5px;
+
+        .selectedList-items {
+            font-size: 12;
+            font-weight: 300;
+            margin-top: 1;
+        }
+    }
+}
+
+.widthAndDash {
+
+    .width {
+        .width-top {
+            display: flex;
+
+            .width-title {
+                font-size: 12;
+                margin-right: 20px;
+                margin-left: 35px;
+                text-align: center;
+            }
+
+            .width-input {
+                margin-right: 30px;
+                margin-top: -10px;
+            }
+        }
+
+        .width-range {
+            margin-right: 1px;
+            margin-bottom: 6;
+        }
+    }
+
+    .arrows {
+
+        display: flex;
+        margin-bottom: 3px;
+        margin-left: 4px;
+
+        .arrows-head {
+
+            display: flex;
+            margin-right: 35px;
+
+            .arrows-head-title {
+                font-size: 10;
+            }
+
+            .arrows-head-input {
+                margin-left: 6px;
+                margin-top: 2px;
+            }
+        }
+
+        .arrows-tail {
+            display: flex;
+
+            .arrows-tail-title {
+                font-size: 10;
+            }
+
+            .arrows-tail-input {
+                margin-left: 6px;
+                margin-top: 2px;
+            }
+        }
+    }
+
+    .dashed {
+
+        display: flex;
+        margin-left: 64px;
+        margin-bottom: 6px;
+
+        .dashed-title {
+            font-size: 10;
+        }
+
+        .dashed-input {
+            margin-left: 6px;
+            margin-top: 2px;
+        }
+    }
+}
+
+.editable-title {
+    border: none;
+    padding: 6px;
+    padding-bottom: 2px;
+    background: #eeeeee;
+    border-top: 1px solid;
+    border-left: 1px solid;
+
+    &:hover {
+        border: 0.75px solid rgb(122, 28, 28);
+    }
+}
+
+
+.properties-flyout {
+    grid-column: 2/4;
+}
\ No newline at end of file
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
new file mode 100644
index 000000000..fef0a3e00
--- /dev/null
+++ b/src/client/views/PropertiesView.tsx
@@ -0,0 +1,1089 @@
+import React = require("react");
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Checkbox, Tooltip } from "@material-ui/core";
+import { action, computed, observable } from "mobx";
+import { observer } from "mobx-react";
+import { ColorState, SketchPicker } from "react-color";
+import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, DataSym, Doc, Field, HeightSym, WidthSym } from "../../fields/Doc";
+import { Id } from "../../fields/FieldSymbols";
+import { InkField } from "../../fields/InkField";
+import { ComputedField } from "../../fields/ScriptField";
+import { Cast, NumCast, StrCast } from "../../fields/Types";
+import { GetEffectiveAcl, SharingPermissions } from "../../fields/util";
+import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnZero } from "../../Utils";
+import { DocumentType } from "../documents/DocumentTypes";
+import { DocumentManager } from "../util/DocumentManager";
+import { SelectionManager } from "../util/SelectionManager";
+import { SharingManager } from "../util/SharingManager";
+import { Transform } from "../util/Transform";
+import { undoBatch, UndoManager } from "../util/UndoManager";
+import { CollectionDockingView } from "./collections/CollectionDockingView";
+import { EditableView } from "./EditableView";
+import { FormatShapePane } from "./FormatShapePane";
+import { ContentFittingDocumentView } from "./nodes/ContentFittingDocumentView";
+import { KeyValueBox } from "./nodes/KeyValueBox";
+import { PresBox } from "./nodes/PresBox";
+import { PropertiesButtons } from "./PropertiesButtons";
+import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector";
+import "./PropertiesView.scss";
+const higflyout = require("@hig/flyout");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
+const _global = (window /* browser */ || global /* node */) as any;
+
+interface PropertiesViewProps {
+    width: number;
+    height: number;
+    renderDepth: number;
+    ScreenToLocalTransform: () => Transform;
+    onDown: (event: any) => void;
+}
+
+@observer
+export class PropertiesView extends React.Component<PropertiesViewProps> {
+    private _widthUndo?: UndoManager.Batch;
+
+    @computed get MAX_EMBED_HEIGHT() { return 200; }
+
+    @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; }
+    @computed get selectedDocumentView() {
+        if (SelectionManager.SelectedDocuments().length) {
+            return SelectionManager.SelectedDocuments()[0];
+        } else if (PresBox.Instance && PresBox.Instance._selectedArray.length) {
+            return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
+        } else { return undefined; }
+    }
+    @computed get isPres(): boolean {
+        if (this.selectedDoc?.type === DocumentType.PRES) return true;
+        return false;
+    }
+    @computed get dataDoc() { return this.selectedDoc?.[DataSym]; }
+
+    @observable layoutFields: boolean = false;
+
+    @observable openOptions: boolean = true;
+    @observable openSharing: boolean = true;
+    @observable openFields: boolean = true;
+    @observable openLayout: boolean = true;
+    @observable openContexts: boolean = true;
+    @observable openAppearance: boolean = true;
+    @observable openTransform: boolean = true;
+    // @observable selectedUser: string = "";
+    // @observable addButtonPressed: boolean = false;
+    @observable layoutDocAcls: boolean = false;
+
+    //Pres Trails booleans:
+    @observable openPresTransitions: boolean = false;
+    @observable openPresProgressivize: boolean = false;
+    @observable openAddSlide: boolean = false;
+    @observable openSlideOptions: boolean = false;
+
+    @observable inOptions: boolean = false;
+    @observable _controlBtn: boolean = false;
+    @observable _lock: boolean = false;
+
+    @computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; }
+
+    @action
+    rtfWidth = () => {
+        if (this.selectedDoc) {
+            return Math.min(this.selectedDoc?.[WidthSym](), this.props.width - 20);
+        } else {
+            return 0;
+        }
+    }
+    @action
+    rtfHeight = () => {
+        if (this.selectedDoc) {
+            return this.rtfWidth() <= this.selectedDoc?.[WidthSym]() ? Math.min(this.selectedDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
+        } else {
+            return 0;
+        }
+    }
+
+    @action
+    docWidth = () => {
+        if (this.selectedDoc) {
+            const layoutDoc = this.selectedDoc;
+            const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+            if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.width - 20));
+            return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20;
+        } else {
+            return 0;
+        }
+    }
+
+    @action
+    docHeight = () => {
+        if (this.selectedDoc && this.dataDoc) {
+            const layoutDoc = this.selectedDoc;
+            return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => {
+                const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+                if (aspect) return this.docWidth() * aspect;
+                return layoutDoc._fitWidth ? (!this.dataDoc._nativeHeight ? NumCast(this.props.height) :
+                    Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
+                        NumCast(this.props.height)))) :
+                    NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
+            })()));
+        } else {
+            return 0;
+        }
+    }
+
+    @computed get expandedField() {
+        if (this.dataDoc && this.selectedDoc) {
+            const ids: { [key: string]: string } = {};
+            const docs = SelectionManager.SelectedDocuments().length < 2 ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] :
+                SelectionManager.SelectedDocuments().map(dv => this.layoutFields ? Doc.Layout(dv.layoutDoc) : dv.dataDoc);
+            docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)));
+            const rows: JSX.Element[] = [];
+            for (const key of Object.keys(ids).slice().sort()) {
+                const docvals = new Set<any>();
+                docs.forEach(doc => docvals.add(doc[key]));
+                const contents = Array.from(docvals.keys()).length > 1 ? "-multiple" : docs[0][key];
+                if (key[0] === "#") {
+                    rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "2px" }} key={key}>
+                        <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key}</span>
+                    &nbsp;
+                </div>);
+                } else {
+                    const contentElement = <EditableView key="editableView"
+                        contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
+                        height={13}
+                        fontSize={10}
+                        GetValue={() => contents !== undefined ? Field.toString(contents as Field) : "null"}
+                        SetValue={(value: string) => { docs.map(doc => KeyValueBox.SetField(doc, key, value, true)); return true; }}
+                    />;
+                    rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
+                        <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
+                        &nbsp;
+                        {contentElement}
+                    </div>);
+                }
+            }
+            rows.push(<div className="field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
+                <EditableView
+                    key="editableView"
+                    contents={"add key:value or #tags"}
+                    height={13}
+                    fontSize={10}
+                    GetValue={() => ""}
+                    SetValue={this.setKeyValue} />
+            </div>);
+            return rows;
+        }
+    }
+
+    @computed get noviceFields() {
+        if (this.dataDoc) {
+            const ids: { [key: string]: string } = {};
+            const docs = SelectionManager.SelectedDocuments().length < 2 ? [this.dataDoc] : SelectionManager.SelectedDocuments().map(dv => dv.dataDoc);
+            docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)));
+            const rows: JSX.Element[] = [];
+            const noviceReqFields = ["author", "creationDate"];
+            const noviceLayoutFields = ["_curPage"];
+            const noviceKeys = [...Array.from(Object.keys(ids)).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("ACL") && key !== "UseCors")),
+            ...noviceReqFields, ...noviceLayoutFields];
+            for (const key of noviceKeys.sort()) {
+                const docvals = new Set<any>();
+                docs.forEach(doc => docvals.add(doc[key]));
+                const contents = Array.from(docvals.keys()).length > 1 ? "-multiple" : docs[0][key];
+                if (key[0] === "#") {
+                    rows.push(<div className="uneditable-field" key={key}>
+                        <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key}</span>
+                        &nbsp;
+                    </div>);
+                } else if (contents !== undefined) {
+                    const value = Field.toString(contents as Field);
+                    if (noviceReqFields.includes(key) || key.indexOf("lastModified") !== -1) {
+                        rows.push(<div className="uneditable-field" key={key}>
+                            <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ": "}</span>
+                            <div style={{ whiteSpace: "nowrap", overflowX: "hidden" }}>{value}</div>
+                        </div>);
+                    } else {
+                        const contentElement = <EditableView key="editableView"
+                            contents={value}
+                            height={13}
+                            fontSize={10}
+                            GetValue={() => contents !== undefined ? Field.toString(contents as Field) : "null"}
+                            SetValue={(value: string) => { docs.map(doc => KeyValueBox.SetField(doc, key, value, true)); return true; }}
+                        />;
+
+                        rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
+                            <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
+                        &nbsp;
+                        {contentElement}
+                        </div>);
+                    }
+                }
+            }
+            rows.push(<div className="field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
+                <EditableView
+                    key="editableView"
+                    contents={"add key:value or #tags"}
+                    height={13}
+                    fontSize={10}
+                    GetValue={() => ""}
+                    SetValue={this.setKeyValue} />
+            </div>);
+            return rows;
+        }
+    }
+
+    @undoBatch
+    setKeyValue = (value: string) => {
+        const docs = SelectionManager.SelectedDocuments().length < 2 && this.selectedDoc ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : SelectionManager.SelectedDocuments().map(dv => this.layoutFields ? dv.layoutDoc : dv.dataDoc);
+        docs.forEach(doc => {
+            if (value.indexOf(":") !== -1) {
+                const newVal = value[0].toUpperCase() + value.substring(1, value.length);
+                KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
+                return true;
+            } else if (value[0] === "#") {
+                const newVal = value + `:'${value}'`;
+                KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
+                return true;
+            }
+        });
+        return false;
+    }
+
+    @observable transform: Transform = Transform.Identity();
+    getTransform = () => this.transform;
+    propertiesDocViewRef = (ref: HTMLDivElement) => {
+        const observer = new _global.ResizeObserver(action((entries: any) => {
+            const cliRect = ref.getBoundingClientRect();
+            this.transform = new Transform(-cliRect.x, -cliRect.y, 1);
+        }));
+        ref && observer.observe(ref);
+    }
+
+    @computed get contexts() {
+        return !this.selectedDoc ? (null) : <PropertiesDocContextSelector Document={this.selectedDoc} hideTitle={true} addDocTab={(doc, where) => CollectionDockingView.AddRightSplit(doc)} />;
+    }
+
+    previewBackground = () => "lightgrey";
+    @computed get layoutPreview() {
+        if (SelectionManager.SelectedDocuments().length > 1) {
+            return "-- multiple selected --";
+        }
+        if (this.selectedDoc) {
+            const layoutDoc = Doc.Layout(this.selectedDoc);
+            const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight;
+            const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth;
+            return <div ref={this.propertiesDocViewRef} style={{ pointerEvents: "none", display: "inline-block", height: panelHeight() }} key={this.selectedDoc[Id]}>
+                <ContentFittingDocumentView
+                    Document={layoutDoc}
+                    DataDoc={this.dataDoc}
+                    LibraryPath={emptyPath}
+                    renderDepth={this.props.renderDepth + 1}
+                    rootSelected={returnFalse}
+                    treeViewDoc={undefined}
+                    backgroundColor={this.previewBackground}
+                    fitToBox={true}
+                    FreezeDimensions={true}
+                    NativeWidth={layoutDoc.type ===
+                        StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero}
+                    NativeHeight={layoutDoc.type ===
+                        StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : returnZero}
+                    PanelWidth={panelWidth}
+                    PanelHeight={panelHeight}
+                    focus={returnFalse}
+                    ScreenToLocalTransform={this.getTransform}
+                    docFilters={returnEmptyFilter}
+                    searchFilterDocs={returnEmptyDoclist}
+                    ContainingCollectionDoc={undefined}
+                    ContainingCollectionView={undefined}
+                    addDocument={returnFalse}
+                    moveDocument={undefined}
+                    removeDocument={returnFalse}
+                    parentActive={() => false}
+                    whenActiveChanged={emptyFunction}
+                    addDocTab={returnFalse}
+                    pinToPres={emptyFunction}
+                    bringToFront={returnFalse}
+                    ContentScaling={returnOne}
+                    dontRegisterView={true}
+                    dropAction={undefined}
+                />
+            </div>;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Handles the changing of a user's permissions from the permissions panel.
+     */
+    @undoBatch
+    changePermissions = (e: any, user: string) => {
+        SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, this.selectedDoc!);
+    }
+
+    /**
+     * @returns the options for the permissions dropdown.
+     */
+    getPermissionsSelect(user: string, permission: string) {
+        return <select className="permissions-select"
+            value={permission}
+            onChange={e => this.changePermissions(e, user)}>
+            {Object.values(SharingPermissions).map(permission => {
+                return (
+                    <option key={permission} value={permission}>
+                        {permission}
+                    </option>);
+            })}
+        </select>;
+    }
+
+    /**
+     * @returns the notification icon. On clicking, it should notify someone of a document been shared with them.
+     */
+    @computed get notifyIcon() {
+        return <Tooltip title={<div className="dash-tooltip">Notify with message</div>}>
+            <div className="notify-button">
+                <FontAwesomeIcon className="notify-button-icon" icon="bell" color="white" size="sm" />
+            </div>
+        </Tooltip>;
+    }
+
+    /**
+     * ... next to the owner that opens the main SharingManager interface on click.
+     */
+    @computed get expansionIcon() {
+        return <Tooltip title={<div className="dash-tooltip">{"Show more permissions"}</div>}>
+            <div className="expansion-button" onPointerDown={() => {
+                if (this.selectedDocumentView || this.selectedDoc) {
+                    SharingManager.Instance.open(this.selectedDocumentView?.props.Document === this.selectedDocumentView ? this.selectedDocumentView : undefined, this.selectedDoc);
+                }
+            }}>
+                <FontAwesomeIcon className="expansion-button-icon" icon="ellipsis-h" color="black" size="sm" />
+            </div>
+        </Tooltip>;
+    }
+
+    /**
+     * @returns a row of the permissions panel
+     */
+    sharingItem(name: string, effectiveAcl: symbol, permission: string) {
+        return <div className="propertiesView-sharingTable-item" key={name + permission}
+        // style={{ backgroundColor: this.selectedUser === name ? "#bcecfc" : "" }}
+        // onPointerDown={action(() => this.selectedUser = this.selectedUser === name ? "" : name)}
+        >
+            <div className="propertiesView-sharingTable-item-name" style={{ width: name !== "Me" ? "85px" : "80px" }}> {name} </div>
+            {/* {name !== "Me" ? this.notifyIcon : null} */}
+            <div className="propertiesView-sharingTable-item-permission">
+                {effectiveAcl === AclAdmin && permission !== "Owner" ? this.getPermissionsSelect(name, permission) : permission}
+                {permission === "Owner" ? this.expansionIcon : null}
+            </div>
+        </div>;
+    }
+
+    /**
+     * @returns the sharing and permissiosn panel.
+     */
+    @computed get sharingTable() {
+        const AclMap = new Map<symbol, string>([
+            [AclPrivate, SharingPermissions.None],
+            [AclReadonly, SharingPermissions.View],
+            [AclAddonly, SharingPermissions.Add],
+            [AclEdit, SharingPermissions.Edit],
+            [AclAdmin, SharingPermissions.Admin]
+        ]);
+
+        const target = this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym];
+
+        const effectiveAcl = GetEffectiveAcl(target);
+        const tableEntries = [];
+
+        // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
+        if (target[AclSym]) {
+            for (const [key, value] of Object.entries(target[AclSym])) {
+                const name = key.substring(4).replace("_", ".");
+                if (name !== Doc.CurrentUserEmail && name !== target.author && name !== "Public"/* && sidebarUsersDisplayed![name] !== false*/) {
+                    tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value as symbol)!));
+                }
+            }
+        }
+
+        //     if (Doc.UserDoc().sidebarUsersDisplayed) {
+        //         for (const [name, value] of Object.entries(sidebarUsersDisplayed!)) {
+        //             if (value === true && !this.selectedDoc![`ACL-${name.substring(8).replace(".", "_")}`]) tableEntries.push(this.sharingItem(name.substring(8), effectiveAcl, SharingPermissions.None));
+        //         }
+        //     }
+        // })
+
+        // shifts the current user, owner, public to the top of the doc.
+        tableEntries.unshift(this.sharingItem("Public", effectiveAcl, (AclMap.get(target[AclSym]?.["ACL-Public"]) || SharingPermissions.None)));
+        tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === target.author ? "Owner" : AclMap.get(effectiveAcl)!));
+        if (Doc.CurrentUserEmail !== target.author) tableEntries.unshift(this.sharingItem(StrCast(target.author), effectiveAcl, "Owner"));
+
+        return <div className="propertiesView-sharingTable">
+            {tableEntries}
+        </div>;
+    }
+
+    @computed get fieldsCheckbox() {
+        return <Checkbox
+            color="primary"
+            onChange={this.toggleCheckbox}
+            checked={this.layoutFields}
+        />;
+    }
+
+    @action
+    toggleCheckbox = () => {
+        this.layoutFields = !this.layoutFields;
+    }
+
+    @computed get editableTitle() {
+        const titles = new Set<string>();
+        SelectionManager.SelectedDocuments().forEach(dv => titles.add(StrCast(dv.rootDoc.title)));
+        const title = Array.from(titles.keys()).length > 1 ? "--multiple selected--" : StrCast(this.selectedDoc?.title);
+        return <div className="editable-title"><EditableView
+            key="editableView"
+            contents={title}
+            height={25}
+            fontSize={14}
+            GetValue={() => title}
+            SetValue={this.setTitle} /> </div>;
+    }
+
+    @undoBatch
+    @action
+    setTitle = (value: string) => {
+        if (SelectionManager.SelectedDocuments().length > 1) {
+            SelectionManager.SelectedDocuments().map(dv => Doc.SetInPlace(dv.rootDoc, "title", value, true));
+            return true;
+        } else if (this.dataDoc) {
+            if (this.selectedDoc) Doc.SetInPlace(this.selectedDoc, "title", value, true);
+            else KeyValueBox.SetField(this.dataDoc, "title", value, true);
+            return true;
+        }
+        return false;
+    }
+
+
+    @undoBatch
+    @action
+    rotate = (angle: number) => {
+        const _centerPoints: { X: number, Y: number }[] = [];
+        if (this.selectedDoc) {
+            const doc = this.selectedDoc;
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                const ink = Cast(doc.data, InkField)?.inkData;
+                if (ink) {
+                    const xs = ink.map(p => p.X);
+                    const ys = ink.map(p => p.Y);
+                    const left = Math.min(...xs);
+                    const top = Math.min(...ys);
+                    const right = Math.max(...xs);
+                    const bottom = Math.max(...ys);
+                    _centerPoints.push({ X: left, Y: top });
+                }
+            }
+
+            var index = 0;
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                doc.rotation = Number(doc.rotation) + Number(angle);
+                const inks = Cast(doc.data, InkField)?.inkData;
+                if (inks) {
+                    const newPoints: { X: number, Y: number }[] = [];
+                    inks.forEach(ink => {
+                        const newX = Math.cos(angle) * (ink.X - _centerPoints[index].X) - Math.sin(angle) * (ink.Y - _centerPoints[index].Y) + _centerPoints[index].X;
+                        const newY = Math.sin(angle) * (ink.X - _centerPoints[index].X) + Math.cos(angle) * (ink.Y - _centerPoints[index].Y) + _centerPoints[index].Y;
+                        newPoints.push({ X: newX, Y: newY });
+                    });
+                    doc.data = new InkField(newPoints);
+                    const xs = newPoints.map(p => p.X);
+                    const ys = newPoints.map(p => p.Y);
+                    const left = Math.min(...xs);
+                    const top = Math.min(...ys);
+                    const right = Math.max(...xs);
+                    const bottom = Math.max(...ys);
+
+                    doc._height = (bottom - top);
+                    doc._width = (right - left);
+                }
+                index++;
+            }
+        }
+    }
+
+
+
+    @computed
+    get controlPointsButton() {
+        return <div className="inking-button">
+            <Tooltip title={<div className="dash-tooltip">{"Edit points"}</div>}>
+                <div className="inking-button-points" onPointerDown={action(() => FormatShapePane.Instance._controlBtn = !FormatShapePane.Instance._controlBtn)} style={{ backgroundColor: FormatShapePane.Instance._controlBtn ? "black" : "" }}>
+                    <FontAwesomeIcon icon="bezier-curve" color="white" size="lg" />
+                </div>
+            </Tooltip>
+            <Tooltip title={<div className="dash-tooltip">{FormatShapePane.Instance._lock ? "Unlock ratio" : "Lock ratio"}</div>}>
+                <div className="inking-button-lock" onPointerDown={action(() => FormatShapePane.Instance._lock = !FormatShapePane.Instance._lock)} >
+                    <FontAwesomeIcon icon={FormatShapePane.Instance._lock ? "lock" : "unlock"} color="white" size="lg" />
+                </div>
+            </Tooltip>
+            <Tooltip title={<div className="dash-tooltip">{"Rotate 90˚"}</div>}>
+                <div className="inking-button-rotate" onPointerDown={action(() => this.rotate(Math.PI / 2))}>
+                    <FontAwesomeIcon icon="undo" color="white" size="lg" />
+                </div>
+            </Tooltip>
+        </div>;
+    }
+
+    inputBox = (key: string, value: any, setter: (val: string) => {}, title: string) => {
+        return <div className="inputBox"
+            style={{
+                marginRight: title === "X:" ? "19px" : "",
+                marginLeft: title === "∠:" ? "39px" : ""
+            }}>
+            <div className="inputBox-title"> {title} </div>
+            <input className="inputBox-input"
+                type="text" value={value}
+                onChange={e => {
+                    setter(e.target.value);
+                }}
+                onKeyPress={e => {
+                    e.stopPropagation();
+                }} />
+            <div className="inputBox-button">
+                <div className="inputBox-button-up" key="up2"
+                    onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))} >
+                    <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
+                </div>
+                <div className="inputbox-Button-down" key="down2"
+                    onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} >
+                    <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
+                </div>
+            </div>
+        </div>;
+    }
+
+    inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => {
+        return <div className="inputBox-duo">
+            {this.inputBox(key, value, setter, title1)}
+            {title2 === "" ? (null) : this.inputBox(key2, value2, setter2, title2)}
+        </div>;
+    }
+
+    @action
+    upDownButtons = (dirs: string, field: string) => {
+        switch (field) {
+            case "rot": this.rotate((dirs === "up" ? .1 : -.1)); break;
+            // case "rot": this.selectedInk?.forEach(i => i.rootDoc.rotation = NumCast(i.rootDoc.rotation) + (dirs === "up" ? 0.1 : -0.1)); break;
+            case "Xps": this.selectedDoc && (this.selectedDoc.x = NumCast(this.selectedDoc?.x) + (dirs === "up" ? 10 : -10)); break;
+            case "Yps": this.selectedDoc && (this.selectedDoc.y = NumCast(this.selectedDoc?.y) + (dirs === "up" ? 10 : -10)); break;
+            case "stk": this.selectedDoc && (this.selectedDoc.strokeWidth = NumCast(this.selectedDoc?.strokeWidth) + (dirs === "up" ? .1 : -.1)); break;
+            case "wid":
+                const oldWidth = NumCast(this.selectedDoc?._width);
+                const oldHeight = NumCast(this.selectedDoc?._height);
+                const oldX = NumCast(this.selectedDoc?.x);
+                const oldY = NumCast(this.selectedDoc?.y);
+                this.selectedDoc && (this.selectedDoc._width = oldWidth + (dirs === "up" ? 10 : - 10));
+                FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) / oldWidth * NumCast(this.selectedDoc?._height)));
+                const doc = this.selectedDoc;
+                if (doc?.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    if (ink) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        for (var j = 0; j < ink.length; j++) {
+                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
+                            const newX = (NumCast(doc.x) - oldX) + (ink[j].X * NumCast(doc._width)) / oldWidth;
+                            const newY = (NumCast(doc.y) - oldY) + (ink[j].Y * NumCast(doc._height)) / oldHeight;
+                            newPoints.push({ X: newX, Y: newY });
+                        }
+                        doc.data = new InkField(newPoints);
+                    }
+                }
+                break;
+            case "hgt":
+                const oWidth = NumCast(this.selectedDoc?._width);
+                const oHeight = NumCast(this.selectedDoc?._height);
+                const oX = NumCast(this.selectedDoc?.x);
+                const oY = NumCast(this.selectedDoc?.y);
+                this.selectedDoc && (this.selectedDoc._height = oHeight + (dirs === "up" ? 10 : - 10));
+                FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) / oHeight * NumCast(this.selectedDoc?._width)));
+                const docu = this.selectedDoc;
+                if (docu?.type === DocumentType.INK && docu.x && docu.y && docu._height && docu._width) {
+                    const ink = Cast(docu.data, InkField)?.inkData;
+                    if (ink) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        for (var j = 0; j < ink.length; j++) {
+                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
+                            const newX = (NumCast(docu.x) - oX) + (ink[j].X * NumCast(docu._width)) / oWidth;
+                            const newY = (NumCast(docu.y) - oY) + (ink[j].Y * NumCast(docu._height)) / oHeight;
+                            newPoints.push({ X: newX, Y: newY });
+                        }
+                        docu.data = new InkField(newPoints);
+                    }
+                }
+                break;
+        }
+    }
+
+    getField(key: string) {
+        //if (this.selectedDoc) {
+        return Field.toString(this.selectedDoc?.[key] as Field);
+        // } else {
+        //     return undefined as Opt<string>;
+        // }
+    }
+
+    @computed get shapeXps() { return this.getField("x"); }
+    @computed get shapeYps() { return this.getField("y"); }
+    @computed get shapeRot() { return this.getField("rotation"); }
+    @computed get shapeHgt() { return this.getField("_height"); }
+    @computed get shapeWid() { return this.getField("_width"); }
+    set shapeXps(value) { this.selectedDoc && (this.selectedDoc.x = Number(value)); }
+    set shapeYps(value) { this.selectedDoc && (this.selectedDoc.y = Number(value)); }
+    set shapeRot(value) { this.selectedDoc && (this.selectedDoc.rotation = Number(value)); }
+    set shapeWid(value) {
+        const oldWidth = NumCast(this.selectedDoc?._width);
+        this.selectedDoc && (this.selectedDoc._width = Number(value));
+        FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) * NumCast(this.selectedDoc?._height)) / oldWidth);
+    }
+    set shapeHgt(value) {
+        const oldHeight = NumCast(this.selectedDoc?._height);
+        this.selectedDoc && (this.selectedDoc._height = Number(value));
+        FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) * NumCast(this.selectedDoc?._width)) / oldHeight);
+    }
+
+    @computed get hgtInput() { return this.inputBoxDuo("hgt", this.shapeHgt, (val: string) => { if (!isNaN(Number(val))) { this.shapeHgt = val; } return true; }, "H:", "wid", this.shapeWid, (val: string) => { if (!isNaN(Number(val))) { this.shapeWid = val; } return true; }, "W:"); }
+    @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => { if (val !== "0" && !isNaN(Number(val))) { this.shapeXps = val; } return true; }, "X:", "Yps", this.shapeYps, (val: string) => { if (val !== "0" && !isNaN(Number(val))) { this.shapeYps = val; } return true; }, "Y:"); }
+    @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { if (!isNaN(Number(val))) { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; } return true; }, "∠:", "rot", this.shapeRot, (val: string) => { if (!isNaN(Number(val))) { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; } return true; }, ""); }
+
+
+    @observable private _fillBtn = false;
+    @observable private _lineBtn = false;
+
+    private _lastFill = "#D0021B";
+    private _lastLine = "#D0021B";
+    private _lastDash: any = "2";
+
+    @computed get colorFil() { const ccol = this.getField("fillColor") || ""; ccol && (this._lastFill = ccol); return ccol; }
+    @computed get colorStk() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; }
+    set colorFil(value) { value && (this._lastFill = value); this.selectedDoc && (this.selectedDoc.fillColor = value ? value : undefined); }
+    set colorStk(value) { value && (this._lastLine = value); this.selectedDoc && (this.selectedDoc.color = value ? value : undefined); }
+
+    colorButton(value: string, type: string, setter: () => {}) {
+        // return <div className="properties-flyout" onPointerEnter={e => this.changeScrolling(false)}
+        //     onPointerLeave={e => this.changeScrolling(true)}>
+        //     <Flyout anchorPoint={anchorPoints.LEFT_TOP}
+        //         content={type === "fill" ? this.fillPicker : this.linePicker}>
+        return <div className="color-button" key="color" onPointerDown={undoBatch(action(e => setter()))}>
+            <div className="color-button-preview" style={{
+                backgroundColor: value ?? "121212", width: 15, height: 15,
+                display: value === "" || value === "transparent" ? "none" : ""
+            }} />
+            {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -14 }}>☒</p> : ""}
+        </div>;
+        //     </Flyout>
+        // </div>;
+
+    }
+
+    @undoBatch
+    @action
+    switchStk = (color: ColorState) => {
+        const val = String(color.hex);
+        this.colorStk = val;
+        return true;
+    }
+    @undoBatch
+    @action
+    switchFil = (color: ColorState) => {
+        const val = String(color.hex);
+        this.colorFil = val;
+        return true;
+    }
+
+    colorPicker(setter: (color: string) => {}, type: string) {
+        return <SketchPicker onChange={type === "stk" ? this.switchStk : this.switchFil}
+            presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+                '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
+                '#FFFFFF', '#f1efeb', 'transparent']}
+            color={type === "stk" ? this.colorStk : this.colorFil} />;
+    }
+
+    @computed get fillButton() { return this.colorButton(this.colorFil, "fill", () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; return true; }); }
+    @computed get lineButton() { return this.colorButton(this.colorStk, "line", () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; return true; }); }
+
+    @computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color, "fil"); }
+    @computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color, "stk"); }
+
+    @computed get strokeAndFill() {
+        return <div>
+            <div key="fill" className="strokeAndFill">
+                <div className="fill">
+                    <div className="fill-title">Fill:</div>
+                    <div className="fill-button">{this.fillButton}</div>
+                </div>
+                <div className="stroke">
+                    <div className="stroke-title"> Stroke: </div>
+                    <div className="stroke-button">{this.lineButton}</div>
+                </div>
+            </div>
+            {this._fillBtn ? this.fillPicker : ""}
+            {this._lineBtn ? this.linePicker : ""}
+        </div>;
+    }
+
+    @computed get solidStk() { return this.selectedDoc?.color && (!this.selectedDoc?.strokeDash || this.selectedDoc?.strokeDash === "0") ? true : false; }
+    @computed get dashdStk() { return this.selectedDoc?.strokeDash || ""; }
+    @computed get unStrokd() { return this.selectedDoc?.color ? true : false; }
+    @computed get widthStk() { return this.getField("strokeWidth") || "1"; }
+    @computed get markHead() { return this.getField("strokeStartMarker") || ""; }
+    @computed get markTail() { return this.getField("strokeEndMarker") || ""; }
+    set solidStk(value) { this.dashdStk = ""; this.unStrokd = !value; }
+    set dashdStk(value) {
+        value && (this._lastDash = value) && (this.unStrokd = false);
+        this.selectedDoc && (this.selectedDoc.strokeDash = value ? this._lastDash : undefined);
+    }
+    set widthStk(value) { this.selectedDoc && (this.selectedDoc.strokeWidth = Number(value)); }
+    set unStrokd(value) { this.colorStk = value ? "" : this._lastLine; }
+    set markHead(value) { this.selectedDoc && (this.selectedDoc.strokeStartMarker = value); }
+    set markTail(value) { this.selectedDoc && (this.selectedDoc.strokeEndMarker = value); }
+
+
+    @computed get stkInput() { return this.regInput("stk", this.widthStk, (val: string) => this.widthStk = val); }
+
+
+    regInput = (key: string, value: any, setter: (val: string) => {}) => {
+        return <div className="inputBox">
+            <input className="inputBox-input"
+                type="text" value={value}
+                onChange={e => setter(e.target.value)} />
+            <div className="inputBox-button">
+                <div className="inputBox-button-up" key="up2"
+                    onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))} >
+                    <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
+                </div>
+                <div className="inputbox-Button-down" key="down2"
+                    onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} >
+                    <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
+                </div>
+            </div>
+        </div>;
+    }
+
+    @computed get widthAndDash() {
+        return <div className="widthAndDash">
+            <div className="width">
+                <div className="width-top">
+                    <div className="width-title">Width:</div>
+                    <div className="width-input">{this.stkInput}</div>
+                </div>
+                <input className="width-range" type="range"
+                    defaultValue={Number(this.widthStk)} min={1} max={100}
+                    onChange={(action((e) => this.widthStk = e.target.value))}
+                    onMouseDown={(e) => { this._widthUndo = UndoManager.StartBatch("width undo"); }}
+                    onMouseUp={(e) => { this._widthUndo?.end(); this._widthUndo = undefined; }}
+                />
+            </div>
+
+            <div className="arrows">
+                <div className="arrows-head">
+                    <div className="arrows-head-title" >Arrow Head: </div>
+                    <input key="markHead" className="arrows-head-input" type="checkbox"
+                        checked={this.markHead !== ""}
+                        onChange={undoBatch(action(() => this.markHead = this.markHead ? "" : "arrow"))} />
+                </div>
+                <div className="arrows-tail">
+                    <div className="arrows-tail-title" >Arrow End: </div>
+                    <input key="markTail" className="arrows-tail-input" type="checkbox"
+                        checked={this.markTail !== ""}
+                        onChange={undoBatch(action(() => this.markTail = this.markTail ? "" : "arrow"))} />
+                </div>
+            </div>
+            <div className="dashed">
+                <div className="dashed-title">Dashed Line:</div>
+                <input key="markHead" className="dashed-input"
+                    type="checkbox" checked={this.dashdStk === "2"}
+                    onChange={this.changeDash} />
+            </div>
+        </div>;
+    }
+
+    @undoBatch @action
+    changeDash = () => {
+        this.dashdStk = this.dashdStk === "2" ? "0" : "2";
+    }
+
+    @computed get appearanceEditor() {
+        return <div className="appearance-editor">
+            {this.widthAndDash}
+            {this.strokeAndFill}
+        </div>;
+    }
+
+    @computed get transformEditor() {
+        return <div className="transform-editor">
+            {this.controlPointsButton}
+            {this.hgtInput}
+            {this.XpsInput}
+            {this.rotInput}
+        </div>;
+    }
+
+    /**
+     * Handles adding and removing members from the sharing panel
+     */
+    // handleUserChange = (selectedUser: string, add: boolean) => {
+    //     if (!Doc.UserDoc().sidebarUsersDisplayed) Doc.UserDoc().sidebarUsersDisplayed = new Doc;
+    //     DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
+    //         sidebarUsersDisplayed![`display-${selectedUser}`] = add;
+    //         !add && runInAction(() => this.selectedUser = "");
+    //     });
+    // }
+
+    render() {
+        if (!this.selectedDoc && !this.isPres) {
+            return <div className="propertiesView" style={{ width: this.props.width }}>
+                <div className="propertiesView-title" style={{ width: this.props.width }}>
+                    No Document Selected
+                </div>
+            </div>;
+
+        } else {
+            const novice = Doc.UserDoc().noviceMode;
+
+            if (this.selectedDoc && !this.isPres) {
+                return <div className="propertiesView" style={{
+                    width: this.props.width,
+                    //overflowY: this.scrolling ? "scroll" : "visible"
+                }} >
+                    <div className="propertiesView-title" style={{ width: this.props.width }}>
+                        Properties
+                    {/* <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
+                        <FontAwesomeIcon icon="times" color="black" size="sm" />
+                    </div> */}
+                    </div>
+                    <div className="propertiesView-name">
+                        {this.editableTitle}
+                    </div>
+                    <div className="propertiesView-settings" onPointerEnter={action(() => this.inOptions = true)}
+                        onPointerLeave={action(() => this.inOptions = false)}>
+                        <div className="propertiesView-settings-title"
+                            onPointerDown={action(() => this.openOptions = !this.openOptions)}
+                            style={{ backgroundColor: this.openOptions ? "black" : "" }}>
+                            Options
+                        <div className="propertiesView-settings-title-icon">
+                                <FontAwesomeIcon icon={this.openOptions ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {!this.openOptions ? (null) :
+                            <div className="propertiesView-settings-content">
+                                <PropertiesButtons />
+                            </div>}
+                    </div>
+                    <div className="propertiesView-sharing">
+                        <div className="propertiesView-sharing-title"
+                            onPointerDown={action(() => this.openSharing = !this.openSharing)}
+                            style={{ backgroundColor: this.openSharing ? "black" : "" }}>
+                            Sharing {"&"} Permissions
+                        <div className="propertiesView-sharing-title-icon">
+                                <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {!this.openSharing ? (null) :
+                            <div className="propertiesView-sharing-content">
+                                <div className="propertiesView-acls-checkbox">
+                                    <Checkbox
+                                        color="primary"
+                                        onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)}
+                                        checked={this.layoutDocAcls}
+                                    />;
+                                    <div className="propertiesView-acls-checkbox-text">Layout</div>
+                                </div>
+                                {this.sharingTable}
+                                {/* <div className="change-buttons">
+                            <button
+                                onPointerDown={action(() => this.addButtonPressed = !this.addButtonPressed)}
+                            >
+                                <FontAwesomeIcon icon={fa.faPlus} size={"sm"} style={{ marginTop: -3, marginLeft: -3 }} />
+                            </button>
+                            <button
+                                id="sharingProperties-removeUser"
+                                onPointerDown={() => this.handleUserChange(this.selectedUser, false)}
+                                style={{ backgroundColor: this.selectedUser ? "#121721" : "#777777" }}
+                            ><FontAwesomeIcon icon={fa.faMinus} size={"sm"} style={{ marginTop: -3, marginLeft: -3 }} /></button>
+                            <button onClick={() => SharingManager.Instance.open(this.selectedDocumentView!)}><FontAwesomeIcon icon={fa.faCog} size={"sm"} style={{ marginTop: -3, marginLeft: -3 }} /></button>
+                            {this.addButtonPressed ?
+                                // <input type="text" onKeyDown={this.handleKeyPress} /> :
+                                <select onChange={e => this.handleUserChange(e.target.value, true)}>
+                                    <option selected disabled hidden>
+                                        Add users
+                                    </option>
+                                    {SharingManager.Instance.users.map(user =>
+                                        (<option value={user.user.email}>
+                                            {user.user.email}
+                                        </option>)
+                                    )}
+                                    {GroupManager.Instance.getAllGroups().map(group =>
+                                        (<option value={StrCast(group.groupName)}>
+                                            {StrCast(group.groupName)}
+                                        </option>))}
+                                </select> :
+                                null}
+                        </div> */}
+                            </div>}
+                    </div>
+
+                    {!this.isInk ? (null) :
+                        <div className="propertiesView-appearance">
+                            <div className="propertiesView-appearance-title"
+                                onPointerDown={action(() => this.openAppearance = !this.openAppearance)}
+                                style={{ backgroundColor: this.openAppearance ? "black" : "" }}>
+                                Appearance
+                            <div className="propertiesView-appearance-title-icon">
+                                    <FontAwesomeIcon icon={this.openAppearance ? "caret-down" : "caret-right"} size="lg" color="white" />
+                                </div>
+                            </div>
+                            {!this.openAppearance ? (null) :
+                                <div className="propertiesView-appearance-content">
+                                    {this.appearanceEditor}
+                                </div>}
+                        </div>}
+
+                    {this.isInk ? <div className="propertiesView-transform">
+                        <div className="propertiesView-transform-title"
+                            onPointerDown={action(() => this.openTransform = !this.openTransform)}
+                            style={{ backgroundColor: this.openTransform ? "black" : "" }}>
+                            Transform
+                        <div className="propertiesView-transform-title-icon">
+                                <FontAwesomeIcon icon={this.openTransform ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {this.openTransform ? <div className="propertiesView-transform-content">
+                            {this.transformEditor}
+                        </div> : null}
+                    </div> : null}
+
+                    <div className="propertiesView-fields">
+                        <div className="propertiesView-fields-title"
+                            onPointerDown={action(() => this.openFields = !this.openFields)}
+                            style={{ backgroundColor: this.openFields ? "black" : "" }}>
+                            Fields {"&"} Tags
+                            <div className="propertiesView-fields-title-icon">
+                                <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {!novice && this.openFields ? <div className="propertiesView-fields-checkbox">
+                            {this.fieldsCheckbox}
+                            <div className="propertiesView-fields-checkbox-text">Layout</div>
+                        </div> : null}
+                        {!this.openFields ? (null) :
+                            <div className="propertiesView-fields-content">
+                                {novice ? this.noviceFields : this.expandedField}
+                            </div>}
+                    </div>
+                    <div className="propertiesView-contexts">
+                        <div className="propertiesView-contexts-title"
+                            onPointerDown={action(() => this.openContexts = !this.openContexts)}
+                            style={{ backgroundColor: this.openContexts ? "black" : "" }}>
+                            Contexts
+                        <div className="propertiesView-contexts-title-icon">
+                                <FontAwesomeIcon icon={this.openContexts ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {this.openContexts ? <div className="propertiesView-contexts-content"  >{this.contexts}</div> : null}
+                    </div>
+                    <div className="propertiesView-layout">
+                        <div className="propertiesView-layout-title"
+                            onPointerDown={action(() => this.openLayout = !this.openLayout)}
+                            style={{ backgroundColor: this.openLayout ? "black" : "" }}>
+                            Layout
+                        <div className="propertiesView-layout-title-icon">
+                                <FontAwesomeIcon icon={this.openLayout ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {this.openLayout ? <div className="propertiesView-layout-content"  >{this.layoutPreview}</div> : null}
+                    </div>
+                </div>;
+            }
+            if (this.isPres) {
+                const selectedItem: boolean = PresBox.Instance?._selectedArray.length > 0;
+                return <div className="propertiesView" style={{ width: this.props.width }}>
+                    <div className="propertiesView-title" style={{ width: this.props.width }}>
+                        Presentation
+                    </div>
+                    <div className="propertiesView-name">
+                        {this.editableTitle}
+                        <div className="propertiesView-presSelected">
+                            {PresBox.Instance?._selectedArray.length} selected
+                            <div className="propertiesView-selectedList">
+                                {PresBox.Instance?.listOfSelected}
+                            </div>
+                        </div>
+                    </div>
+                    {!selectedItem ? (null) : <div className="propertiesView-presTrails">
+                        <div className="propertiesView-presTrails-title"
+                            onPointerDown={action(() => { this.openPresTransitions = !this.openPresTransitions; })}
+                            style={{ backgroundColor: this.openPresTransitions ? "black" : "" }}>
+                            &nbsp; <FontAwesomeIcon icon={"rocket"} /> &nbsp; Transitions
+                        <div className="propertiesView-presTrails-title-icon">
+                                <FontAwesomeIcon icon={this.openPresTransitions ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {this.openPresTransitions ? <div className="propertiesView-presTrails-content">
+                            {PresBox.Instance.transitionDropdown}
+                        </div> : null}
+                    </div>}
+                    {!selectedItem ? (null) : <div className="propertiesView-presTrails">
+                        <div className="propertiesView-presTrails-title"
+                            onPointerDown={action(() => { this.openPresProgressivize = !this.openPresProgressivize; })}
+                            style={{ backgroundColor: this.openPresProgressivize ? "black" : "" }}>
+                            &nbsp; <FontAwesomeIcon icon={"tasks"} /> &nbsp; Progressivize
+                        <div className="propertiesView-presTrails-title-icon">
+                                <FontAwesomeIcon icon={this.openPresProgressivize ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {this.openPresProgressivize ? <div className="propertiesView-presTrails-content">
+                            {PresBox.Instance.progressivizeDropdown}
+                        </div> : null}
+                    </div>}
+                    {!selectedItem ? (null) : <div className="propertiesView-presTrails">
+                        <div className="propertiesView-presTrails-title"
+                            onPointerDown={action(() => { this.openSlideOptions = !this.openSlideOptions; })}
+                            style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}>
+                            &nbsp; <FontAwesomeIcon icon={"cog"} /> &nbsp; {PresBox.Instance.stringType} options
+                        <div className="propertiesView-presTrails-title-icon">
+                                <FontAwesomeIcon icon={this.openSlideOptions ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {this.openSlideOptions ? <div className="propertiesView-presTrails-content">
+                            {PresBox.Instance.optionsDropdown}
+                        </div> : null}
+                    </div>}
+                    <div className="propertiesView-presTrails">
+                        <div className="propertiesView-presTrails-title"
+                            onPointerDown={action(() => { this.openAddSlide = !this.openAddSlide; })}
+                            style={{ backgroundColor: this.openAddSlide ? "black" : "" }}>
+                            &nbsp; <FontAwesomeIcon icon={"plus"} /> &nbsp; Add new slide
+                        <div className="propertiesView-presTrails-title-icon">
+                                <FontAwesomeIcon icon={this.openAddSlide ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {this.openAddSlide ? <div className="propertiesView-presTrails-content">
+                            {PresBox.Instance.newDocumentDropdown}
+                        </div> : null}
+                    </div>
+                    {/* <div className="propertiesView-sharing">
+                        <div className="propertiesView-sharing-title"
+                            onPointerDown={acition(() => { this.openSharing = !this.openSharing; })}
+                            style={{ backgroundColor: this.openSharing ? "black" : "" }}>
+                            Sharing {"&"} Permissions
+                        <div className="propertiesView-sharing-title-icon">
+                                <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {this.openSharing ? <div className="propertiesView-sharing-content">
+                            {this.sharingTable}
+                        </div> : null}
+                    </div> */}
+                </div>;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 06cadcacf..8301d3df8 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -31,7 +31,7 @@ import "./CollectionDockingView.scss";
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView";
 import { CollectionViewType } from './CollectionView';
-import { DockingViewButtonSelector } from './ParentDocumentSelector';
+import { CollectionDockingViewMenu } from './CollectionDockingViewMenu';
 import React = require("react");
 const _global = (window /* browser */ || global /* node */) as any;
 
@@ -80,11 +80,8 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
 
     @undoBatch
     public CloseFullScreen = () => {
-        const target = this._goldenLayout._maximisedItem;
-        if (target) {
-            target.remove();
-            this.stateChanged();
-        }
+        this._goldenLayout._maximisedItem?.toggleMaximise();
+        this.stateChanged();
     }
 
     @undoBatch
@@ -453,7 +450,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
         tab.reactComponents?.forEach((ele: any) => ReactDOM.unmountComponentAtNode(ele));
     }
     tabCreated = (tab: any) => {
-        (tab.contentItem.element[0]?.firstChild?.firstChild as any)?.InitTab(tab);  // have to explicitly initialize tabs that reuse contents from previous abs (ie, when dragging a tab around a new tab is created for the old content)
+        tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab(tab);  // have to explicitly initialize tabs that reuse contents from previous abs (ie, when dragging a tab around a new tab is created for the old content)
     }
 
     stackCreated = (stack: any) => {
@@ -563,7 +560,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
                 (view) => {
                     if (view) {
                         ReactDOM.render(<span title="Drag as document" className="collectionDockingView-dragAsDocument" onPointerDown={onDown} >
-                            <DockingViewButtonSelector views={() => [view]} Stack={stack} />
+                            <CollectionDockingViewMenu views={() => [view]} Stack={stack} />
                         </span>,
                             gearSpan);
                         tab._disposers.buttonDisposer?.();
diff --git a/src/client/views/collections/CollectionDockingViewMenu.scss b/src/client/views/collections/CollectionDockingViewMenu.scss
new file mode 100644
index 000000000..4157f0f7e
--- /dev/null
+++ b/src/client/views/collections/CollectionDockingViewMenu.scss
@@ -0,0 +1,34 @@
+
+.dockingViewButtonSelector {
+    div {
+        overflow: visible !important;
+    }
+
+    display: inline-block;
+    width:100%;
+    height:100%;
+}
+.dockingViewButtonSelector-flyout {
+    position: relative;
+    z-index: 9999;
+    background-color: #eeeeee;
+    box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
+    color: black;
+
+    padding: 10px;
+    border-radius: 3px;
+    display: inline-block;
+    height: 100%;
+    width: 100%;
+    border-radius: 3px;
+
+    hr {
+        height: 1px;
+        margin: 0px;
+        background-color: gray;
+        border-top: 0px;
+        border-bottom: 0px;
+        border-right: 0px;
+        border-left: 0px;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionDockingViewMenu.tsx b/src/client/views/collections/CollectionDockingViewMenu.tsx
new file mode 100644
index 000000000..4fe97452c
--- /dev/null
+++ b/src/client/views/collections/CollectionDockingViewMenu.tsx
@@ -0,0 +1,51 @@
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Tooltip } from "@material-ui/core";
+import { action, computed, observable } from "mobx";
+import { observer } from "mobx-react";
+import * as React from "react";
+import { DocumentButtonBar } from "../DocumentButtonBar";
+import { DocumentView } from "../nodes/DocumentView";
+const higflyout = require("@hig/flyout");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
+
+@observer
+export class CollectionDockingViewMenu extends React.Component<{ views: () => DocumentView[], Stack: any }> {
+    customStylesheet(styles: any) {
+        return {
+            ...styles,
+            panel: {
+                ...styles.panel,
+                minWidth: "100px"
+            },
+        };
+    }
+    _ref = React.createRef<HTMLDivElement>();
+
+    @computed get flyout() {
+        return (
+            <div className="dockingViewButtonSelector-flyout" title=" " ref={this._ref}>
+                <DocumentButtonBar views={this.props.views} stack={this.props.Stack} />
+            </div>
+        );
+    }
+
+    @observable _tooltipOpen: boolean = false;
+    render() {
+        return <Tooltip open={this._tooltipOpen} onClose={action(() => this._tooltipOpen = false)} title={<><div className="dash-tooltip">Tap for toolbar, drag to create alias in another pane</div></>} placement="bottom">
+            <span className="dockingViewButtonSelector"
+                onPointerEnter={action(() => !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))}
+                onPointerDown={action(e => {
+                    if (getComputedStyle(this._ref.current!).width !== "100%") {
+                        e.stopPropagation(); e.preventDefault();
+                    }
+                    this.props.views()[0]?.select(false);
+                    this._tooltipOpen = false;
+                })} >
+                <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.flyout} stylesheet={this.customStylesheet}>
+                    <FontAwesomeIcon icon={"arrows-alt"} size={"sm"} />
+                </Flyout>
+            </span>
+        </Tooltip >;
+    }
+}
diff --git a/src/client/views/collections/ParentDocumentSelector.scss b/src/client/views/collections/ParentDocumentSelector.scss
deleted file mode 100644
index bc9cf4848..000000000
--- a/src/client/views/collections/ParentDocumentSelector.scss
+++ /dev/null
@@ -1,63 +0,0 @@
-.parentDocumentSelector-linkFlyout {
-    div {
-        overflow: visible !important;
-    }
-
-    .metadataEntry-outerDiv {
-        overflow: hidden !important;
-        pointer-events: all;
-    }
-}
-
-.parentDocumentSelector-flyout {
-    position: relative;
-    z-index: 9999;
-    background-color: #eeeeee;
-    box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
-    color: black;
-
-    padding: 10px;
-    border-radius: 3px;
-    display: inline-block;
-    height: 100%;
-    width: 100%;
-    border-radius: 3px;
-
-    hr {
-        height: 1px;
-        margin: 0px;
-        background-color: gray;
-        border-top: 0px;
-        border-bottom: 0px;
-        border-right: 0px;
-        border-left: 0px;
-    }
-}
-
-.parentDocumentSelector-button {
-    pointer-events: all;
-    position: relative;
-    display: inline-block;
-
-    svg {
-        // width:20px !important;
-        //height:20px;
-    }
-}
-
-.parentDocumentSelector-metadata {
-    pointer-events: auto;
-    padding-right: 5px;
-    width: 25px;
-    display: inline-block;
-}
-
-.buttonSelector {
-    div {
-        overflow: visible !important;
-    }
-
-    display: inline-block;
-    width:100%;
-    height:100%;
-}
\ No newline at end of file
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
deleted file mode 100644
index f019ddfe6..000000000
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Tooltip } from "@material-ui/core";
-import { computed, IReactionDisposer, observable, reaction, runInAction, action } from "mobx";
-import { observer } from "mobx-react";
-import * as React from "react";
-import { Doc } from "../../../fields/Doc";
-import { Id } from "../../../fields/FieldSymbols";
-import { NumCast } from "../../../fields/Types";
-import { SearchUtil } from "../../util/SearchUtil";
-import { DocumentButtonBar } from "../DocumentButtonBar";
-import { DocumentView } from "../nodes/DocumentView";
-import { CollectionDockingView } from "./CollectionDockingView";
-import { CollectionViewType } from "./CollectionView";
-import './ParentDocumentSelector.scss';
-const higflyout = require("@hig/flyout");
-export const { anchorPoints } = higflyout;
-export const Flyout = higflyout.default;
-
-type SelectorProps = {
-    Document: Doc,
-    Stack?: any,
-    hideTitle?: boolean,
-    addDocTab(doc: Doc, location: string): void
-};
-
-@observer
-export class SelectorContextMenu extends React.Component<SelectorProps> {
-    @observable private _docs: { col: Doc, target: Doc }[] = [];
-    @observable private _otherDocs: { col: Doc, target: Doc }[] = [];
-    _reaction: IReactionDisposer | undefined;
-
-    componentDidMount() {
-        this._reaction = reaction(() => this.props.Document, () => this.fetchDocuments(), { fireImmediately: true });
-    }
-    componentWillUnmount() {
-        this._reaction?.();
-    }
-    async fetchDocuments() {
-        const aliases = await SearchUtil.GetAliasesOfDocument(this.props.Document);
-        const containerProtoSets = await Promise.all(aliases.map(async alias => ((await SearchUtil.Search("", true, { fq: `data_l:"${alias[Id]}"` })).docs)));
-        const containerProtos = containerProtoSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set<Doc>());
-        const containerSets = await Promise.all(Array.from(containerProtos.keys()).map(async container => SearchUtil.GetAliasesOfDocument(container)));
-        const containers = containerSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set<Doc>());
-        const doclayoutSets = await Promise.all(Array.from(containers.keys()).map(async (dp) => SearchUtil.GetAliasesOfDocument(dp)));
-        const doclayouts = Array.from(doclayoutSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set<Doc>()).keys());
-        runInAction(() => {
-            this._docs = doclayouts.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).filter(doc => !Doc.IsSystem(doc)).map(doc => ({ col: doc, target: this.props.Document }));
-            this._otherDocs = [];
-        });
-    }
-
-    getOnClick({ col, target }: { col: Doc, target: Doc }) {
-        return () => {
-            col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col;
-            if (col._viewType === CollectionViewType.Freeform) {
-                const newPanX = NumCast(target.x) + NumCast(target._width) / 2;
-                const newPanY = NumCast(target.y) + NumCast(target._height) / 2;
-                col._panX = newPanX;
-                col._panY = newPanY;
-            }
-            this.props.addDocTab(col, "inTab"); // bcz: dataDoc?
-        };
-    }
-
-    render() {
-        return <div >
-            {this.props.hideTitle ? (null) : <p key="contexts">Contexts:</p>}
-            {this._docs.map(doc => <p key={doc.col[Id] + doc.target[Id]}><a onClick={this.getOnClick(doc)}>{doc.col.title?.toString()}</a></p>)}
-            {this._otherDocs.length ? <hr key="hr" /> : null}
-            {this._otherDocs.map(doc => <p key={"p" + doc.col[Id] + doc.target[Id]}><a onClick={this.getOnClick(doc)}>{doc.col.title?.toString()}</a></p>)}
-        </div>;
-    }
-}
-@observer
-export class DockingViewButtonSelector extends React.Component<{ views: () => DocumentView[], Stack: any }> {
-    customStylesheet(styles: any) {
-        return {
-            ...styles,
-            panel: {
-                ...styles.panel,
-                minWidth: "100px"
-            },
-        };
-    }
-    _ref = React.createRef<HTMLDivElement>();
-
-    @computed get flyout() {
-        return (
-            <div className="ParentDocumentSelector-flyout" title=" " ref={this._ref}>
-                <DocumentButtonBar views={this.props.views} stack={this.props.Stack} />
-            </div>
-        );
-    }
-
-    @observable _tooltipOpen: boolean = false;
-    render() {
-        return <Tooltip open={this._tooltipOpen} onClose={action(() => this._tooltipOpen = false)} title={<><div className="dash-tooltip">Tap for toolbar, drag to create alias in another pane</div></>} placement="bottom">
-            <span className="buttonSelector"
-                onPointerEnter={action(() => !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))}
-                onPointerDown={action(e => {
-                    if (getComputedStyle(this._ref.current!).width !== "100%") {
-                        e.stopPropagation(); e.preventDefault();
-                    }
-                    this.props.views()[0]?.select(false);
-                    this._tooltipOpen = false;
-                })} >
-                <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.flyout} stylesheet={this.customStylesheet}>
-                    <FontAwesomeIcon icon={"arrows-alt"} size={"sm"} />
-                </Flyout>
-            </span>
-        </Tooltip >;
-    }
-}
diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
deleted file mode 100644
index d49ab27fb..000000000
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
+++ /dev/null
@@ -1,68 +0,0 @@
-.antimodeMenu-button {
-    width: 200px;
-    position: relative;
-    text-align: left;
-
-    .color-previewI {
-        width: 100%;
-        height: 40%;
-    }
-
-    .color-previewII {
-        width: 100%;
-        height: 100%;
-    }
-}
-
-.antimenu-Buttonup {
-    position: absolute;
-    width: 20;
-    height: 10;
-    right: 0;
-    padding: 0;
-}
-
-.formatShapePane-inputBtn {
-    width: inherit;
-    position: absolute;
-}
-
-.btn-group-palette {
-    .sketch-picker {
-        background: #323232;
-        width: 160px !important;
-        height: 80% !important;
-
-        .flexbox-fit {
-            background: #323232;
-        }
-    }
-}
-
-.btn-group {
-    display: grid;
-    grid-template-columns: auto auto auto auto;
-    /* Make the buttons appear below each other */
-}
-
-.btn-group-palette {
-    display: block;
-    /* Make the buttons appear below each other */
-}
-
-.btn-draw {
-    display: inline;
-    /* Make the buttons appear below each other */
-}
-
-.btn2-group {
-    display: block;
-    background: #323232;
-    grid-template-columns: auto;
-
-    /* Make the buttons appear below each other */
-    .antimodeMenu-button {
-        background: #323232;
-        display: block;
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
deleted file mode 100644
index e6ec274f0..000000000
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
+++ /dev/null
@@ -1,545 +0,0 @@
-import React = require("react");
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, runInAction } from "mobx";
-import { observer } from "mobx-react";
-import { Doc, Field, Opt } from "../../../../fields/Doc";
-import { Document } from "../../../../fields/documentSchemas";
-import { InkField } from "../../../../fields/InkField";
-import { BoolCast, Cast, NumCast } from "../../../../fields/Types";
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { SelectionManager } from "../../../util/SelectionManager";
-import { AntimodeMenu, AntimodeMenuProps } from "../../AntimodeMenu";
-import "./FormatShapePane.scss";
-import { undoBatch } from "../../../util/UndoManager";
-import { ColorState, SketchPicker } from 'react-color';
-
-@observer
-export class FormatShapePane extends AntimodeMenu<AntimodeMenuProps> {
-    static Instance: FormatShapePane;
-
-    private _lastFill = "#D0021B";
-    private _lastLine = "#D0021B";
-    private _lastDash = "2";
-    private _mode = ["fill-drip", "ruler-combined"];
-
-    @observable private _subOpen = [false, false];
-    @observable private _currMode = "fill-drip";
-    @observable _lock = false;
-    @observable private _fillBtn = false;
-    @observable private _lineBtn = false;
-    @observable _controlBtn = false;
-    @observable private _controlPoints: { X: number, Y: number }[] = [];
-    @observable _currPoint = -1;
-
-    getField(key: string) {
-        return this.selectedInk?.reduce((p, i) =>
-            (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt<string>);
-    }
-
-    @computed get selectedInk() {
-        const inks = SelectionManager.SelectedDocuments().filter(i => Document(i.rootDoc).type === DocumentType.INK);
-        return inks.length ? inks : undefined;
-    }
-    @computed get unFilled() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.fillColor ? true : false, true) || false; }
-    @computed get unStrokd() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.color ? true : false, true) || false; }
-    @computed get solidFil() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.fillColor ? true : false, true) || false; }
-    @computed get solidStk() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.color && (!i.rootDoc.strokeDash || i.rootDoc.strokeDash === "0") ? true : false, true) || false; }
-    @computed get dashdStk() { return !this.unStrokd && this.getField("strokeDash") || ""; }
-    @computed get colorFil() { const ccol = this.getField("fillColor") || ""; ccol && (this._lastFill = ccol); return ccol; }
-    @computed get colorStk() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; }
-    @computed get widthStk() { return this.getField("strokeWidth") || "1"; }
-    @computed get markHead() { return this.getField("strokeStartMarker") || ""; }
-    @computed get markTail() { return this.getField("strokeEndMarker") || ""; }
-    @computed get shapeHgt() { return this.getField("_height"); }
-    @computed get shapeWid() { return this.getField("_width"); }
-    @computed get shapeXps() { return this.getField("x"); }
-    @computed get shapeYps() { return this.getField("y"); }
-    @computed get shapeRot() { return this.getField("rotation"); }
-    set unFilled(value) { this.colorFil = value ? "" : this._lastFill; }
-    set solidFil(value) { this.unFilled = !value; }
-    set colorFil(value) { value && (this._lastFill = value); this.selectedInk?.forEach(i => i.rootDoc.fillColor = value ? value : undefined); }
-    set colorStk(value) { value && (this._lastLine = value); this.selectedInk?.forEach(i => i.rootDoc.color = value ? value : undefined); }
-    set markHead(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeStartMarker = value); }
-    set markTail(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeEndMarker = value); }
-    set unStrokd(value) { this.colorStk = value ? "" : this._lastLine; }
-    set solidStk(value) { this.dashdStk = ""; this.unStrokd = !value; }
-    set dashdStk(value) {
-        value && (this._lastDash = value) && (this.unStrokd = false);
-        this.selectedInk?.forEach(i => i.rootDoc.strokeDash = value ? this._lastDash : undefined);
-    }
-    set shapeXps(value) { this.selectedInk?.forEach(i => i.rootDoc.x = Number(value)); }
-    set shapeYps(value) { this.selectedInk?.forEach(i => i.rootDoc.y = Number(value)); }
-    set shapeRot(value) { this.selectedInk?.forEach(i => i.rootDoc.rotation = Number(value)); }
-    set widthStk(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeWidth = Number(value)); }
-    set shapeWid(value) {
-        this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
-            const oldWidth = NumCast(i.rootDoc._width);
-            i.rootDoc._width = Number(value);
-            this._lock && (i.rootDoc._height = (i.rootDoc._width * NumCast(i.rootDoc._height)) / oldWidth);
-        });
-    }
-    set shapeHgt(value) {
-        this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
-            const oldHeight = NumCast(i.rootDoc._height);
-            i.rootDoc._height = Number(value);
-            this._lock && (i.rootDoc._width = (i.rootDoc._height * NumCast(i.rootDoc._width)) / oldHeight);
-        });
-    }
-
-    constructor(props: Readonly<{}>) {
-        super(props);
-        FormatShapePane.Instance = this;
-        this._canFade = false;
-        runInAction(() => this.Pinned = BoolCast(Doc.UserDoc()["menuFormatShape-pinned"]));
-    }
-
-    @action
-    closePane = () => {
-        this.fadeOut(false);
-        this.Pinned = false;
-    }
-
-    @action
-    upDownButtons = (dirs: string, field: string) => {
-        switch (field) {
-            case "rot": this.rotate((dirs === "up" ? .1 : -.1)); break;
-            // case "rot": this.selectedInk?.forEach(i => i.rootDoc.rotation = NumCast(i.rootDoc.rotation) + (dirs === "up" ? 0.1 : -0.1)); break;
-            case "Xps": this.selectedInk?.forEach(i => i.rootDoc.x = NumCast(i.rootDoc.x) + (dirs === "up" ? 10 : -10)); break;
-            case "Yps": this.selectedInk?.forEach(i => i.rootDoc.y = NumCast(i.rootDoc.y) + (dirs === "up" ? 10 : -10)); break;
-            case "stk": this.selectedInk?.forEach(i => i.rootDoc.strokeWidth = NumCast(i.rootDoc.strokeWidth) + (dirs === "up" ? .1 : -.1)); break;
-            case "wid": this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
-                //redraw points
-                const oldWidth = NumCast(i.rootDoc._width);
-                const oldHeight = NumCast(i.rootDoc._height);
-                const oldX = NumCast(i.rootDoc.x);
-                const oldY = NumCast(i.rootDoc.y);
-                i.rootDoc._width = oldWidth + (dirs === "up" ? 10 : - 10);
-                this._lock && (i.rootDoc._height = (i.rootDoc._width / oldWidth * NumCast(i.rootDoc._height)));
-                const doc = Document(i.rootDoc);
-                if (doc.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
-                    const ink = Cast(doc.data, InkField)?.inkData;
-                    if (ink) {
-                        const newPoints: { X: number, Y: number }[] = [];
-                        ink.forEach(i => {
-                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
-                            const newX = ((doc.x || 0) - oldX) + (i.X * (doc._width || 0)) / oldWidth;
-                            const newY = ((doc.y || 0) - oldY) + (i.Y * (doc._height || 0)) / oldHeight;
-                            newPoints.push({ X: newX, Y: newY });
-                        });
-                        Doc.GetProto(doc).data = new InkField(newPoints);
-                    }
-                }
-            });
-                break;
-            case "hgt": this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => {
-                const oldWidth = NumCast(i.rootDoc._width);
-                const oldHeight = NumCast(i.rootDoc._height);
-                const oldX = NumCast(i.rootDoc.x);
-                const oldY = NumCast(i.rootDoc.y); i.rootDoc._height = oldHeight + (dirs === "up" ? 10 : - 10);
-                this._lock && (i.rootDoc._width = (i.rootDoc._height / oldHeight * NumCast(i.rootDoc._width)));
-                const doc = Document(i.rootDoc);
-                if (doc.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
-                    const ink = Cast(doc.data, InkField)?.inkData;
-                    if (ink) {
-                        const newPoints: { X: number, Y: number }[] = [];
-                        ink.forEach(i => {
-                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
-                            const newX = ((doc.x || 0) - oldX) + (i.X * (doc._width || 0)) / oldWidth;
-                            const newY = ((doc.y || 0) - oldY) + (i.Y * (doc._height || 0)) / oldHeight;
-                            newPoints.push({ X: newX, Y: newY });
-                        });
-                        Doc.GetProto(doc).data = new InkField(newPoints);
-                    }
-                }
-            });
-                break;
-        }
-    }
-
-    @undoBatch
-    @action
-    addPoints = (x: number, y: number, pts: { X: number, Y: number }[], index: number, control: { X: number, Y: number }[]) => {
-        this.selectedInk?.forEach(action(inkView => {
-            if (this.selectedInk?.length === 1) {
-                const doc = Document(inkView.rootDoc);
-                if (doc.type === DocumentType.INK) {
-                    const ink = Cast(doc.data, InkField)?.inkData;
-                    if (ink) {
-                        const newPoints: { X: number, Y: number }[] = [];
-                        var counter = 0;
-                        for (var k = 0; k < index; k++) {
-                            control.forEach(pt => (pts[k].X === pt.X && pts[k].Y === pt.Y) && counter++);
-                        }
-                        //decide where to put the new coordinate
-                        const spNum = Math.floor(counter / 2) * 4 + 2;
-
-                        for (var i = 0; i < spNum; i++) {
-                            ink[i] && newPoints.push({ X: ink[i].X, Y: ink[i].Y });
-                        }
-                        for (var j = 0; j < 4; j++) {
-                            newPoints.push({ X: x, Y: y });
-
-                        }
-                        for (var i = spNum; i < ink.length; i++) {
-                            newPoints.push({ X: ink[i].X, Y: ink[i].Y });
-                        }
-                        this._currPoint = -1;
-                        Doc.GetProto(doc).data = new InkField(newPoints);
-                    }
-                }
-            }
-        }));
-    }
-
-    @undoBatch
-    @action
-    deletePoints = () => {
-        this.selectedInk?.forEach(action(inkView => {
-            if (this.selectedInk?.length === 1 && this._currPoint !== -1) {
-                const doc = Document(inkView.rootDoc);
-                if (doc.type === DocumentType.INK) {
-                    const ink = Cast(doc.data, InkField)?.inkData;
-                    if (ink && ink.length > 4) {
-                        const newPoints: { X: number, Y: number }[] = [];
-                        const toRemove = Math.floor(((this._currPoint + 2) / 4));
-                        for (var i = 0; i < ink.length; i++) {
-                            if (Math.floor((i + 2) / 4) !== toRemove) {
-                                newPoints.push({ X: ink[i].X, Y: ink[i].Y });
-                            }
-                        }
-                        this._currPoint = -1;
-                        Doc.GetProto(doc).data = new InkField(newPoints);
-                        if (newPoints.length === 4) {
-                            const newerPoints: { X: number, Y: number }[] = [];
-                            newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y });
-                            newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y });
-                            newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y });
-                            newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y });
-                            Doc.GetProto(doc).data = new InkField(newerPoints);
-
-                        }
-                    }
-                }
-            }
-        }));
-    }
-
-    @undoBatch
-    @action
-    rotate = (angle: number) => {
-        const _centerPoints: { X: number, Y: number }[] = [];
-        SelectionManager.SelectedDocuments().forEach(action(inkView => {
-            const doc = Document(inkView.rootDoc);
-            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
-                const ink = Cast(doc.data, InkField)?.inkData;
-                if (ink) {
-                    const xs = ink.map(p => p.X);
-                    const ys = ink.map(p => p.Y);
-                    const left = Math.min(...xs);
-                    const top = Math.min(...ys);
-                    const right = Math.max(...xs);
-                    const bottom = Math.max(...ys);
-                    _centerPoints.push({ X: left, Y: top });
-                }
-            }
-        }));
-
-        var index = 0;
-        SelectionManager.SelectedDocuments().forEach(action(inkView => {
-            const doc = Document(inkView.rootDoc);
-            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
-                doc.rotation = Number(doc.rotation) + Number(angle);
-                const ink = Cast(doc.data, InkField)?.inkData;
-                if (ink) {
-
-                    const newPoints: { X: number, Y: number }[] = [];
-                    ink.forEach(i => {
-                        const newX = Math.cos(angle) * (i.X - _centerPoints[index].X) - Math.sin(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].X;
-                        const newY = Math.sin(angle) * (i.X - _centerPoints[index].X) + Math.cos(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].Y;
-                        newPoints.push({ X: newX, Y: newY });
-                    });
-                    Doc.GetProto(doc).data = new InkField(newPoints);
-                    const xs = newPoints.map(p => p.X);
-                    const ys = newPoints.map(p => p.Y);
-                    const left = Math.min(...xs);
-                    const top = Math.min(...ys);
-                    const right = Math.max(...xs);
-                    const bottom = Math.max(...ys);
-
-                    doc._height = (bottom - top);
-                    doc._width = (right - left);
-                }
-                index++;
-            }
-        }));
-    }
-
-    @undoBatch
-    @action
-    control = (xDiff: number, yDiff: number, controlNum: number) => {
-        this.selectedInk?.forEach(action(inkView => {
-            if (this.selectedInk?.length === 1) {
-                const doc = Document(inkView.rootDoc);
-                if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
-                    const ink = Cast(doc.data, InkField)?.inkData;
-                    if (ink) {
-
-                        const newPoints: { X: number, Y: number }[] = [];
-                        const order = controlNum % 4;
-                        for (var i = 0; i < ink.length; i++) {
-                            if (controlNum === i ||
-                                (order === 0 && i === controlNum + 1) ||
-                                (order === 0 && controlNum !== 0 && i === controlNum - 2) ||
-                                (order === 0 && controlNum !== 0 && i === controlNum - 1) ||
-                                (order === 3 && i === controlNum - 1) ||
-                                (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 1) ||
-                                (order === 3 && controlNum !== ink.length - 1 && i === controlNum + 2)
-                                || ((ink[0].X === ink[ink.length - 1].X) && (ink[0].Y === ink[ink.length - 1].Y) && (i === 0 || i === ink.length - 1) && (controlNum === 0 || controlNum === ink.length - 1))
-                            ) {
-                                newPoints.push({ X: ink[i].X - (xDiff * inkView.props.ScreenToLocalTransform().Scale), Y: ink[i].Y - (yDiff * inkView.props.ScreenToLocalTransform().Scale) });
-                            }
-                            else {
-                                newPoints.push({ X: ink[i].X, Y: ink[i].Y });
-                            }
-                        }
-                        const oldx = doc.x;
-                        const oldy = doc.y;
-                        const xs = ink.map(p => p.X);
-                        const ys = ink.map(p => p.Y);
-                        const left = Math.min(...xs);
-                        const top = Math.min(...ys);
-                        Doc.GetProto(doc).data = new InkField(newPoints);
-                        const xs2 = newPoints.map(p => p.X);
-                        const ys2 = newPoints.map(p => p.Y);
-                        const left2 = Math.min(...xs2);
-                        const top2 = Math.min(...ys2);
-                        const right2 = Math.max(...xs2);
-                        const bottom2 = Math.max(...ys2);
-                        doc._height = (bottom2 - top2);
-                        doc._width = (right2 - left2);
-                        //if points move out of bounds
-
-                        doc.x = oldx - (left - left2);
-                        doc.y = oldy - (top - top2);
-
-                    }
-                }
-            }
-        }));
-    }
-
-    @undoBatch
-    @action
-    switchStk = (color: ColorState) => {
-        const val = String(color.hex);
-        this.colorStk = val;
-        return true;
-    }
-
-    @undoBatch
-    @action
-    switchFil = (color: ColorState) => {
-        const val = String(color.hex);
-        this.colorFil = val;
-        return true;
-    }
-
-
-    colorPicker(setter: (color: string) => {}, type: string) {
-        return <div className="btn-group-palette" key="colorpicker" style={{ width: 160, margin: 10 }}>
-            <SketchPicker onChange={type === "stk" ? this.switchStk : this.switchFil} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']}
-                color={type === "stk" ? this.colorStk : this.colorFil} />
-        </div>;
-    }
-    inputBox = (key: string, value: any, setter: (val: string) => {}) => {
-        return <>
-            <input style={{ color: "black", width: 40, position: "absolute", right: 20 }}
-                type="text" defaultValue={value}
-                onChange={undoBatch(action((e) => setter(e.target.value)))}
-                autoFocus />
-            <button className="antiMenu-Buttonup" key="up1" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))}>
-                ˄
-            </button>
-            <br />
-            <button className="antiMenu-Buttonup" key="down1" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} style={{ marginTop: -8 }}>
-                ˅
-            </button>
-        </>;
-    }
-
-    inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => {
-        return <>
-            {title1}
-            <p style={{ marginTop: -20, right: 70, position: "absolute" }}>{title2}</p>
-
-            <input style={{ color: "black", width: 40, position: "absolute", right: 130 }}
-                type="text" defaultValue={value}
-                onChange={e => setter(e.target.value)}
-                autoFocus />
-            <button className="antiMenu-Buttonup" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))} style={{ right: 110 }}>
-                ˄
-        </button>
-            <button className="antiMenu-Buttonup" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} style={{ marginTop: 12, right: 110 }}>
-                ˅
-        </button>
-            {title2 === "" ? "" : <>
-                <input style={{ color: "black", width: 40, position: "absolute", right: 20 }}
-                    type="text" defaultValue={value2}
-                    onChange={e => setter2(e.target.value)}
-                    autoFocus />
-                <button className="antiMenu-Buttonup" key="up3" onPointerDown={undoBatch(action(() => this.upDownButtons("up", key2)))}>
-                    ˄
-      </button>
-                <br />
-                <button className="antiMenu-Buttonup" key="down3" onPointerDown={undoBatch(action(() => this.upDownButtons("down", key2)))} style={{ marginTop: -8 }}>
-                    ˅
-      </button></>}
-        </>;
-    }
-
-
-    colorButton(value: string, setter: () => {}) {
-        return <>
-            <button className="antimodeMenu-button" key="color" onPointerDown={undoBatch(action(e => setter()))} style={{ position: "relative", marginTop: -5 }}>
-                <div className="color-previewII" style={{ backgroundColor: value ?? "121212" }} />
-                {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -23, position: "fixed" }}>☒</p> : ""}
-            </button>
-        </>;
-    }
-
-    controlPointsButton() {
-        return <>
-            <button className="antimodeMenu-button" title="Edit points" key="bezier" onPointerDown={action(() => this._controlBtn = this._controlBtn ? false : true)} style={{ position: "relative", marginTop: 10, backgroundColor: this._controlBtn ? "black" : "" }}>
-                <FontAwesomeIcon icon="bezier-curve" size="lg" />
-            </button>
-            <button className="antimodeMenu-button" title="Lock ratio" key="ratio" onPointerDown={action(() => this._lock = this._lock ? false : true)} style={{ position: "relative", marginTop: 10, backgroundColor: this._lock ? "black" : "" }}>
-                <FontAwesomeIcon icon="lock" size="lg" />
-
-            </button>
-            <button className="antimodeMenu-button" key="rotate" title="Rotate 90˚" onPointerDown={action(() => this.rotate(Math.PI / 2))} style={{ position: "relative", marginTop: 10, fontSize: 15 }}>
-                ⟲
-            </button>
-            <br /> <br />
-        </>;
-    }
-
-    lockRatioButton() {
-        return <>
-            <button className="antimodeMenu-button" key="lock" onPointerDown={action(() => this._lock = this._lock ? false : true)} style={{ position: "absolute", right: 80, backgroundColor: this._lock ? "black" : "" }}>
-                {/* <FontAwesomeIcon icon="bezier-curve" size="lg" /> */}
-                <FontAwesomeIcon icon="lock" size="lg" />
-
-            </button>
-            <br /> <br />
-        </>;
-    }
-
-    rotate90Button() {
-        return <>
-            <button className="antimodeMenu-button" key="rot" onPointerDown={action(() => this.rotate(Math.PI / 2))} style={{ position: "absolute", right: 80, }}>
-                {/* <FontAwesomeIcon icon="bezier-curve" size="lg" /> */}
-                ⟲
-            </button>
-            <br /> <br />
-        </>;
-    }
-    @computed get fillButton() { return this.colorButton(this.colorFil, () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; return true; }); }
-    @computed get lineButton() { return this.colorButton(this.colorStk, () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; return true; }); }
-
-    @computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color, "fil"); }
-    @computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color, "stk"); }
-
-    @computed get stkInput() { return this.inputBox("stk", this.widthStk, (val: string) => this.widthStk = val); }
-    @computed get dashInput() { return this.inputBox("dsh", this.widthStk, (val: string) => this.widthStk = val); }
-
-    @computed get hgtInput() { return this.inputBoxDuo("hgt", this.shapeHgt, (val: string) => this.shapeHgt = val, "H:", "wid", this.shapeWid, (val: string) => this.shapeWid = val, "W:"); }
-    @computed get widInput() { return this.inputBox("wid", this.shapeWid, (val: string) => this.shapeWid = val); }
-    @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; return true; }, "∠:", "rot", this.shapeRot, (val: string) => this.shapeRot = val, ""); }
-
-    @computed get YpsInput() { return this.inputBox("Yps", this.shapeYps, (val: string) => this.shapeYps = val); }
-
-    @computed get controlPoints() { return this.controlPointsButton(); }
-    @computed get lockRatio() { return this.lockRatioButton(); }
-    @computed get rotate90() { return this.rotate90Button(); }
-    @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); }
-
-
-    @computed get propertyGroupItems() {
-        const fillCheck = <div key="fill" style={{ display: (this._subOpen[0] && this.selectedInk && this.selectedInk.length >= 1) ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
-            Fill:
-            {this.fillButton}
-            <div style={{ float: "left", width: 100 }} >
-                Stroke:
-            {this.lineButton}
-            </div>
-
-            {this._fillBtn ? this.fillPicker : ""}
-            {this._lineBtn ? this.linePicker : ""}
-            {this._fillBtn || this._lineBtn ? "" : <br />}
-            {(this.solidStk || this.dashdStk) ? "Width" : ""}
-            {(this.solidStk || this.dashdStk) ? this.stkInput : ""}
-            {(this.solidStk || this.dashdStk) ? <input type="range" defaultValue={Number(this.widthStk)} min={1} max={100} onChange={undoBatch(action((e) => this.widthStk = e.target.value))} /> : (null)}
-            <br />
-            {(this.solidStk || this.dashdStk) ? <>
-                <p style={{ position: "absolute", fontSize: 12 }}>Arrow Head</p>
-                <input key="markHead" className="formatShapePane-inputBtn" type="checkbox" checked={this.markHead !== ""} onChange={undoBatch(action(() => this.markHead = this.markHead ? "" : "arrow"))} style={{ position: "absolute", right: 110, width: 20 }} />
-                <p style={{ position: "absolute", fontSize: 12, right: 30 }}>Arrow End</p>
-                <input key="markTail" className="formatShapePane-inputBtn" type="checkbox" checked={this.markTail !== ""} onChange={undoBatch(action(() => this.markTail = this.markTail ? "" : "arrow"))} style={{ position: "absolute", right: 0, width: 20 }} />
-                <br />
-            </> : ""}
-            Dash:
-            <input key="markHead" className="formatShapePane-inputBtn" type="checkbox" checked={this.dashdStk === "2"} onChange={undoBatch(action(() => this.dashdStk = this.dashdStk === "2" ? "0" : "2"))} style={{ position: "absolute", right: 110, width: 20 }} />
-        </div>;
-
-
-
-        const sizeCheck =
-
-            <div key="sizeCheck" style={{ display: (this._subOpen[1] && this.selectedInk && this.selectedInk.length >= 1) ? "" : "none", width: "inherit", backgroundColor: "#323232", color: "white", }}>
-                {this.controlPoints}
-                {this.hgtInput}
-                {this.XpsInput}
-                {this.rotInput}
-
-            </div>;
-
-
-        const subMenus = this._currMode === "fill-drip" ? [`Appearance`, 'Transform'] : [];
-        const menuItems = this._currMode === "fill-drip" ? [fillCheck, sizeCheck] : [];
-        const indexOffset = 0;
-
-        return <div className="antimodeMenu-sub" key="submenu" style={{ position: "absolute", width: "inherit", top: 60 }}>
-            {subMenus.map((subMenu, i) =>
-                <div key={subMenu} style={{ width: "inherit" }}>
-                    <button className="antimodeMenu-button" onPointerDown={action(() => this._subOpen[i + indexOffset] = !this._subOpen[i + indexOffset])}
-                        style={{ backgroundColor: "121212", position: "relative", width: "inherit" }}>
-                        {this._subOpen[i + indexOffset] ? "▼" : "▶︎"}
-                        {subMenu}
-                    </button>
-                    {menuItems[i]}
-                </div>)}
-        </div>;
-    }
-
-    @computed get closeBtn() {
-        return <button className="antimodeMenu-button" key="close" onPointerDown={action(() => this.closePane())} style={{ position: "absolute", right: 0 }}>
-            X
-        </button>;
-    }
-
-    @computed get propertyGroupBtn() {
-        return <div className="antimodeMenu-button-tab" key="modes">
-            {this._mode.map(mode =>
-                <button className="antimodeMenu-button" key={mode} onPointerDown={action(() => this._currMode = mode)}
-                    style={{ backgroundColor: this._currMode === mode ? "121212" : "", position: "relative", top: 30 }}>
-                    <FontAwesomeIcon icon={mode as IconProp} size="lg" />
-                </button>)}
-        </div>;
-    }
-
-    render() {
-        return this.getElementVert([this.closeBtn,
-        this.propertyGroupItems]);
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
deleted file mode 100644
index 254afeb0a..000000000
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ /dev/null
@@ -1,779 +0,0 @@
-.propertiesView {
-
-    background-color: rgb(205, 205, 205);
-    height: 100%;
-    font-family: "Noto Sans";
-    cursor: auto;
-
-    overflow-x: hidden;
-    overflow-y: scroll;
-
-    .propertiesView-title {
-        background-color: rgb(159, 159, 159);
-        text-align: center;
-        padding-top: 12px;
-        padding-bottom: 12px;
-        display: flex;
-        font-size: 18px;
-        font-weight: bold;
-        justify-content: center;
-
-        .propertiesView-title-icon {
-            width: 20px;
-            height: 20px;
-            padding-left: 38px;
-            margin-top: -5px;
-            align-items: flex-end;
-            margin-left: auto;
-            margin-right: 10px;
-
-            &:hover {
-                color: grey;
-                cursor: pointer;
-            }
-
-        }
-
-    }
-
-    .propertiesView-name {
-        border-bottom: 1px solid black;
-        padding: 8.5px;
-        font-size: 12.5px;
-
-        &:hover {
-            cursor: text;
-        }
-    }
-
-    .propertiesView-settings {
-        border-bottom: 1px solid black;
-        //padding: 8.5px;
-        font-size: 12.5px;
-        font-weight: bold;
-
-        .propertiesView-settings-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-settings-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-settings-content {
-            margin-left: 12px;
-            padding-bottom: 10px;
-            padding-top: 8px;
-        }
-
-    }
-
-    .propertiesView-sharing {
-        border-bottom: 1px solid black;
-        //padding: 8.5px;
-
-        .propertiesView-sharing-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-sharing-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-sharing-content {
-            font-size: 10px;
-            padding: 10px;
-            margin-left: 5px;
-
-            .propertiesView-acls-checkbox {
-                float: right;
-                height: 20px;
-                margin-top: -20px;
-                margin-right: -15;
-
-                .propertiesView-acls-checkbox-text {
-                    font-size: 7px;
-                    margin-top: -10px;
-                    margin-left: 6px;
-                }
-            }
-
-            .change-buttons {
-                display: flex;
-
-                button {
-                    width: 5;
-                    height: 5;
-                }
-
-                input {
-                    width: 100%;
-                }
-            }
-        }
-    }
-
-    .propertiesView-appearance {
-        border-bottom: 1px solid black;
-        //padding: 8.5px;
-
-        .propertiesView-appearance-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-appearance-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-appearance-content {
-            font-size: 10px;
-            padding: 10px;
-            margin-left: 5px;
-        }
-    }
-
-    .propertiesView-transform {
-        border-bottom: 1px solid black;
-        //padding: 8.5px;
-
-        .propertiesView-transform-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-transform-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-transform-content {
-            font-size: 10px;
-            padding: 10px;
-            margin-left: 5px;
-        }
-    }
-
-    .notify-button {
-        padding: 2px;
-        width: 12px;
-        height: 12px;
-        background-color: black;
-        border-radius: 10px;
-        padding-left: 2px;
-        padding-right: 2px;
-        margin-top: 2px;
-        margin-left: 3px;
-
-        .notify-button-icon {
-            width: 6px;
-            height: 6.5px;
-            margin-left: .5px;
-        }
-
-        &:hover {
-            background-color: rgb(158, 158, 158);
-            cursor: pointer;
-        }
-    }
-
-    .expansion-button-icon {
-        width: 11px;
-        height: 11px;
-        color: black;
-        margin-left: 27px;
-
-        &:hover {
-            color: rgb(131, 131, 131);
-            cursor: pointer;
-        }
-    }
-
-    .propertiesView-sharingTable {
-
-        // whatever's commented out - add it back in when adding the buttons
-
-        // border: 1.5px solid black;
-        border: 1px solid black;
-        padding: 5px; // remove when adding buttons
-        border-radius: 6px; // remove when adding buttons
-        margin-right: 10px; // remove when adding buttons
-        // width: 100%;
-        // display: inline-table;
-        background-color: #ececec;
-        max-height: 130px;
-        overflow-y: scroll;
-        width: 92%;
-
-        .propertiesView-sharingTable-item {
-
-            display: flex;
-            // padding: 5px;
-            padding: 3px;
-            align-items: center;
-            border-bottom: 0.5px solid grey;
-
-            &:hover .propertiesView-sharingTable-item-name {
-                overflow-x: unset;
-                white-space: unset;
-                overflow-wrap: break-word;
-            }
-
-            .propertiesView-sharingTable-item-name {
-                font-weight: bold;
-                width: 95px;
-                overflow-x: hidden;
-                display: inline-block;
-                text-overflow: ellipsis;
-                white-space: nowrap;
-            }
-
-            .propertiesView-sharingTable-item-permission {
-                display: flex;
-                align-items: flex-end;
-                margin-left: auto;
-
-                .permissions-select {
-                    border: none;
-                    background-color: inherit;
-                    width: 75px;
-                    //text-align: justify; // for Edge
-                    //text-align-last: end;
-
-                    &:hover {
-                        cursor: pointer;
-                    }
-                }
-            }
-
-            &:last-child {
-                border-bottom: none;
-            }
-        }
-    }
-
-    .propertiesView-fields {
-        border-bottom: 1px solid black;
-        //padding: 8.5px;
-
-        .propertiesView-fields-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-fields-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-
-        }
-
-        .propertiesView-fields-checkbox {
-            float: right;
-            height: 20px;
-            margin-top: -9px;
-
-            .propertiesView-fields-checkbox-text {
-                font-size: 7px;
-                margin-top: -10px;
-                margin-left: 6px;
-            }
-        }
-
-        .propertiesView-fields-content {
-            font-size: 10px;
-            margin-left: 2px;
-            padding: 10px;
-
-            &:hover {
-                cursor: pointer;
-            }
-        }
-    }
-
-    .field {
-        display: flex;
-        font-size: 7px;
-        background-color: #e8e8e8;
-        padding-right: 3px;
-        border: 0.5px solid grey;
-        border-radius: 5px;
-        padding-left: 3px;
-    }
-
-    .uneditable-field {
-        display: flex;
-        overflow-y: visible;
-        margin-bottom: 2px;
-
-        &:hover {
-            cursor: auto;
-        }
-    }
-    .propertiesView-contexts {
-
-        .propertiesView-contexts-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-contexts-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-contexts-content {
-            overflow: hidden;
-            padding: 10px;
-        }
-
-    }
-
-    .propertiesView-layout {
-
-        .propertiesView-layout-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-layout-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-layout-content {
-            overflow: hidden;
-            padding: 10px;
-        }
-
-    }
-
-    .propertiesView-presTrails {
-        border-bottom: 1px solid black;
-        //padding: 8.5px;
-
-        .propertiesView-presTrails-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-presTrails-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-presTrails-content {
-            font-size: 10px;
-            padding: 10px;
-            margin-left: 5px;
-        }
-    }
-}
-
-.inking-button {
-
-    display: flex;
-
-    .inking-button-points {
-        background-color: #333333;
-        padding: 7px;
-        border-radius: 7px;
-        margin-right: 32px;
-        width: 32;
-        height: 32;
-        padding-top: 9px;
-        margin-left: 18px;
-
-        &:hover {
-            background: rgb(131, 131, 131);
-            transform: scale(1.05);
-            cursor: pointer;
-        }
-    }
-
-    .inking-button-lock {
-        background-color: #333333;
-        padding: 7px;
-        border-radius: 7px;
-        margin-right: 32px;
-        width: 32;
-        height: 32;
-        padding-top: 9px;
-        padding-left: 10px;
-
-        &:hover {
-            background: rgb(131, 131, 131);
-            transform: scale(1.05);
-            cursor: pointer;
-        }
-    }
-
-    .inking-button-rotate {
-        background-color: #333333;
-        padding: 7px;
-        border-radius: 7px;
-        width: 32;
-        height: 32;
-        padding-top: 9px;
-        padding-left: 10px;
-
-        &:hover {
-            background: rgb(131, 131, 131);
-            transform: scale(1.05);
-            cursor: pointer;
-        }
-    }
-}
-
-.inputBox-duo {
-    display: flex;
-}
-
-.inputBox {
-
-    margin-top: 10px;
-    display: flex;
-    height: 19px;
-    margin-right: 15px;
-
-    .inputBox-title {
-        font-size: 12px;
-        padding-right: 5px;
-    }
-
-    .inputBox-input {
-        font-size: 10px;
-        width: 50px;
-        margin-right: 1px;
-        border-radius: 3px;
-
-        &:hover {
-            cursor: pointer;
-        }
-    }
-
-    .inputBox-button {
-
-        .inputBox-button-up {
-            background-color: #333333;
-            height: 9px;
-            padding-left: 3px;
-            padding-right: 3px;
-            padding-top: 1px;
-            padding-bottom: 1px;
-            border-radius: 1.5px;
-
-            &:hover {
-                background: rgb(131, 131, 131);
-                transform: scale(1.05);
-                cursor: pointer;
-            }
-        }
-
-        .inputBox-button-down {
-            background-color: #333333;
-            height: 9px;
-            padding-left: 3px;
-            padding-right: 3px;
-            padding-top: 1px;
-            padding-bottom: 1px;
-            border-radius: 1.5px;
-
-            &:hover {
-                background: rgb(131, 131, 131);
-                transform: scale(1.05);
-                cursor: pointer;
-            }
-        }
-
-    }
-}
-
-.color-palette {
-    width: 160px;
-    height: 360;
-}
-
-.strokeAndFill {
-    display: flex;
-    margin-top: 10px;
-
-    .fill {
-        margin-right: 40px;
-        display: flex;
-        padding-bottom: 7px;
-        margin-left: 35px;
-
-        .fill-title {
-            font-size: 12px;
-            margin-right: 2px;
-        }
-
-        .fill-button {
-            padding-top: 2px;
-            margin-top: -1px;
-        }
-    }
-
-    .stroke {
-        display: flex;
-
-        .stroke-title {
-            font-size: 12px;
-        }
-
-        .stroke-button {
-            padding-top: 2px;
-            margin-left: 2px;
-            margin-top: -1px;
-        }
-    }
-}
-
-.propertiesView-presSelected {
-    border-top: solid 1px darkgrey;
-    width: 100%;
-    padding-top: 5px;
-    font-family: Roboto;
-    font-weight: 500;
-    display: inline-flex;
-
-    .propertiesView-selectedList {
-        border-left: solid 1px darkgrey;
-        margin-left: 10px;
-        padding-left: 5px;
-
-        .selectedList-items {
-            font-size: 12;
-            font-weight: 300;
-            margin-top: 1;
-        }
-    }
-}
-
-.widthAndDash {
-
-    .width {
-        .width-top {
-            display: flex;
-
-            .width-title {
-                font-size: 12;
-                margin-right: 20px;
-                margin-left: 35px;
-                text-align: center;
-            }
-
-            .width-input {
-                margin-right: 30px;
-                margin-top: -10px;
-            }
-        }
-
-        .width-range {
-            margin-right: 1px;
-            margin-bottom: 6;
-        }
-    }
-
-    .arrows {
-
-        display: flex;
-        margin-bottom: 3px;
-        margin-left: 4px;
-
-        .arrows-head {
-
-            display: flex;
-            margin-right: 35px;
-
-            .arrows-head-title {
-                font-size: 10;
-            }
-
-            .arrows-head-input {
-                margin-left: 6px;
-                margin-top: 2px;
-            }
-        }
-
-        .arrows-tail {
-            display: flex;
-
-            .arrows-tail-title {
-                font-size: 10;
-            }
-
-            .arrows-tail-input {
-                margin-left: 6px;
-                margin-top: 2px;
-            }
-        }
-    }
-
-    .dashed {
-
-        display: flex;
-        margin-left: 64px;
-        margin-bottom: 6px;
-
-        .dashed-title {
-            font-size: 10;
-        }
-
-        .dashed-input {
-            margin-left: 6px;
-            margin-top: 2px;
-        }
-    }
-}
-
-.editable-title {
-    border: none;
-    padding: 6px;
-    padding-bottom: 2px;
-    background: #eeeeee;
-    border-top: 1px solid;
-    border-left: 1px solid;
-
-    &:hover {
-        border: 0.75px solid rgb(122, 28, 28);
-    }
-}
-
-
-.properties-flyout {
-    grid-column: 2/4;
-}
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
deleted file mode 100644
index 560f09931..000000000
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ /dev/null
@@ -1,1090 +0,0 @@
-import React = require("react");
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Checkbox, Tooltip } from "@material-ui/core";
-import { action, computed, observable } from "mobx";
-import { observer } from "mobx-react";
-import { ColorState, SketchPicker } from "react-color";
-import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, DataSym, Doc, Field, HeightSym, WidthSym } from "../../../../fields/Doc";
-import { Id } from "../../../../fields/FieldSymbols";
-import { InkField } from "../../../../fields/InkField";
-import { ComputedField } from "../../../../fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../../fields/Types";
-import { GetEffectiveAcl, SharingPermissions } from "../../../../fields/util";
-import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnZero } from "../../../../Utils";
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { DocumentManager } from "../../../util/DocumentManager";
-import { SelectionManager } from "../../../util/SelectionManager";
-import { SharingManager } from "../../../util/SharingManager";
-import { Transform } from "../../../util/Transform";
-import { undoBatch, UndoManager } from "../../../util/UndoManager";
-import { EditableView } from "../../EditableView";
-import { ContentFittingDocumentView } from "../../nodes/ContentFittingDocumentView";
-import { KeyValueBox } from "../../nodes/KeyValueBox";
-import { PresBox } from "../../nodes/PresBox";
-import { PropertiesButtons } from "../../PropertiesButtons";
-import { CollectionDockingView } from "../CollectionDockingView";
-import { SelectorContextMenu } from "../ParentDocumentSelector";
-import { FormatShapePane } from "./FormatShapePane";
-import "./FormatShapePane.scss";
-import "./PropertiesView.scss";
-const higflyout = require("@hig/flyout");
-export const { anchorPoints } = higflyout;
-export const Flyout = higflyout.default;
-const _global = (window /* browser */ || global /* node */) as any;
-
-interface PropertiesViewProps {
-    width: number;
-    height: number;
-    renderDepth: number;
-    ScreenToLocalTransform: () => Transform;
-    onDown: (event: any) => void;
-}
-
-@observer
-export class PropertiesView extends React.Component<PropertiesViewProps> {
-    private _widthUndo?: UndoManager.Batch;
-
-    @computed get MAX_EMBED_HEIGHT() { return 200; }
-
-    @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; }
-    @computed get selectedDocumentView() {
-        if (SelectionManager.SelectedDocuments().length) {
-            return SelectionManager.SelectedDocuments()[0];
-        } else if (PresBox.Instance && PresBox.Instance._selectedArray.length) {
-            return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
-        } else { return undefined; }
-    }
-    @computed get isPres(): boolean {
-        if (this.selectedDoc?.type === DocumentType.PRES) return true;
-        return false;
-    }
-    @computed get dataDoc() { return this.selectedDoc?.[DataSym]; }
-
-    @observable layoutFields: boolean = false;
-
-    @observable openOptions: boolean = true;
-    @observable openSharing: boolean = true;
-    @observable openFields: boolean = true;
-    @observable openLayout: boolean = true;
-    @observable openContexts: boolean = true;
-    @observable openAppearance: boolean = true;
-    @observable openTransform: boolean = true;
-    // @observable selectedUser: string = "";
-    // @observable addButtonPressed: boolean = false;
-    @observable layoutDocAcls: boolean = false;
-
-    //Pres Trails booleans:
-    @observable openPresTransitions: boolean = false;
-    @observable openPresProgressivize: boolean = false;
-    @observable openAddSlide: boolean = false;
-    @observable openSlideOptions: boolean = false;
-
-    @observable inOptions: boolean = false;
-    @observable _controlBtn: boolean = false;
-    @observable _lock: boolean = false;
-
-    @computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; }
-
-    @action
-    rtfWidth = () => {
-        if (this.selectedDoc) {
-            return Math.min(this.selectedDoc?.[WidthSym](), this.props.width - 20);
-        } else {
-            return 0;
-        }
-    }
-    @action
-    rtfHeight = () => {
-        if (this.selectedDoc) {
-            return this.rtfWidth() <= this.selectedDoc?.[WidthSym]() ? Math.min(this.selectedDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
-        } else {
-            return 0;
-        }
-    }
-
-    @action
-    docWidth = () => {
-        if (this.selectedDoc) {
-            const layoutDoc = this.selectedDoc;
-            const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
-            if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.width - 20));
-            return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20;
-        } else {
-            return 0;
-        }
-    }
-
-    @action
-    docHeight = () => {
-        if (this.selectedDoc && this.dataDoc) {
-            const layoutDoc = this.selectedDoc;
-            return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => {
-                const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
-                if (aspect) return this.docWidth() * aspect;
-                return layoutDoc._fitWidth ? (!this.dataDoc._nativeHeight ? NumCast(this.props.height) :
-                    Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
-                        NumCast(this.props.height)))) :
-                    NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
-            })()));
-        } else {
-            return 0;
-        }
-    }
-
-    @computed get expandedField() {
-        if (this.dataDoc && this.selectedDoc) {
-            const ids: { [key: string]: string } = {};
-            const docs = SelectionManager.SelectedDocuments().length < 2 ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] :
-                SelectionManager.SelectedDocuments().map(dv => this.layoutFields ? Doc.Layout(dv.layoutDoc) : dv.dataDoc);
-            docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)));
-            const rows: JSX.Element[] = [];
-            for (const key of Object.keys(ids).slice().sort()) {
-                const docvals = new Set<any>();
-                docs.forEach(doc => docvals.add(doc[key]));
-                const contents = Array.from(docvals.keys()).length > 1 ? "-multiple" : docs[0][key];
-                if (key[0] === "#") {
-                    rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "2px" }} key={key}>
-                        <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key}</span>
-                    &nbsp;
-                </div>);
-                } else {
-                    const contentElement = <EditableView key="editableView"
-                        contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
-                        height={13}
-                        fontSize={10}
-                        GetValue={() => contents !== undefined ? Field.toString(contents as Field) : "null"}
-                        SetValue={(value: string) => { docs.map(doc => KeyValueBox.SetField(doc, key, value, true)); return true; }}
-                    />;
-                    rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
-                        <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
-                        &nbsp;
-                        {contentElement}
-                    </div>);
-                }
-            }
-            rows.push(<div className="field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
-                <EditableView
-                    key="editableView"
-                    contents={"add key:value or #tags"}
-                    height={13}
-                    fontSize={10}
-                    GetValue={() => ""}
-                    SetValue={this.setKeyValue} />
-            </div>);
-            return rows;
-        }
-    }
-
-    @computed get noviceFields() {
-        if (this.dataDoc) {
-            const ids: { [key: string]: string } = {};
-            const docs = SelectionManager.SelectedDocuments().length < 2 ? [this.dataDoc] : SelectionManager.SelectedDocuments().map(dv => dv.dataDoc);
-            docs.forEach(doc => Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)));
-            const rows: JSX.Element[] = [];
-            const noviceReqFields = ["author", "creationDate"];
-            const noviceLayoutFields = ["_curPage"];
-            const noviceKeys = [...Array.from(Object.keys(ids)).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("ACL") && key !== "UseCors")),
-            ...noviceReqFields, ...noviceLayoutFields];
-            for (const key of noviceKeys.sort()) {
-                const docvals = new Set<any>();
-                docs.forEach(doc => docvals.add(doc[key]));
-                const contents = Array.from(docvals.keys()).length > 1 ? "-multiple" : docs[0][key];
-                if (key[0] === "#") {
-                    rows.push(<div className="uneditable-field" key={key}>
-                        <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key}</span>
-                        &nbsp;
-                    </div>);
-                } else if (contents !== undefined) {
-                    const value = Field.toString(contents as Field);
-                    if (noviceReqFields.includes(key) || key.indexOf("lastModified") !== -1) {
-                        rows.push(<div className="uneditable-field" key={key}>
-                            <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ": "}</span>
-                            <div style={{ whiteSpace: "nowrap", overflowX: "hidden" }}>{value}</div>
-                        </div>);
-                    } else {
-                        const contentElement = <EditableView key="editableView"
-                            contents={value}
-                            height={13}
-                            fontSize={10}
-                            GetValue={() => contents !== undefined ? Field.toString(contents as Field) : "null"}
-                            SetValue={(value: string) => { docs.map(doc => KeyValueBox.SetField(doc, key, value, true)); return true; }}
-                        />;
-
-                        rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
-                            <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
-                        &nbsp;
-                        {contentElement}
-                        </div>);
-                    }
-                }
-            }
-            rows.push(<div className="field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
-                <EditableView
-                    key="editableView"
-                    contents={"add key:value or #tags"}
-                    height={13}
-                    fontSize={10}
-                    GetValue={() => ""}
-                    SetValue={this.setKeyValue} />
-            </div>);
-            return rows;
-        }
-    }
-
-    @undoBatch
-    setKeyValue = (value: string) => {
-        const docs = SelectionManager.SelectedDocuments().length < 2 && this.selectedDoc ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : SelectionManager.SelectedDocuments().map(dv => this.layoutFields ? dv.layoutDoc : dv.dataDoc);
-        docs.forEach(doc => {
-            if (value.indexOf(":") !== -1) {
-                const newVal = value[0].toUpperCase() + value.substring(1, value.length);
-                KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
-                return true;
-            } else if (value[0] === "#") {
-                const newVal = value + `:'${value}'`;
-                KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
-                return true;
-            }
-        });
-        return false;
-    }
-
-    @observable transform: Transform = Transform.Identity();
-    getTransform = () => this.transform;
-    propertiesDocViewRef = (ref: HTMLDivElement) => {
-        const observer = new _global.ResizeObserver(action((entries: any) => {
-            const cliRect = ref.getBoundingClientRect();
-            this.transform = new Transform(-cliRect.x, -cliRect.y, 1);
-        }));
-        ref && observer.observe(ref);
-    }
-
-    @computed get contexts() {
-        return !this.selectedDoc ? (null) : <SelectorContextMenu Document={this.selectedDoc} hideTitle={true} addDocTab={(doc, where) => CollectionDockingView.AddRightSplit(doc)} />;
-    }
-
-    previewBackground = () => "lightgrey";
-    @computed get layoutPreview() {
-        if (SelectionManager.SelectedDocuments().length > 1) {
-            return "-- multiple selected --";
-        }
-        if (this.selectedDoc) {
-            const layoutDoc = Doc.Layout(this.selectedDoc);
-            const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight;
-            const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth;
-            return <div ref={this.propertiesDocViewRef} style={{ pointerEvents: "none", display: "inline-block", height: panelHeight() }} key={this.selectedDoc[Id]}>
-                <ContentFittingDocumentView
-                    Document={layoutDoc}
-                    DataDoc={this.dataDoc}
-                    LibraryPath={emptyPath}
-                    renderDepth={this.props.renderDepth + 1}
-                    rootSelected={returnFalse}
-                    treeViewDoc={undefined}
-                    backgroundColor={this.previewBackground}
-                    fitToBox={true}
-                    FreezeDimensions={true}
-                    NativeWidth={layoutDoc.type ===
-                        StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero}
-                    NativeHeight={layoutDoc.type ===
-                        StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : returnZero}
-                    PanelWidth={panelWidth}
-                    PanelHeight={panelHeight}
-                    focus={returnFalse}
-                    ScreenToLocalTransform={this.getTransform}
-                    docFilters={returnEmptyFilter}
-                    searchFilterDocs={returnEmptyDoclist}
-                    ContainingCollectionDoc={undefined}
-                    ContainingCollectionView={undefined}
-                    addDocument={returnFalse}
-                    moveDocument={undefined}
-                    removeDocument={returnFalse}
-                    parentActive={() => false}
-                    whenActiveChanged={emptyFunction}
-                    addDocTab={returnFalse}
-                    pinToPres={emptyFunction}
-                    bringToFront={returnFalse}
-                    ContentScaling={returnOne}
-                    dontRegisterView={true}
-                    dropAction={undefined}
-                />
-            </div>;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Handles the changing of a user's permissions from the permissions panel.
-     */
-    @undoBatch
-    changePermissions = (e: any, user: string) => {
-        SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, this.selectedDoc!);
-    }
-
-    /**
-     * @returns the options for the permissions dropdown.
-     */
-    getPermissionsSelect(user: string, permission: string) {
-        return <select className="permissions-select"
-            value={permission}
-            onChange={e => this.changePermissions(e, user)}>
-            {Object.values(SharingPermissions).map(permission => {
-                return (
-                    <option key={permission} value={permission}>
-                        {permission}
-                    </option>);
-            })}
-        </select>;
-    }
-
-    /**
-     * @returns the notification icon. On clicking, it should notify someone of a document been shared with them.
-     */
-    @computed get notifyIcon() {
-        return <Tooltip title={<div className="dash-tooltip">Notify with message</div>}>
-            <div className="notify-button">
-                <FontAwesomeIcon className="notify-button-icon" icon="bell" color="white" size="sm" />
-            </div>
-        </Tooltip>;
-    }
-
-    /**
-     * ... next to the owner that opens the main SharingManager interface on click.
-     */
-    @computed get expansionIcon() {
-        return <Tooltip title={<div className="dash-tooltip">{"Show more permissions"}</div>}>
-            <div className="expansion-button" onPointerDown={() => {
-                if (this.selectedDocumentView || this.selectedDoc) {
-                    SharingManager.Instance.open(this.selectedDocumentView?.props.Document === this.selectedDocumentView ? this.selectedDocumentView : undefined, this.selectedDoc);
-                }
-            }}>
-                <FontAwesomeIcon className="expansion-button-icon" icon="ellipsis-h" color="black" size="sm" />
-            </div>
-        </Tooltip>;
-    }
-
-    /**
-     * @returns a row of the permissions panel
-     */
-    sharingItem(name: string, effectiveAcl: symbol, permission: string) {
-        return <div className="propertiesView-sharingTable-item" key={name + permission}
-        // style={{ backgroundColor: this.selectedUser === name ? "#bcecfc" : "" }}
-        // onPointerDown={action(() => this.selectedUser = this.selectedUser === name ? "" : name)}
-        >
-            <div className="propertiesView-sharingTable-item-name" style={{ width: name !== "Me" ? "85px" : "80px" }}> {name} </div>
-            {/* {name !== "Me" ? this.notifyIcon : null} */}
-            <div className="propertiesView-sharingTable-item-permission">
-                {effectiveAcl === AclAdmin && permission !== "Owner" ? this.getPermissionsSelect(name, permission) : permission}
-                {permission === "Owner" ? this.expansionIcon : null}
-            </div>
-        </div>;
-    }
-
-    /**
-     * @returns the sharing and permissiosn panel.
-     */
-    @computed get sharingTable() {
-        const AclMap = new Map<symbol, string>([
-            [AclPrivate, SharingPermissions.None],
-            [AclReadonly, SharingPermissions.View],
-            [AclAddonly, SharingPermissions.Add],
-            [AclEdit, SharingPermissions.Edit],
-            [AclAdmin, SharingPermissions.Admin]
-        ]);
-
-        const target = this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym];
-
-        const effectiveAcl = GetEffectiveAcl(target);
-        const tableEntries = [];
-
-        // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
-        if (target[AclSym]) {
-            for (const [key, value] of Object.entries(target[AclSym])) {
-                const name = key.substring(4).replace("_", ".");
-                if (name !== Doc.CurrentUserEmail && name !== target.author && name !== "Public"/* && sidebarUsersDisplayed![name] !== false*/) {
-                    tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value as symbol)!));
-                }
-            }
-        }
-
-        //     if (Doc.UserDoc().sidebarUsersDisplayed) {
-        //         for (const [name, value] of Object.entries(sidebarUsersDisplayed!)) {
-        //             if (value === true && !this.selectedDoc![`ACL-${name.substring(8).replace(".", "_")}`]) tableEntries.push(this.sharingItem(name.substring(8), effectiveAcl, SharingPermissions.None));
-        //         }
-        //     }
-        // })
-
-        // shifts the current user, owner, public to the top of the doc.
-        tableEntries.unshift(this.sharingItem("Public", effectiveAcl, (AclMap.get(target[AclSym]?.["ACL-Public"]) || SharingPermissions.None)));
-        tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === target.author ? "Owner" : AclMap.get(effectiveAcl)!));
-        if (Doc.CurrentUserEmail !== target.author) tableEntries.unshift(this.sharingItem(StrCast(target.author), effectiveAcl, "Owner"));
-
-        return <div className="propertiesView-sharingTable">
-            {tableEntries}
-        </div>;
-    }
-
-    @computed get fieldsCheckbox() {
-        return <Checkbox
-            color="primary"
-            onChange={this.toggleCheckbox}
-            checked={this.layoutFields}
-        />;
-    }
-
-    @action
-    toggleCheckbox = () => {
-        this.layoutFields = !this.layoutFields;
-    }
-
-    @computed get editableTitle() {
-        const titles = new Set<string>();
-        SelectionManager.SelectedDocuments().forEach(dv => titles.add(StrCast(dv.rootDoc.title)));
-        const title = Array.from(titles.keys()).length > 1 ? "--multiple selected--" : StrCast(this.selectedDoc?.title);
-        return <div className="editable-title"><EditableView
-            key="editableView"
-            contents={title}
-            height={25}
-            fontSize={14}
-            GetValue={() => title}
-            SetValue={this.setTitle} /> </div>;
-    }
-
-    @undoBatch
-    @action
-    setTitle = (value: string) => {
-        if (SelectionManager.SelectedDocuments().length > 1) {
-            SelectionManager.SelectedDocuments().map(dv => Doc.SetInPlace(dv.rootDoc, "title", value, true));
-            return true;
-        } else if (this.dataDoc) {
-            if (this.selectedDoc) Doc.SetInPlace(this.selectedDoc, "title", value, true);
-            else KeyValueBox.SetField(this.dataDoc, "title", value, true);
-            return true;
-        }
-        return false;
-    }
-
-
-    @undoBatch
-    @action
-    rotate = (angle: number) => {
-        const _centerPoints: { X: number, Y: number }[] = [];
-        if (this.selectedDoc) {
-            const doc = this.selectedDoc;
-            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
-                const ink = Cast(doc.data, InkField)?.inkData;
-                if (ink) {
-                    const xs = ink.map(p => p.X);
-                    const ys = ink.map(p => p.Y);
-                    const left = Math.min(...xs);
-                    const top = Math.min(...ys);
-                    const right = Math.max(...xs);
-                    const bottom = Math.max(...ys);
-                    _centerPoints.push({ X: left, Y: top });
-                }
-            }
-
-            var index = 0;
-            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
-                doc.rotation = Number(doc.rotation) + Number(angle);
-                const inks = Cast(doc.data, InkField)?.inkData;
-                if (inks) {
-                    const newPoints: { X: number, Y: number }[] = [];
-                    inks.forEach(ink => {
-                        const newX = Math.cos(angle) * (ink.X - _centerPoints[index].X) - Math.sin(angle) * (ink.Y - _centerPoints[index].Y) + _centerPoints[index].X;
-                        const newY = Math.sin(angle) * (ink.X - _centerPoints[index].X) + Math.cos(angle) * (ink.Y - _centerPoints[index].Y) + _centerPoints[index].Y;
-                        newPoints.push({ X: newX, Y: newY });
-                    });
-                    doc.data = new InkField(newPoints);
-                    const xs = newPoints.map(p => p.X);
-                    const ys = newPoints.map(p => p.Y);
-                    const left = Math.min(...xs);
-                    const top = Math.min(...ys);
-                    const right = Math.max(...xs);
-                    const bottom = Math.max(...ys);
-
-                    doc._height = (bottom - top);
-                    doc._width = (right - left);
-                }
-                index++;
-            }
-        }
-    }
-
-
-
-    @computed
-    get controlPointsButton() {
-        return <div className="inking-button">
-            <Tooltip title={<div className="dash-tooltip">{"Edit points"}</div>}>
-                <div className="inking-button-points" onPointerDown={action(() => FormatShapePane.Instance._controlBtn = !FormatShapePane.Instance._controlBtn)} style={{ backgroundColor: FormatShapePane.Instance._controlBtn ? "black" : "" }}>
-                    <FontAwesomeIcon icon="bezier-curve" color="white" size="lg" />
-                </div>
-            </Tooltip>
-            <Tooltip title={<div className="dash-tooltip">{FormatShapePane.Instance._lock ? "Unlock ratio" : "Lock ratio"}</div>}>
-                <div className="inking-button-lock" onPointerDown={action(() => FormatShapePane.Instance._lock = !FormatShapePane.Instance._lock)} >
-                    <FontAwesomeIcon icon={FormatShapePane.Instance._lock ? "lock" : "unlock"} color="white" size="lg" />
-                </div>
-            </Tooltip>
-            <Tooltip title={<div className="dash-tooltip">{"Rotate 90˚"}</div>}>
-                <div className="inking-button-rotate" onPointerDown={action(() => this.rotate(Math.PI / 2))}>
-                    <FontAwesomeIcon icon="undo" color="white" size="lg" />
-                </div>
-            </Tooltip>
-        </div>;
-    }
-
-    inputBox = (key: string, value: any, setter: (val: string) => {}, title: string) => {
-        return <div className="inputBox"
-            style={{
-                marginRight: title === "X:" ? "19px" : "",
-                marginLeft: title === "∠:" ? "39px" : ""
-            }}>
-            <div className="inputBox-title"> {title} </div>
-            <input className="inputBox-input"
-                type="text" value={value}
-                onChange={e => {
-                    setter(e.target.value);
-                }}
-                onKeyPress={e => {
-                    e.stopPropagation();
-                }} />
-            <div className="inputBox-button">
-                <div className="inputBox-button-up" key="up2"
-                    onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))} >
-                    <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
-                </div>
-                <div className="inputbox-Button-down" key="down2"
-                    onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} >
-                    <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
-                </div>
-            </div>
-        </div>;
-    }
-
-    inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => {
-        return <div className="inputBox-duo">
-            {this.inputBox(key, value, setter, title1)}
-            {title2 === "" ? (null) : this.inputBox(key2, value2, setter2, title2)}
-        </div>;
-    }
-
-    @action
-    upDownButtons = (dirs: string, field: string) => {
-        switch (field) {
-            case "rot": this.rotate((dirs === "up" ? .1 : -.1)); break;
-            // case "rot": this.selectedInk?.forEach(i => i.rootDoc.rotation = NumCast(i.rootDoc.rotation) + (dirs === "up" ? 0.1 : -0.1)); break;
-            case "Xps": this.selectedDoc && (this.selectedDoc.x = NumCast(this.selectedDoc?.x) + (dirs === "up" ? 10 : -10)); break;
-            case "Yps": this.selectedDoc && (this.selectedDoc.y = NumCast(this.selectedDoc?.y) + (dirs === "up" ? 10 : -10)); break;
-            case "stk": this.selectedDoc && (this.selectedDoc.strokeWidth = NumCast(this.selectedDoc?.strokeWidth) + (dirs === "up" ? .1 : -.1)); break;
-            case "wid":
-                const oldWidth = NumCast(this.selectedDoc?._width);
-                const oldHeight = NumCast(this.selectedDoc?._height);
-                const oldX = NumCast(this.selectedDoc?.x);
-                const oldY = NumCast(this.selectedDoc?.y);
-                this.selectedDoc && (this.selectedDoc._width = oldWidth + (dirs === "up" ? 10 : - 10));
-                FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) / oldWidth * NumCast(this.selectedDoc?._height)));
-                const doc = this.selectedDoc;
-                if (doc?.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
-                    const ink = Cast(doc.data, InkField)?.inkData;
-                    if (ink) {
-                        const newPoints: { X: number, Y: number }[] = [];
-                        for (var j = 0; j < ink.length; j++) {
-                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
-                            const newX = (NumCast(doc.x) - oldX) + (ink[j].X * NumCast(doc._width)) / oldWidth;
-                            const newY = (NumCast(doc.y) - oldY) + (ink[j].Y * NumCast(doc._height)) / oldHeight;
-                            newPoints.push({ X: newX, Y: newY });
-                        }
-                        doc.data = new InkField(newPoints);
-                    }
-                }
-                break;
-            case "hgt":
-                const oWidth = NumCast(this.selectedDoc?._width);
-                const oHeight = NumCast(this.selectedDoc?._height);
-                const oX = NumCast(this.selectedDoc?.x);
-                const oY = NumCast(this.selectedDoc?.y);
-                this.selectedDoc && (this.selectedDoc._height = oHeight + (dirs === "up" ? 10 : - 10));
-                FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) / oHeight * NumCast(this.selectedDoc?._width)));
-                const docu = this.selectedDoc;
-                if (docu?.type === DocumentType.INK && docu.x && docu.y && docu._height && docu._width) {
-                    const ink = Cast(docu.data, InkField)?.inkData;
-                    if (ink) {
-                        const newPoints: { X: number, Y: number }[] = [];
-                        for (var j = 0; j < ink.length; j++) {
-                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
-                            const newX = (NumCast(docu.x) - oX) + (ink[j].X * NumCast(docu._width)) / oWidth;
-                            const newY = (NumCast(docu.y) - oY) + (ink[j].Y * NumCast(docu._height)) / oHeight;
-                            newPoints.push({ X: newX, Y: newY });
-                        }
-                        docu.data = new InkField(newPoints);
-                    }
-                }
-                break;
-        }
-    }
-
-    getField(key: string) {
-        //if (this.selectedDoc) {
-        return Field.toString(this.selectedDoc?.[key] as Field);
-        // } else {
-        //     return undefined as Opt<string>;
-        // }
-    }
-
-    @computed get shapeXps() { return this.getField("x"); }
-    @computed get shapeYps() { return this.getField("y"); }
-    @computed get shapeRot() { return this.getField("rotation"); }
-    @computed get shapeHgt() { return this.getField("_height"); }
-    @computed get shapeWid() { return this.getField("_width"); }
-    set shapeXps(value) { this.selectedDoc && (this.selectedDoc.x = Number(value)); }
-    set shapeYps(value) { this.selectedDoc && (this.selectedDoc.y = Number(value)); }
-    set shapeRot(value) { this.selectedDoc && (this.selectedDoc.rotation = Number(value)); }
-    set shapeWid(value) {
-        const oldWidth = NumCast(this.selectedDoc?._width);
-        this.selectedDoc && (this.selectedDoc._width = Number(value));
-        FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) * NumCast(this.selectedDoc?._height)) / oldWidth);
-    }
-    set shapeHgt(value) {
-        const oldHeight = NumCast(this.selectedDoc?._height);
-        this.selectedDoc && (this.selectedDoc._height = Number(value));
-        FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) * NumCast(this.selectedDoc?._width)) / oldHeight);
-    }
-
-    @computed get hgtInput() { return this.inputBoxDuo("hgt", this.shapeHgt, (val: string) => { if (!isNaN(Number(val))) { this.shapeHgt = val; } return true; }, "H:", "wid", this.shapeWid, (val: string) => { if (!isNaN(Number(val))) { this.shapeWid = val; } return true; }, "W:"); }
-    @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => { if (val !== "0" && !isNaN(Number(val))) { this.shapeXps = val; } return true; }, "X:", "Yps", this.shapeYps, (val: string) => { if (val !== "0" && !isNaN(Number(val))) { this.shapeYps = val; } return true; }, "Y:"); }
-    @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { if (!isNaN(Number(val))) { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; } return true; }, "∠:", "rot", this.shapeRot, (val: string) => { if (!isNaN(Number(val))) { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; } return true; }, ""); }
-
-
-    @observable private _fillBtn = false;
-    @observable private _lineBtn = false;
-
-    private _lastFill = "#D0021B";
-    private _lastLine = "#D0021B";
-    private _lastDash: any = "2";
-
-    @computed get colorFil() { const ccol = this.getField("fillColor") || ""; ccol && (this._lastFill = ccol); return ccol; }
-    @computed get colorStk() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; }
-    set colorFil(value) { value && (this._lastFill = value); this.selectedDoc && (this.selectedDoc.fillColor = value ? value : undefined); }
-    set colorStk(value) { value && (this._lastLine = value); this.selectedDoc && (this.selectedDoc.color = value ? value : undefined); }
-
-    colorButton(value: string, type: string, setter: () => {}) {
-        // return <div className="properties-flyout" onPointerEnter={e => this.changeScrolling(false)}
-        //     onPointerLeave={e => this.changeScrolling(true)}>
-        //     <Flyout anchorPoint={anchorPoints.LEFT_TOP}
-        //         content={type === "fill" ? this.fillPicker : this.linePicker}>
-        return <div className="color-button" key="color" onPointerDown={undoBatch(action(e => setter()))}>
-            <div className="color-button-preview" style={{
-                backgroundColor: value ?? "121212", width: 15, height: 15,
-                display: value === "" || value === "transparent" ? "none" : ""
-            }} />
-            {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -14 }}>☒</p> : ""}
-        </div>;
-        //     </Flyout>
-        // </div>;
-
-    }
-
-    @undoBatch
-    @action
-    switchStk = (color: ColorState) => {
-        const val = String(color.hex);
-        this.colorStk = val;
-        return true;
-    }
-    @undoBatch
-    @action
-    switchFil = (color: ColorState) => {
-        const val = String(color.hex);
-        this.colorFil = val;
-        return true;
-    }
-
-    colorPicker(setter: (color: string) => {}, type: string) {
-        return <SketchPicker onChange={type === "stk" ? this.switchStk : this.switchFil}
-            presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
-                '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
-                '#FFFFFF', '#f1efeb', 'transparent']}
-            color={type === "stk" ? this.colorStk : this.colorFil} />;
-    }
-
-    @computed get fillButton() { return this.colorButton(this.colorFil, "fill", () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; return true; }); }
-    @computed get lineButton() { return this.colorButton(this.colorStk, "line", () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; return true; }); }
-
-    @computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color, "fil"); }
-    @computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color, "stk"); }
-
-    @computed get strokeAndFill() {
-        return <div>
-            <div key="fill" className="strokeAndFill">
-                <div className="fill">
-                    <div className="fill-title">Fill:</div>
-                    <div className="fill-button">{this.fillButton}</div>
-                </div>
-                <div className="stroke">
-                    <div className="stroke-title"> Stroke: </div>
-                    <div className="stroke-button">{this.lineButton}</div>
-                </div>
-            </div>
-            {this._fillBtn ? this.fillPicker : ""}
-            {this._lineBtn ? this.linePicker : ""}
-        </div>;
-    }
-
-    @computed get solidStk() { return this.selectedDoc?.color && (!this.selectedDoc?.strokeDash || this.selectedDoc?.strokeDash === "0") ? true : false; }
-    @computed get dashdStk() { return this.selectedDoc?.strokeDash || ""; }
-    @computed get unStrokd() { return this.selectedDoc?.color ? true : false; }
-    @computed get widthStk() { return this.getField("strokeWidth") || "1"; }
-    @computed get markHead() { return this.getField("strokeStartMarker") || ""; }
-    @computed get markTail() { return this.getField("strokeEndMarker") || ""; }
-    set solidStk(value) { this.dashdStk = ""; this.unStrokd = !value; }
-    set dashdStk(value) {
-        value && (this._lastDash = value) && (this.unStrokd = false);
-        this.selectedDoc && (this.selectedDoc.strokeDash = value ? this._lastDash : undefined);
-    }
-    set widthStk(value) { this.selectedDoc && (this.selectedDoc.strokeWidth = Number(value)); }
-    set unStrokd(value) { this.colorStk = value ? "" : this._lastLine; }
-    set markHead(value) { this.selectedDoc && (this.selectedDoc.strokeStartMarker = value); }
-    set markTail(value) { this.selectedDoc && (this.selectedDoc.strokeEndMarker = value); }
-
-
-    @computed get stkInput() { return this.regInput("stk", this.widthStk, (val: string) => this.widthStk = val); }
-
-
-    regInput = (key: string, value: any, setter: (val: string) => {}) => {
-        return <div className="inputBox">
-            <input className="inputBox-input"
-                type="text" value={value}
-                onChange={e => setter(e.target.value)} />
-            <div className="inputBox-button">
-                <div className="inputBox-button-up" key="up2"
-                    onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))} >
-                    <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
-                </div>
-                <div className="inputbox-Button-down" key="down2"
-                    onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} >
-                    <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
-                </div>
-            </div>
-        </div>;
-    }
-
-    @computed get widthAndDash() {
-        return <div className="widthAndDash">
-            <div className="width">
-                <div className="width-top">
-                    <div className="width-title">Width:</div>
-                    <div className="width-input">{this.stkInput}</div>
-                </div>
-                <input className="width-range" type="range"
-                    defaultValue={Number(this.widthStk)} min={1} max={100}
-                    onChange={(action((e) => this.widthStk = e.target.value))}
-                    onMouseDown={(e) => { this._widthUndo = UndoManager.StartBatch("width undo"); }}
-                    onMouseUp={(e) => { this._widthUndo?.end(); this._widthUndo = undefined; }}
-                />
-            </div>
-
-            <div className="arrows">
-                <div className="arrows-head">
-                    <div className="arrows-head-title" >Arrow Head: </div>
-                    <input key="markHead" className="arrows-head-input" type="checkbox"
-                        checked={this.markHead !== ""}
-                        onChange={undoBatch(action(() => this.markHead = this.markHead ? "" : "arrow"))} />
-                </div>
-                <div className="arrows-tail">
-                    <div className="arrows-tail-title" >Arrow End: </div>
-                    <input key="markTail" className="arrows-tail-input" type="checkbox"
-                        checked={this.markTail !== ""}
-                        onChange={undoBatch(action(() => this.markTail = this.markTail ? "" : "arrow"))} />
-                </div>
-            </div>
-            <div className="dashed">
-                <div className="dashed-title">Dashed Line:</div>
-                <input key="markHead" className="dashed-input"
-                    type="checkbox" checked={this.dashdStk === "2"}
-                    onChange={this.changeDash} />
-            </div>
-        </div>;
-    }
-
-    @undoBatch @action
-    changeDash = () => {
-        this.dashdStk = this.dashdStk === "2" ? "0" : "2";
-    }
-
-    @computed get appearanceEditor() {
-        return <div className="appearance-editor">
-            {this.widthAndDash}
-            {this.strokeAndFill}
-        </div>;
-    }
-
-    @computed get transformEditor() {
-        return <div className="transform-editor">
-            {this.controlPointsButton}
-            {this.hgtInput}
-            {this.XpsInput}
-            {this.rotInput}
-        </div>;
-    }
-
-    /**
-     * Handles adding and removing members from the sharing panel
-     */
-    // handleUserChange = (selectedUser: string, add: boolean) => {
-    //     if (!Doc.UserDoc().sidebarUsersDisplayed) Doc.UserDoc().sidebarUsersDisplayed = new Doc;
-    //     DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
-    //         sidebarUsersDisplayed![`display-${selectedUser}`] = add;
-    //         !add && runInAction(() => this.selectedUser = "");
-    //     });
-    // }
-
-    render() {
-        if (!this.selectedDoc && !this.isPres) {
-            return <div className="propertiesView" style={{ width: this.props.width }}>
-                <div className="propertiesView-title" style={{ width: this.props.width }}>
-                    No Document Selected
-                </div>
-            </div>;
-
-        } else {
-            const novice = Doc.UserDoc().noviceMode;
-
-            if (this.selectedDoc && !this.isPres) {
-                return <div className="propertiesView" style={{
-                    width: this.props.width,
-                    //overflowY: this.scrolling ? "scroll" : "visible"
-                }} >
-                    <div className="propertiesView-title" style={{ width: this.props.width }}>
-                        Properties
-                    {/* <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
-                        <FontAwesomeIcon icon="times" color="black" size="sm" />
-                    </div> */}
-                    </div>
-                    <div className="propertiesView-name">
-                        {this.editableTitle}
-                    </div>
-                    <div className="propertiesView-settings" onPointerEnter={action(() => this.inOptions = true)}
-                        onPointerLeave={action(() => this.inOptions = false)}>
-                        <div className="propertiesView-settings-title"
-                            onPointerDown={action(() => this.openOptions = !this.openOptions)}
-                            style={{ backgroundColor: this.openOptions ? "black" : "" }}>
-                            Options
-                        <div className="propertiesView-settings-title-icon">
-                                <FontAwesomeIcon icon={this.openOptions ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {!this.openOptions ? (null) :
-                            <div className="propertiesView-settings-content">
-                                <PropertiesButtons />
-                            </div>}
-                    </div>
-                    <div className="propertiesView-sharing">
-                        <div className="propertiesView-sharing-title"
-                            onPointerDown={action(() => this.openSharing = !this.openSharing)}
-                            style={{ backgroundColor: this.openSharing ? "black" : "" }}>
-                            Sharing {"&"} Permissions
-                        <div className="propertiesView-sharing-title-icon">
-                                <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {!this.openSharing ? (null) :
-                            <div className="propertiesView-sharing-content">
-                                <div className="propertiesView-acls-checkbox">
-                                    <Checkbox
-                                        color="primary"
-                                        onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)}
-                                        checked={this.layoutDocAcls}
-                                    />;
-                                    <div className="propertiesView-acls-checkbox-text">Layout</div>
-                                </div>
-                                {this.sharingTable}
-                                {/* <div className="change-buttons">
-                            <button
-                                onPointerDown={action(() => this.addButtonPressed = !this.addButtonPressed)}
-                            >
-                                <FontAwesomeIcon icon={fa.faPlus} size={"sm"} style={{ marginTop: -3, marginLeft: -3 }} />
-                            </button>
-                            <button
-                                id="sharingProperties-removeUser"
-                                onPointerDown={() => this.handleUserChange(this.selectedUser, false)}
-                                style={{ backgroundColor: this.selectedUser ? "#121721" : "#777777" }}
-                            ><FontAwesomeIcon icon={fa.faMinus} size={"sm"} style={{ marginTop: -3, marginLeft: -3 }} /></button>
-                            <button onClick={() => SharingManager.Instance.open(this.selectedDocumentView!)}><FontAwesomeIcon icon={fa.faCog} size={"sm"} style={{ marginTop: -3, marginLeft: -3 }} /></button>
-                            {this.addButtonPressed ?
-                                // <input type="text" onKeyDown={this.handleKeyPress} /> :
-                                <select onChange={e => this.handleUserChange(e.target.value, true)}>
-                                    <option selected disabled hidden>
-                                        Add users
-                                    </option>
-                                    {SharingManager.Instance.users.map(user =>
-                                        (<option value={user.user.email}>
-                                            {user.user.email}
-                                        </option>)
-                                    )}
-                                    {GroupManager.Instance.getAllGroups().map(group =>
-                                        (<option value={StrCast(group.groupName)}>
-                                            {StrCast(group.groupName)}
-                                        </option>))}
-                                </select> :
-                                null}
-                        </div> */}
-                            </div>}
-                    </div>
-
-                    {!this.isInk ? (null) :
-                        <div className="propertiesView-appearance">
-                            <div className="propertiesView-appearance-title"
-                                onPointerDown={action(() => this.openAppearance = !this.openAppearance)}
-                                style={{ backgroundColor: this.openAppearance ? "black" : "" }}>
-                                Appearance
-                            <div className="propertiesView-appearance-title-icon">
-                                    <FontAwesomeIcon icon={this.openAppearance ? "caret-down" : "caret-right"} size="lg" color="white" />
-                                </div>
-                            </div>
-                            {!this.openAppearance ? (null) :
-                                <div className="propertiesView-appearance-content">
-                                    {this.appearanceEditor}
-                                </div>}
-                        </div>}
-
-                    {this.isInk ? <div className="propertiesView-transform">
-                        <div className="propertiesView-transform-title"
-                            onPointerDown={action(() => this.openTransform = !this.openTransform)}
-                            style={{ backgroundColor: this.openTransform ? "black" : "" }}>
-                            Transform
-                        <div className="propertiesView-transform-title-icon">
-                                <FontAwesomeIcon icon={this.openTransform ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {this.openTransform ? <div className="propertiesView-transform-content">
-                            {this.transformEditor}
-                        </div> : null}
-                    </div> : null}
-
-                    <div className="propertiesView-fields">
-                        <div className="propertiesView-fields-title"
-                            onPointerDown={action(() => this.openFields = !this.openFields)}
-                            style={{ backgroundColor: this.openFields ? "black" : "" }}>
-                            Fields {"&"} Tags
-                            <div className="propertiesView-fields-title-icon">
-                                <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {!novice && this.openFields ? <div className="propertiesView-fields-checkbox">
-                            {this.fieldsCheckbox}
-                            <div className="propertiesView-fields-checkbox-text">Layout</div>
-                        </div> : null}
-                        {!this.openFields ? (null) :
-                            <div className="propertiesView-fields-content">
-                                {novice ? this.noviceFields : this.expandedField}
-                            </div>}
-                    </div>
-                    <div className="propertiesView-contexts">
-                        <div className="propertiesView-contexts-title"
-                            onPointerDown={action(() => this.openContexts = !this.openContexts)}
-                            style={{ backgroundColor: this.openContexts ? "black" : "" }}>
-                            Contexts
-                        <div className="propertiesView-contexts-title-icon">
-                                <FontAwesomeIcon icon={this.openContexts ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {this.openContexts ? <div className="propertiesView-contexts-content"  >{this.contexts}</div> : null}
-                    </div>
-                    <div className="propertiesView-layout">
-                        <div className="propertiesView-layout-title"
-                            onPointerDown={action(() => this.openLayout = !this.openLayout)}
-                            style={{ backgroundColor: this.openLayout ? "black" : "" }}>
-                            Layout
-                        <div className="propertiesView-layout-title-icon">
-                                <FontAwesomeIcon icon={this.openLayout ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {this.openLayout ? <div className="propertiesView-layout-content"  >{this.layoutPreview}</div> : null}
-                    </div>
-                </div>;
-            }
-            if (this.isPres) {
-                const selectedItem: boolean = PresBox.Instance?._selectedArray.length > 0;
-                return <div className="propertiesView" style={{ width: this.props.width }}>
-                    <div className="propertiesView-title" style={{ width: this.props.width }}>
-                        Presentation
-                    </div>
-                    <div className="propertiesView-name">
-                        {this.editableTitle}
-                        <div className="propertiesView-presSelected">
-                            {PresBox.Instance?._selectedArray.length} selected
-                            <div className="propertiesView-selectedList">
-                                {PresBox.Instance?.listOfSelected}
-                            </div>
-                        </div>
-                    </div>
-                    {!selectedItem ? (null) : <div className="propertiesView-presTrails">
-                        <div className="propertiesView-presTrails-title"
-                            onPointerDown={action(() => { this.openPresTransitions = !this.openPresTransitions; })}
-                            style={{ backgroundColor: this.openPresTransitions ? "black" : "" }}>
-                            &nbsp; <FontAwesomeIcon icon={"rocket"} /> &nbsp; Transitions
-                        <div className="propertiesView-presTrails-title-icon">
-                                <FontAwesomeIcon icon={this.openPresTransitions ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {this.openPresTransitions ? <div className="propertiesView-presTrails-content">
-                            {PresBox.Instance.transitionDropdown}
-                        </div> : null}
-                    </div>}
-                    {!selectedItem ? (null) : <div className="propertiesView-presTrails">
-                        <div className="propertiesView-presTrails-title"
-                            onPointerDown={action(() => { this.openPresProgressivize = !this.openPresProgressivize; })}
-                            style={{ backgroundColor: this.openPresProgressivize ? "black" : "" }}>
-                            &nbsp; <FontAwesomeIcon icon={"tasks"} /> &nbsp; Progressivize
-                        <div className="propertiesView-presTrails-title-icon">
-                                <FontAwesomeIcon icon={this.openPresProgressivize ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {this.openPresProgressivize ? <div className="propertiesView-presTrails-content">
-                            {PresBox.Instance.progressivizeDropdown}
-                        </div> : null}
-                    </div>}
-                    {!selectedItem ? (null) : <div className="propertiesView-presTrails">
-                        <div className="propertiesView-presTrails-title"
-                            onPointerDown={action(() => { this.openSlideOptions = !this.openSlideOptions; })}
-                            style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}>
-                            &nbsp; <FontAwesomeIcon icon={"cog"} /> &nbsp; {PresBox.Instance.stringType} options
-                        <div className="propertiesView-presTrails-title-icon">
-                                <FontAwesomeIcon icon={this.openSlideOptions ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {this.openSlideOptions ? <div className="propertiesView-presTrails-content">
-                            {PresBox.Instance.optionsDropdown}
-                        </div> : null}
-                    </div>}
-                    <div className="propertiesView-presTrails">
-                        <div className="propertiesView-presTrails-title"
-                            onPointerDown={action(() => { this.openAddSlide = !this.openAddSlide; })}
-                            style={{ backgroundColor: this.openAddSlide ? "black" : "" }}>
-                            &nbsp; <FontAwesomeIcon icon={"plus"} /> &nbsp; Add new slide
-                        <div className="propertiesView-presTrails-title-icon">
-                                <FontAwesomeIcon icon={this.openAddSlide ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {this.openAddSlide ? <div className="propertiesView-presTrails-content">
-                            {PresBox.Instance.newDocumentDropdown}
-                        </div> : null}
-                    </div>
-                    {/* <div className="propertiesView-sharing">
-                        <div className="propertiesView-sharing-title"
-                            onPointerDown={acition(() => { this.openSharing = !this.openSharing; })}
-                            style={{ backgroundColor: this.openSharing ? "black" : "" }}>
-                            Sharing {"&"} Permissions
-                        <div className="propertiesView-sharing-title-icon">
-                                <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {this.openSharing ? <div className="propertiesView-sharing-content">
-                            {this.sharingTable}
-                        </div> : null}
-                    </div> */}
-                </div>;
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6e1357b41..2d03c5154 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -30,6 +30,7 @@ import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from '../ContextMenuItem';
 import { DocComponent } from "../DocComponent";
 import { EditableView } from '../EditableView';
+import { FormatShapePane } from '../FormatShapePane';
 import { DocumentContentsView } from "./DocumentContentsView";
 import { DocumentLinksButton } from './DocumentLinksButton';
 import "./DocumentView.scss";
@@ -38,7 +39,6 @@ import { LinkDescriptionPopup } from './LinkDescriptionPopup';
 import { RadialMenu } from './RadialMenu';
 import { TaskCompletionBox } from './TaskCompletedBox';
 import React = require("react");
-import { FormatShapePane } from '../collections/collectionFreeForm/FormatShapePane';
 
 export type DocFocusFunc = () => boolean;
 
diff --git a/src/client/views/nodes/LinkAnchorBox.scss b/src/client/views/nodes/LinkAnchorBox.scss
index 42ef2958e..62ee9513c 100644
--- a/src/client/views/nodes/LinkAnchorBox.scss
+++ b/src/client/views/nodes/LinkAnchorBox.scss
@@ -22,6 +22,11 @@
         padding-left: 2px;
         padding-top: 1px;
     }
+    .linkAnchorBox-button {
+        pointer-events: all;
+        position: relative;
+        display: inline-block;
+    }
 }
 
 .linkAnchorBox-cont-small {
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index 1ef25c80d..8e5ee09ff 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -148,7 +148,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch
             }} >
             {!this._editing && !this._forceOpen ? (null) :
                 <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={flyout} open={this._forceOpen ? true : undefined} onOpen={() => this._isOpen = true} onClose={action(() => this._isOpen = this._forceOpen = this._editing = false)}>
-                    <span className="parentDocumentSelector-button" >
+                    <span className="linkAnchorBox-button" >
                         <FontAwesomeIcon icon={"eye"} size={"lg"} />
                     </span>
                 </Flyout>}
-- 
cgit v1.2.3-70-g09d2

