From 2781f77d46612720865ac0c1d115d6e013806103 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Tue, 3 Dec 2019 17:34:58 -0500 Subject: improved multi-user touch stuff --- .../collectionFreeForm/CollectionFreeFormView.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9506ce084..7267e94be 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -418,7 +418,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { handle1PointerMove = (e: TouchEvent) => { // panning a workspace if (!e.cancelBubble) { - let pt = e.targetTouches.item(0); + let myTouches = InteractionUtils.GetMyTargetTouches(e, this.prevPoints); + let pt = myTouches[0]; if (pt) { if (InkingControl.Instance.selectedTool === InkTool.None) { if (this._hitCluster && this.tryDragCluster(e)) { @@ -443,9 +444,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { handle2PointersMove = (e: TouchEvent) => { // pinch zooming if (!e.cancelBubble) { - let pt1: Touch | null = e.targetTouches.item(0); - let pt2: Touch | null = e.targetTouches.item(1); - if (!pt1 || !pt2) return; + let myTouches = InteractionUtils.GetMyTargetTouches(e, this.prevPoints); + let pt1 = myTouches[0]; + let pt2 = myTouches[1]; if (this.prevPoints.size === 2) { let oldPoint1 = this.prevPoints.get(pt1.identifier); @@ -923,8 +924,8 @@ class CollectionFreeFormViewPannableContents extends React.Component - {this.props.children()} + return
+ {this.props.children}
; } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From cb2edb837ffa9df5ad966d44ac0c26622d6579f0 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Tue, 3 Dec 2019 17:57:37 -0500 Subject: first hint of recognizer? --- src/Utils.ts | 3 + .../collectionFreeForm/CollectionFreeFormView.tsx | 13 +- src/ndollar.ts | 148 +++++++++++---------- 3 files changed, 93 insertions(+), 71 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/Utils.ts b/src/Utils.ts index 37b509370..dc62d96e0 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -3,9 +3,12 @@ import v5 = require("uuid/v5"); import { Socket } from 'socket.io'; import { Message } from './server/Message'; import { RouteStore } from './server/RouteStore'; +import { NDollarRecognizer } from './ndollar'; export namespace Utils { + export const GestureRecognizer = new NDollarRecognizer(false); + export const DRAG_THRESHOLD = 4; export function GenerateGuid(): string { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7267e94be..dcda13b00 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -337,9 +337,16 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (this._points.length > 1) { let B = this.svgBounds; let points = this._points.map(p => ({ x: p.x - B.left, y: p.y - B.top })); - let inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { width: B.width, height: B.height, x: B.left, y: B.top }); - this.addDocument(inkDoc); - this._points = []; + + let result = Utils.GestureRecognizer.Recognize(new Array(points)); + if (result) { + console.log(result.Name); + } + else { + let inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { width: B.width, height: B.height, x: B.left, y: B.top }); + this.addDocument(inkDoc); + this._points = []; + } } document.removeEventListener("pointermove", this.onPointerMove); diff --git a/src/ndollar.ts b/src/ndollar.ts index 2d3903cc3..6d7b8c5d9 100644 --- a/src/ndollar.ts +++ b/src/ndollar.ts @@ -130,6 +130,10 @@ export class Multistroke { } } +export enum Gestures { + Box = "box" +} + // // Result class // @@ -140,7 +144,7 @@ export class Result { // // NDollarRecognizer constants // -const NumMultistrokes = 16; +const NumMultistrokes = 1; const NumPoints = 96; const SquareSize = 250.0; const OneDThreshold = 0.25; // customize to desired gesture set (usually 0.20 - 0.35) @@ -165,78 +169,86 @@ export class NDollarRecognizer { // one predefined multistroke for each multistroke type // this.Multistrokes = new Array(NumMultistrokes); - this.Multistrokes[0] = new Multistroke("T", useBoundedRotationInvariance, new Array( - new Array(new Point(30, 7), new Point(103, 7)), - new Array(new Point(66, 7), new Point(66, 87)) - )); - this.Multistrokes[1] = new Multistroke("N", useBoundedRotationInvariance, new Array( - new Array(new Point(177, 92), new Point(177, 2)), - new Array(new Point(182, 1), new Point(246, 95)), - new Array(new Point(247, 87), new Point(247, 1)) - )); - this.Multistrokes[2] = new Multistroke("D", useBoundedRotationInvariance, new Array( - new Array(new Point(345, 9), new Point(345, 87)), - new Array(new Point(351, 8), new Point(363, 8), new Point(372, 9), new Point(380, 11), new Point(386, 14), new Point(391, 17), new Point(394, 22), new Point(397, 28), new Point(399, 34), new Point(400, 42), new Point(400, 50), new Point(400, 56), new Point(399, 61), new Point(397, 66), new Point(394, 70), new Point(391, 74), new Point(386, 78), new Point(382, 81), new Point(377, 83), new Point(372, 85), new Point(367, 87), new Point(360, 87), new Point(355, 88), new Point(349, 87)) - )); - this.Multistrokes[3] = new Multistroke("P", useBoundedRotationInvariance, new Array( - new Array(new Point(507, 8), new Point(507, 87)), - new Array(new Point(513, 7), new Point(528, 7), new Point(537, 8), new Point(544, 10), new Point(550, 12), new Point(555, 15), new Point(558, 18), new Point(560, 22), new Point(561, 27), new Point(562, 33), new Point(561, 37), new Point(559, 42), new Point(556, 45), new Point(550, 48), new Point(544, 51), new Point(538, 53), new Point(532, 54), new Point(525, 55), new Point(519, 55), new Point(513, 55), new Point(510, 55)) - )); - this.Multistrokes[4] = new Multistroke("X", useBoundedRotationInvariance, new Array( - new Array(new Point(30, 146), new Point(106, 222)), - new Array(new Point(30, 225), new Point(106, 146)) - )); - this.Multistrokes[5] = new Multistroke("H", useBoundedRotationInvariance, new Array( - new Array(new Point(188, 137), new Point(188, 225)), - new Array(new Point(188, 180), new Point(241, 180)), - new Array(new Point(241, 137), new Point(241, 225)) - )); - this.Multistrokes[6] = new Multistroke("I", useBoundedRotationInvariance, new Array( - new Array(new Point(371, 149), new Point(371, 221)), - new Array(new Point(341, 149), new Point(401, 149)), - new Array(new Point(341, 221), new Point(401, 221)) - )); - this.Multistrokes[7] = new Multistroke("exclamation", useBoundedRotationInvariance, new Array( - new Array(new Point(526, 142), new Point(526, 204)), - new Array(new Point(526, 221)) - )); - this.Multistrokes[8] = new Multistroke("line", useBoundedRotationInvariance, new Array( - new Array(new Point(12, 347), new Point(119, 347)) - )); - this.Multistrokes[9] = new Multistroke("five-point star", useBoundedRotationInvariance, new Array( - new Array(new Point(177, 396), new Point(223, 299), new Point(262, 396), new Point(168, 332), new Point(278, 332), new Point(184, 397)) - )); - this.Multistrokes[10] = new Multistroke("null", useBoundedRotationInvariance, new Array( - new Array(new Point(382, 310), new Point(377, 308), new Point(373, 307), new Point(366, 307), new Point(360, 310), new Point(356, 313), new Point(353, 316), new Point(349, 321), new Point(347, 326), new Point(344, 331), new Point(342, 337), new Point(341, 343), new Point(341, 350), new Point(341, 358), new Point(342, 362), new Point(344, 366), new Point(347, 370), new Point(351, 374), new Point(356, 379), new Point(361, 382), new Point(368, 385), new Point(374, 387), new Point(381, 387), new Point(390, 387), new Point(397, 385), new Point(404, 382), new Point(408, 378), new Point(412, 373), new Point(416, 367), new Point(418, 361), new Point(419, 353), new Point(418, 346), new Point(417, 341), new Point(416, 336), new Point(413, 331), new Point(410, 326), new Point(404, 320), new Point(400, 317), new Point(393, 313), new Point(392, 312)), - new Array(new Point(418, 309), new Point(337, 390)) - )); - this.Multistrokes[11] = new Multistroke("arrowhead", useBoundedRotationInvariance, new Array( - new Array(new Point(506, 349), new Point(574, 349)), - new Array(new Point(525, 306), new Point(584, 349), new Point(525, 388)) - )); - this.Multistrokes[12] = new Multistroke("pitchfork", useBoundedRotationInvariance, new Array( - new Array(new Point(38, 470), new Point(36, 476), new Point(36, 482), new Point(37, 489), new Point(39, 496), new Point(42, 500), new Point(46, 503), new Point(50, 507), new Point(56, 509), new Point(63, 509), new Point(70, 508), new Point(75, 506), new Point(79, 503), new Point(82, 499), new Point(85, 493), new Point(87, 487), new Point(88, 480), new Point(88, 474), new Point(87, 468)), - new Array(new Point(62, 464), new Point(62, 571)) - )); - this.Multistrokes[13] = new Multistroke("six-point star", useBoundedRotationInvariance, new Array( - new Array(new Point(177, 554), new Point(223, 476), new Point(268, 554), new Point(183, 554)), - new Array(new Point(177, 490), new Point(223, 568), new Point(268, 490), new Point(183, 490)) - )); - this.Multistrokes[14] = new Multistroke("asterisk", useBoundedRotationInvariance, new Array( - new Array(new Point(325, 499), new Point(417, 557)), - new Array(new Point(417, 499), new Point(325, 557)), - new Array(new Point(371, 486), new Point(371, 571)) - )); - this.Multistrokes[15] = new Multistroke("half-note", useBoundedRotationInvariance, new Array( - new Array(new Point(546, 465), new Point(546, 531)), - new Array(new Point(540, 530), new Point(536, 529), new Point(533, 528), new Point(529, 529), new Point(524, 530), new Point(520, 532), new Point(515, 535), new Point(511, 539), new Point(508, 545), new Point(506, 548), new Point(506, 554), new Point(509, 558), new Point(512, 561), new Point(517, 564), new Point(521, 564), new Point(527, 563), new Point(531, 560), new Point(535, 557), new Point(538, 553), new Point(542, 548), new Point(544, 544), new Point(546, 540), new Point(546, 536)) + this.Multistrokes[0] = new Multistroke(Gestures.Box, useBoundedRotationInvariance, new Array( + new Array(new Point(30, 146), new Point(30, 222), new Point(106, 225), new Point(106, 146)) )); + + // + // PREDEFINED STROKES + // + + // this.Multistrokes[0] = new Multistroke("T", useBoundedRotationInvariance, new Array( + // new Array(new Point(30, 7), new Point(103, 7)), + // new Array(new Point(66, 7), new Point(66, 87)) + // )); + // this.Multistrokes[1] = new Multistroke("N", useBoundedRotationInvariance, new Array( + // new Array(new Point(177, 92), new Point(177, 2)), + // new Array(new Point(182, 1), new Point(246, 95)), + // new Array(new Point(247, 87), new Point(247, 1)) + // )); + // this.Multistrokes[2] = new Multistroke("D", useBoundedRotationInvariance, new Array( + // new Array(new Point(345, 9), new Point(345, 87)), + // new Array(new Point(351, 8), new Point(363, 8), new Point(372, 9), new Point(380, 11), new Point(386, 14), new Point(391, 17), new Point(394, 22), new Point(397, 28), new Point(399, 34), new Point(400, 42), new Point(400, 50), new Point(400, 56), new Point(399, 61), new Point(397, 66), new Point(394, 70), new Point(391, 74), new Point(386, 78), new Point(382, 81), new Point(377, 83), new Point(372, 85), new Point(367, 87), new Point(360, 87), new Point(355, 88), new Point(349, 87)) + // )); + // this.Multistrokes[3] = new Multistroke("P", useBoundedRotationInvariance, new Array( + // new Array(new Point(507, 8), new Point(507, 87)), + // new Array(new Point(513, 7), new Point(528, 7), new Point(537, 8), new Point(544, 10), new Point(550, 12), new Point(555, 15), new Point(558, 18), new Point(560, 22), new Point(561, 27), new Point(562, 33), new Point(561, 37), new Point(559, 42), new Point(556, 45), new Point(550, 48), new Point(544, 51), new Point(538, 53), new Point(532, 54), new Point(525, 55), new Point(519, 55), new Point(513, 55), new Point(510, 55)) + // )); + // this.Multistrokes[4] = new Multistroke("X", useBoundedRotationInvariance, new Array( + // new Array(new Point(30, 146), new Point(106, 222)), + // new Array(new Point(30, 225), new Point(106, 146)) + // )); + // this.Multistrokes[5] = new Multistroke("H", useBoundedRotationInvariance, new Array( + // new Array(new Point(188, 137), new Point(188, 225)), + // new Array(new Point(188, 180), new Point(241, 180)), + // new Array(new Point(241, 137), new Point(241, 225)) + // )); + // this.Multistrokes[6] = new Multistroke("I", useBoundedRotationInvariance, new Array( + // new Array(new Point(371, 149), new Point(371, 221)), + // new Array(new Point(341, 149), new Point(401, 149)), + // new Array(new Point(341, 221), new Point(401, 221)) + // )); + // this.Multistrokes[7] = new Multistroke("exclamation", useBoundedRotationInvariance, new Array( + // new Array(new Point(526, 142), new Point(526, 204)), + // new Array(new Point(526, 221)) + // )); + // this.Multistrokes[8] = new Multistroke("line", useBoundedRotationInvariance, new Array( + // new Array(new Point(12, 347), new Point(119, 347)) + // )); + // this.Multistrokes[9] = new Multistroke("five-point star", useBoundedRotationInvariance, new Array( + // new Array(new Point(177, 396), new Point(223, 299), new Point(262, 396), new Point(168, 332), new Point(278, 332), new Point(184, 397)) + // )); + // this.Multistrokes[10] = new Multistroke("null", useBoundedRotationInvariance, new Array( + // new Array(new Point(382, 310), new Point(377, 308), new Point(373, 307), new Point(366, 307), new Point(360, 310), new Point(356, 313), new Point(353, 316), new Point(349, 321), new Point(347, 326), new Point(344, 331), new Point(342, 337), new Point(341, 343), new Point(341, 350), new Point(341, 358), new Point(342, 362), new Point(344, 366), new Point(347, 370), new Point(351, 374), new Point(356, 379), new Point(361, 382), new Point(368, 385), new Point(374, 387), new Point(381, 387), new Point(390, 387), new Point(397, 385), new Point(404, 382), new Point(408, 378), new Point(412, 373), new Point(416, 367), new Point(418, 361), new Point(419, 353), new Point(418, 346), new Point(417, 341), new Point(416, 336), new Point(413, 331), new Point(410, 326), new Point(404, 320), new Point(400, 317), new Point(393, 313), new Point(392, 312)), + // new Array(new Point(418, 309), new Point(337, 390)) + // )); + // this.Multistrokes[11] = new Multistroke("arrowhead", useBoundedRotationInvariance, new Array( + // new Array(new Point(506, 349), new Point(574, 349)), + // new Array(new Point(525, 306), new Point(584, 349), new Point(525, 388)) + // )); + // this.Multistrokes[12] = new Multistroke("pitchfork", useBoundedRotationInvariance, new Array( + // new Array(new Point(38, 470), new Point(36, 476), new Point(36, 482), new Point(37, 489), new Point(39, 496), new Point(42, 500), new Point(46, 503), new Point(50, 507), new Point(56, 509), new Point(63, 509), new Point(70, 508), new Point(75, 506), new Point(79, 503), new Point(82, 499), new Point(85, 493), new Point(87, 487), new Point(88, 480), new Point(88, 474), new Point(87, 468)), + // new Array(new Point(62, 464), new Point(62, 571)) + // )); + // this.Multistrokes[13] = new Multistroke("six-point star", useBoundedRotationInvariance, new Array( + // new Array(new Point(177, 554), new Point(223, 476), new Point(268, 554), new Point(183, 554)), + // new Array(new Point(177, 490), new Point(223, 568), new Point(268, 490), new Point(183, 490)) + // )); + // this.Multistrokes[14] = new Multistroke("asterisk", useBoundedRotationInvariance, new Array( + // new Array(new Point(325, 499), new Point(417, 557)), + // new Array(new Point(417, 499), new Point(325, 557)), + // new Array(new Point(371, 486), new Point(371, 571)) + // )); + // this.Multistrokes[15] = new Multistroke("half-note", useBoundedRotationInvariance, new Array( + // new Array(new Point(546, 465), new Point(546, 531)), + // new Array(new Point(540, 530), new Point(536, 529), new Point(533, 528), new Point(529, 529), new Point(524, 530), new Point(520, 532), new Point(515, 535), new Point(511, 539), new Point(508, 545), new Point(506, 548), new Point(506, 554), new Point(509, 558), new Point(512, 561), new Point(517, 564), new Point(521, 564), new Point(527, 563), new Point(531, 560), new Point(535, 557), new Point(538, 553), new Point(542, 548), new Point(544, 544), new Point(546, 540), new Point(546, 536)) + // )); // // The $N Gesture Recognizer API begins here -- 3 methods: Recognize(), AddGesture(), and DeleteUserGestures() // } - Recognize = (strokes: any[], useBoundedRotationInvariance: boolean, requireSameNoOfStrokes: boolean, useProtractor: boolean) => { + Recognize = (strokes: any[], useBoundedRotationInvariance: boolean = false, requireSameNoOfStrokes: boolean = false, useProtractor: boolean = true) => { var t0 = Date.now(); var points = CombineStrokes(strokes); // make one connected unistroke from the given strokes var candidate = new Unistroke("", useBoundedRotationInvariance, points); @@ -267,7 +279,7 @@ export class NDollarRecognizer { } } var t1 = Date.now(); - return (u == -1) ? new Result("No match.", 0.0, t1 - t0) : new Result(this.Multistrokes[u].Name, useProtractor ? (1.0 - b) : (1.0 - b / HalfDiagonal), t1 - t0); + return (u == -1) ? null : new Result(this.Multistrokes[u].Name, useProtractor ? (1.0 - b) : (1.0 - b / HalfDiagonal), t1 - t0); } AddGesture = (name: string, useBoundedRotationInvariance: boolean, strokes: any[]) => { -- cgit v1.2.3-70-g09d2 From fb9f08295c10c35c11b647d00a3c830867dc3f7d Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Tue, 3 Dec 2019 18:54:41 -0500 Subject: nothing new, infrastructure stuffs --- src/Utils.ts | 4 - src/client/documents/Documents.ts | 2 +- src/client/views/InkingStroke.tsx | 8 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 22 +- src/ndollar.ts | 531 --------------------- src/new_fields/InkField.ts | 6 +- src/pen-gestures/GestureUtils.ts | 35 ++ src/pen-gestures/ndollar.ts | 529 ++++++++++++++++++++ 8 files changed, 584 insertions(+), 553 deletions(-) delete mode 100644 src/ndollar.ts create mode 100644 src/pen-gestures/GestureUtils.ts create mode 100644 src/pen-gestures/ndollar.ts (limited to 'src/client/views/collections') diff --git a/src/Utils.ts b/src/Utils.ts index dc62d96e0..3db15f997 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -3,12 +3,8 @@ import v5 = require("uuid/v5"); import { Socket } from 'socket.io'; import { Message } from './server/Message'; import { RouteStore } from './server/RouteStore'; -import { NDollarRecognizer } from './ndollar'; export namespace Utils { - - export const GestureRecognizer = new NDollarRecognizer(false); - export const DRAG_THRESHOLD = 4; export function GenerateGuid(): string { diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index c5bf109a1..8c6aa2006 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -422,7 +422,7 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.TEXT), "", options); } - export function InkDocument(color: string, tool: number, strokeWidth: number, points: { x: number, y: number }[], options: DocumentOptions = {}) { + export function InkDocument(color: string, tool: number, strokeWidth: number, points: { X: number, Y: number }[], options: DocumentOptions = {}) { let doc = InstanceFromProto(Prototypes.get(DocumentType.INK), new InkField(points), options); doc.color = color; doc.strokeWidth = strokeWidth; diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index a27f106e3..a2e9f0e55 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -13,8 +13,8 @@ import React = require("react"); type InkDocument = makeInterface<[typeof documentSchema]>; const InkDocument = makeInterface(documentSchema); -export function CreatePolyline(points: { x: number, y: number }[], left: number, top: number, color?: string, width?: number) { - let pts = points.reduce((acc: string, pt: { x: number, y: number }) => acc + `${pt.x - left},${pt.y - top} `, ""); +export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, color?: string, width?: number) { + let pts = points.reduce((acc: string, pt: { X: number, Y: number }) => acc + `${pt.X - left},${pt.Y - top} `, ""); return ( p.x); - let ys = data.map(p => p.y); + let xs = data.map(p => p.X); + let ys = data.map(p => p.Y); let left = Math.min(...xs); let top = Math.min(...ys); let right = Math.max(...xs); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index dcda13b00..6dd472c84 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -41,6 +41,7 @@ import { MarqueeView } from "./MarqueeView"; import React = require("react"); import { computedFn, keepAlive } from "mobx-utils"; import { TraceMobx } from "../../../../new_fields/util"; +import { GestureUtils } from "../../../../pen-gestures/GestureUtils"; library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); @@ -272,7 +273,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { return clusterColor; } - @observable private _points: { x: number, y: number }[] = []; + @observable private _points: { X: number, Y: number }[] = []; @action onPointerDown = (e: React.PointerEvent): void => { @@ -288,7 +289,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { e.stopPropagation(); e.preventDefault(); let point = this.getTransform().transformPoint(e.pageX, e.pageY); - this._points.push({ x: point[0], y: point[1] }); + this._points.push({ X: point[0], Y: point[1] }); } // if not using a pen and in no ink mode else if (InkingControl.Instance.selectedTool === InkTool.None) { @@ -336,11 +337,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (this._points.length > 1) { let B = this.svgBounds; - let points = this._points.map(p => ({ x: p.x - B.left, y: p.y - B.top })); + let points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top })); - let result = Utils.GestureRecognizer.Recognize(new Array(points)); + let result = GestureUtils.GestureRecognizer.Recognize(new Array(points)); if (result) { console.log(result.Name); + this._points = []; } else { let inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { width: B.width, height: B.height, x: B.left, y: B.top }); @@ -405,7 +407,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { const selectedTool = InkingControl.Instance.selectedTool; if (selectedTool === InkTool.Highlighter || selectedTool === InkTool.Pen || InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { let point = this.getTransform().transformPoint(e.clientX, e.clientY); - this._points.push({ x: point[0], y: point[1] }); + this._points.push({ X: point[0], Y: point[1] }); } else if (selectedTool === InkTool.None) { if (this._hitCluster && this.tryDragCluster(e)) { @@ -440,7 +442,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } else if (InkingControl.Instance.selectedTool !== InkTool.Eraser && InkingControl.Instance.selectedTool !== InkTool.Scrubber) { let point = this.getTransform().transformPoint(pt.clientX, pt.clientY); - this._points.push({ x: point[0], y: point[1] }); + this._points.push({ X: point[0], Y: point[1] }); } } e.stopPropagation(); @@ -846,8 +848,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } @computed get svgBounds() { - let xs = this._points.map(p => p.x); - let ys = this._points.map(p => p.y); + let xs = this._points.map(p => p.X); + let ys = this._points.map(p => p.Y); let right = Math.max(...xs); let left = Math.min(...xs); let bottom = Math.max(...ys); @@ -863,7 +865,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let B = this.svgBounds; return ( - + {CreatePolyline(this._points, B.left, B.top)} ); @@ -932,7 +934,7 @@ class CollectionFreeFormViewPannableContents extends React.Component - {this.props.children} + {this.props.children()} ; } } \ No newline at end of file diff --git a/src/ndollar.ts b/src/ndollar.ts deleted file mode 100644 index 6d7b8c5d9..000000000 --- a/src/ndollar.ts +++ /dev/null @@ -1,531 +0,0 @@ -/** - * The $N Multistroke Recognizer (JavaScript version) - * Converted to TypeScript -syip2 - * - * Lisa Anthony, Ph.D. - * UMBC - * Information Systems Department - * 1000 Hilltop Circle - * Baltimore, MD 21250 - * lanthony@umbc.edu - * - * Jacob O. Wobbrock, Ph.D. - * The Information School - * University of Washington - * Seattle, WA 98195-2840 - * wobbrock@uw.edu - * - * The academic publications for the $N recognizer, and what should be - * used to cite it, are: - * - * Anthony, L. and Wobbrock, J.O. (2010). A lightweight multistroke - * recognizer for user interface prototypes. Proceedings of Graphics - * Interface (GI '10). Ottawa, Ontario (May 31-June 2, 2010). Toronto, - * Ontario: Canadian Information Processing Society, pp. 245-252. - * https://dl.acm.org/citation.cfm?id=1839258 - * - * Anthony, L. and Wobbrock, J.O. (2012). $N-Protractor: A fast and - * accurate multistroke recognizer. Proceedings of Graphics Interface - * (GI '12). Toronto, Ontario (May 28-30, 2012). Toronto, Ontario: - * Canadian Information Processing Society, pp. 117-120. - * https://dl.acm.org/citation.cfm?id=2305296 - * - * The Protractor enhancement was separately published by Yang Li and programmed - * here by Jacob O. Wobbrock and Lisa Anthony: - * - * Li, Y. (2010). Protractor: A fast and accurate gesture - * recognizer. Proceedings of the ACM Conference on Human - * Factors in Computing Systems (CHI '10). Atlanta, Georgia - * (April 10-15, 2010). New York: ACM Press, pp. 2169-2172. - * https://dl.acm.org/citation.cfm?id=1753654 - * - * This software is distributed under the "New BSD License" agreement: - * - * Copyright (C) 2007-2011, Jacob O. Wobbrock and Lisa Anthony. - * All rights reserved. Last updated July 14, 2018. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of UMBC nor the University of Washington, - * nor the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Lisa Anthony OR Jacob O. Wobbrock - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. -**/ - -// -// Point class -// -export class Point { - constructor(public X: number, public Y: number) { } -} - -// -// Rectangle class -// -export class Rectangle { - constructor(public X: number, public Y: number, public Width: number, public Height: number) { } -} - -// -// Unistroke class: a unistroke template -// -export class Unistroke { - public Points: Point[]; - public StartUnitVector: Point; - public Vector: number[]; - - constructor(public Name: string, useBoundedRotationInvariance: boolean, points: Point[]) { - this.Points = Resample(points, NumPoints); - var radians = IndicativeAngle(this.Points); - this.Points = RotateBy(this.Points, -radians); - this.Points = ScaleDimTo(this.Points, SquareSize, OneDThreshold); - if (useBoundedRotationInvariance) { - this.Points = RotateBy(this.Points, +radians); // restore - } - this.Points = TranslateTo(this.Points, Origin); - this.StartUnitVector = CalcStartUnitVector(this.Points, StartAngleIndex); - this.Vector = Vectorize(this.Points, useBoundedRotationInvariance); // for Protractor - } -} -// -// Multistroke class: a container for unistrokes -// -export class Multistroke { - public NumStrokes: number; - public Unistrokes: Unistroke[]; - - constructor(public Name: string, useBoundedRotationInvariance: boolean, strokes: any[]) // constructor - { - this.NumStrokes = strokes.length; // number of individual strokes - - var order = new Array(strokes.length); // array of integer indices - for (var i = 0; i < strokes.length; i++) { - order[i] = i; // initialize - } - var orders = new Array(); // array of integer arrays - HeapPermute(strokes.length, order, /*out*/ orders); - - var unistrokes = MakeUnistrokes(strokes, orders); // returns array of point arrays - this.Unistrokes = new Array(unistrokes.length); // unistrokes for this multistroke - for (var j = 0; j < unistrokes.length; j++) { - this.Unistrokes[j] = new Unistroke(name, useBoundedRotationInvariance, unistrokes[j]); - } - } -} - -export enum Gestures { - Box = "box" -} - -// -// Result class -// -export class Result { - constructor(public Name: string, public Score: any, public Time: any) { } -} - -// -// NDollarRecognizer constants -// -const NumMultistrokes = 1; -const NumPoints = 96; -const SquareSize = 250.0; -const OneDThreshold = 0.25; // customize to desired gesture set (usually 0.20 - 0.35) -const Origin = new Point(0, 0); -const Diagonal = Math.sqrt(SquareSize * SquareSize + SquareSize * SquareSize); -const HalfDiagonal = 0.5 * Diagonal; -const AngleRange = Deg2Rad(45.0); -const AnglePrecision = Deg2Rad(2.0); -const Phi = 0.5 * (-1.0 + Math.sqrt(5.0)); // Golden Ratio -const StartAngleIndex = (NumPoints / 8); // eighth of gesture length -const AngleSimilarityThreshold = Deg2Rad(30.0); - -// -// NDollarRecognizer class -// -export class NDollarRecognizer { - public Multistrokes: Multistroke[]; - - constructor(useBoundedRotationInvariance: boolean) // constructor - { - // - // one predefined multistroke for each multistroke type - // - this.Multistrokes = new Array(NumMultistrokes); - this.Multistrokes[0] = new Multistroke(Gestures.Box, useBoundedRotationInvariance, new Array( - new Array(new Point(30, 146), new Point(30, 222), new Point(106, 225), new Point(106, 146)) - )); - - // - // PREDEFINED STROKES - // - - // this.Multistrokes[0] = new Multistroke("T", useBoundedRotationInvariance, new Array( - // new Array(new Point(30, 7), new Point(103, 7)), - // new Array(new Point(66, 7), new Point(66, 87)) - // )); - // this.Multistrokes[1] = new Multistroke("N", useBoundedRotationInvariance, new Array( - // new Array(new Point(177, 92), new Point(177, 2)), - // new Array(new Point(182, 1), new Point(246, 95)), - // new Array(new Point(247, 87), new Point(247, 1)) - // )); - // this.Multistrokes[2] = new Multistroke("D", useBoundedRotationInvariance, new Array( - // new Array(new Point(345, 9), new Point(345, 87)), - // new Array(new Point(351, 8), new Point(363, 8), new Point(372, 9), new Point(380, 11), new Point(386, 14), new Point(391, 17), new Point(394, 22), new Point(397, 28), new Point(399, 34), new Point(400, 42), new Point(400, 50), new Point(400, 56), new Point(399, 61), new Point(397, 66), new Point(394, 70), new Point(391, 74), new Point(386, 78), new Point(382, 81), new Point(377, 83), new Point(372, 85), new Point(367, 87), new Point(360, 87), new Point(355, 88), new Point(349, 87)) - // )); - // this.Multistrokes[3] = new Multistroke("P", useBoundedRotationInvariance, new Array( - // new Array(new Point(507, 8), new Point(507, 87)), - // new Array(new Point(513, 7), new Point(528, 7), new Point(537, 8), new Point(544, 10), new Point(550, 12), new Point(555, 15), new Point(558, 18), new Point(560, 22), new Point(561, 27), new Point(562, 33), new Point(561, 37), new Point(559, 42), new Point(556, 45), new Point(550, 48), new Point(544, 51), new Point(538, 53), new Point(532, 54), new Point(525, 55), new Point(519, 55), new Point(513, 55), new Point(510, 55)) - // )); - // this.Multistrokes[4] = new Multistroke("X", useBoundedRotationInvariance, new Array( - // new Array(new Point(30, 146), new Point(106, 222)), - // new Array(new Point(30, 225), new Point(106, 146)) - // )); - // this.Multistrokes[5] = new Multistroke("H", useBoundedRotationInvariance, new Array( - // new Array(new Point(188, 137), new Point(188, 225)), - // new Array(new Point(188, 180), new Point(241, 180)), - // new Array(new Point(241, 137), new Point(241, 225)) - // )); - // this.Multistrokes[6] = new Multistroke("I", useBoundedRotationInvariance, new Array( - // new Array(new Point(371, 149), new Point(371, 221)), - // new Array(new Point(341, 149), new Point(401, 149)), - // new Array(new Point(341, 221), new Point(401, 221)) - // )); - // this.Multistrokes[7] = new Multistroke("exclamation", useBoundedRotationInvariance, new Array( - // new Array(new Point(526, 142), new Point(526, 204)), - // new Array(new Point(526, 221)) - // )); - // this.Multistrokes[8] = new Multistroke("line", useBoundedRotationInvariance, new Array( - // new Array(new Point(12, 347), new Point(119, 347)) - // )); - // this.Multistrokes[9] = new Multistroke("five-point star", useBoundedRotationInvariance, new Array( - // new Array(new Point(177, 396), new Point(223, 299), new Point(262, 396), new Point(168, 332), new Point(278, 332), new Point(184, 397)) - // )); - // this.Multistrokes[10] = new Multistroke("null", useBoundedRotationInvariance, new Array( - // new Array(new Point(382, 310), new Point(377, 308), new Point(373, 307), new Point(366, 307), new Point(360, 310), new Point(356, 313), new Point(353, 316), new Point(349, 321), new Point(347, 326), new Point(344, 331), new Point(342, 337), new Point(341, 343), new Point(341, 350), new Point(341, 358), new Point(342, 362), new Point(344, 366), new Point(347, 370), new Point(351, 374), new Point(356, 379), new Point(361, 382), new Point(368, 385), new Point(374, 387), new Point(381, 387), new Point(390, 387), new Point(397, 385), new Point(404, 382), new Point(408, 378), new Point(412, 373), new Point(416, 367), new Point(418, 361), new Point(419, 353), new Point(418, 346), new Point(417, 341), new Point(416, 336), new Point(413, 331), new Point(410, 326), new Point(404, 320), new Point(400, 317), new Point(393, 313), new Point(392, 312)), - // new Array(new Point(418, 309), new Point(337, 390)) - // )); - // this.Multistrokes[11] = new Multistroke("arrowhead", useBoundedRotationInvariance, new Array( - // new Array(new Point(506, 349), new Point(574, 349)), - // new Array(new Point(525, 306), new Point(584, 349), new Point(525, 388)) - // )); - // this.Multistrokes[12] = new Multistroke("pitchfork", useBoundedRotationInvariance, new Array( - // new Array(new Point(38, 470), new Point(36, 476), new Point(36, 482), new Point(37, 489), new Point(39, 496), new Point(42, 500), new Point(46, 503), new Point(50, 507), new Point(56, 509), new Point(63, 509), new Point(70, 508), new Point(75, 506), new Point(79, 503), new Point(82, 499), new Point(85, 493), new Point(87, 487), new Point(88, 480), new Point(88, 474), new Point(87, 468)), - // new Array(new Point(62, 464), new Point(62, 571)) - // )); - // this.Multistrokes[13] = new Multistroke("six-point star", useBoundedRotationInvariance, new Array( - // new Array(new Point(177, 554), new Point(223, 476), new Point(268, 554), new Point(183, 554)), - // new Array(new Point(177, 490), new Point(223, 568), new Point(268, 490), new Point(183, 490)) - // )); - // this.Multistrokes[14] = new Multistroke("asterisk", useBoundedRotationInvariance, new Array( - // new Array(new Point(325, 499), new Point(417, 557)), - // new Array(new Point(417, 499), new Point(325, 557)), - // new Array(new Point(371, 486), new Point(371, 571)) - // )); - // this.Multistrokes[15] = new Multistroke("half-note", useBoundedRotationInvariance, new Array( - // new Array(new Point(546, 465), new Point(546, 531)), - // new Array(new Point(540, 530), new Point(536, 529), new Point(533, 528), new Point(529, 529), new Point(524, 530), new Point(520, 532), new Point(515, 535), new Point(511, 539), new Point(508, 545), new Point(506, 548), new Point(506, 554), new Point(509, 558), new Point(512, 561), new Point(517, 564), new Point(521, 564), new Point(527, 563), new Point(531, 560), new Point(535, 557), new Point(538, 553), new Point(542, 548), new Point(544, 544), new Point(546, 540), new Point(546, 536)) - // )); - // - // The $N Gesture Recognizer API begins here -- 3 methods: Recognize(), AddGesture(), and DeleteUserGestures() - // - } - - Recognize = (strokes: any[], useBoundedRotationInvariance: boolean = false, requireSameNoOfStrokes: boolean = false, useProtractor: boolean = true) => { - var t0 = Date.now(); - var points = CombineStrokes(strokes); // make one connected unistroke from the given strokes - var candidate = new Unistroke("", useBoundedRotationInvariance, points); - - var u = -1; - var b = +Infinity; - for (var i = 0; i < this.Multistrokes.length; i++) // for each multistroke template - { - if (!requireSameNoOfStrokes || strokes.length == this.Multistrokes[i].NumStrokes) // optional -- only attempt match when same # of component strokes - { - for (var j = 0; j < this.Multistrokes[i].Unistrokes.length; j++) // for each unistroke within this multistroke - { - if (AngleBetweenUnitVectors(candidate.StartUnitVector, this.Multistrokes[i].Unistrokes[j].StartUnitVector) <= AngleSimilarityThreshold) // strokes start in the same direction - { - var d; - if (useProtractor) { - d = OptimalCosineDistance(this.Multistrokes[i].Unistrokes[j].Vector, candidate.Vector); // Protractor - } - else { - d = DistanceAtBestAngle(candidate.Points, this.Multistrokes[i].Unistrokes[j], -AngleRange, +AngleRange, AnglePrecision); // Golden Section Search (original $N) - } - if (d < b) { - b = d; // best (least) distance - u = i; // multistroke owner of unistroke - } - } - } - } - } - var t1 = Date.now(); - return (u == -1) ? null : new Result(this.Multistrokes[u].Name, useProtractor ? (1.0 - b) : (1.0 - b / HalfDiagonal), t1 - t0); - } - - AddGesture = (name: string, useBoundedRotationInvariance: boolean, strokes: any[]) => { - this.Multistrokes[this.Multistrokes.length] = new Multistroke(name, useBoundedRotationInvariance, strokes); - var num = 0; - for (var i = 0; i < this.Multistrokes.length; i++) { - if (this.Multistrokes[i].Name == name) { - num++; - } - } - return num; - } - - DeleteUserGestures = () => { - this.Multistrokes.length = NumMultistrokes; // clear any beyond the original set - return NumMultistrokes; - } -} - - -// -// Private helper functions from here on down -// -function HeapPermute(n: number, order: any[], /*out*/ orders: any[]) { - if (n == 1) { - orders[orders.length] = order.slice(); // append copy - } else { - for (var i = 0; i < n; i++) { - HeapPermute(n - 1, order, orders); - if (n % 2 == 1) { // swap 0, n-1 - var tmp = order[0]; - order[0] = order[n - 1]; - order[n - 1] = tmp; - } else { // swap i, n-1 - var tmp = order[i]; - order[i] = order[n - 1]; - order[n - 1] = tmp; - } - } - } -} - -function MakeUnistrokes(strokes: any, orders: any) { - var unistrokes = new Array(); // array of point arrays - for (var r = 0; r < orders.length; r++) { - for (var b = 0; b < Math.pow(2, orders[r].length); b++) // use b's bits for directions - { - var unistroke = new Array(); // array of points - for (var i = 0; i < orders[r].length; i++) { - var pts; - if (((b >> i) & 1) == 1) {// is b's bit at index i on? - pts = strokes[orders[r][i]].slice().reverse(); // copy and reverse - } - else { - pts = strokes[orders[r][i]].slice(); // copy - } - for (var p = 0; p < pts.length; p++) { - unistroke[unistroke.length] = pts[p]; // append points - } - } - unistrokes[unistrokes.length] = unistroke; // add one unistroke to set - } - } - return unistrokes; -} - -function CombineStrokes(strokes: any) { - var points = new Array(); - for (var s = 0; s < strokes.length; s++) { - for (var p = 0; p < strokes[s].length; p++) - points[points.length] = new Point(strokes[s][p].X, strokes[s][p].Y); - } - return points; -} -function Resample(points: any, n: any) { - var I = PathLength(points) / (n - 1); // interval length - var D = 0.0; - var newpoints = new Array(points[0]); - for (var i = 1; i < points.length; i++) { - var d = Distance(points[i - 1], points[i]); - if ((D + d) >= I) { - var qx = points[i - 1].X + ((I - D) / d) * (points[i].X - points[i - 1].X); - var qy = points[i - 1].Y + ((I - D) / d) * (points[i].Y - points[i - 1].Y); - var q = new Point(qx, qy); - newpoints[newpoints.length] = q; // append new point 'q' - points.splice(i, 0, q); // insert 'q' at position i in points s.t. 'q' will be the next i - D = 0.0; - } - else D += d; - } - if (newpoints.length == n - 1) // somtimes we fall a rounding-error short of adding the last point, so add it if so - newpoints[newpoints.length] = new Point(points[points.length - 1].X, points[points.length - 1].Y); - return newpoints; -} -function IndicativeAngle(points: any) { - var c = Centroid(points); - return Math.atan2(c.Y - points[0].Y, c.X - points[0].X); -} -function RotateBy(points: any, radians: any) // rotates points around centroid -{ - var c = Centroid(points); - var cos = Math.cos(radians); - var sin = Math.sin(radians); - var newpoints = new Array(); - for (var i = 0; i < points.length; i++) { - var qx = (points[i].X - c.X) * cos - (points[i].Y - c.Y) * sin + c.X - var qy = (points[i].X - c.X) * sin + (points[i].Y - c.Y) * cos + c.Y; - newpoints[newpoints.length] = new Point(qx, qy); - } - return newpoints; -} -function ScaleDimTo(points: any, size: any, ratio1D: any) // scales bbox uniformly for 1D, non-uniformly for 2D -{ - var B = BoundingBox(points); - var uniformly = Math.min(B.Width / B.Height, B.Height / B.Width) <= ratio1D; // 1D or 2D gesture test - var newpoints = new Array(); - for (var i = 0; i < points.length; i++) { - var qx = uniformly ? points[i].X * (size / Math.max(B.Width, B.Height)) : points[i].X * (size / B.Width); - var qy = uniformly ? points[i].Y * (size / Math.max(B.Width, B.Height)) : points[i].Y * (size / B.Height); - newpoints[newpoints.length] = new Point(qx, qy); - } - return newpoints; -} -function TranslateTo(points: any, pt: any) // translates points' centroid -{ - var c = Centroid(points); - var newpoints = new Array(); - for (var i = 0; i < points.length; i++) { - var qx = points[i].X + pt.X - c.X; - var qy = points[i].Y + pt.Y - c.Y; - newpoints[newpoints.length] = new Point(qx, qy); - } - return newpoints; -} -function Vectorize(points: any, useBoundedRotationInvariance: any) // for Protractor -{ - var cos = 1.0; - var sin = 0.0; - if (useBoundedRotationInvariance) { - var iAngle = Math.atan2(points[0].Y, points[0].X); - var baseOrientation = (Math.PI / 4.0) * Math.floor((iAngle + Math.PI / 8.0) / (Math.PI / 4.0)); - cos = Math.cos(baseOrientation - iAngle); - sin = Math.sin(baseOrientation - iAngle); - } - var sum = 0.0; - var vector = new Array(); - for (var i = 0; i < points.length; i++) { - var newX = points[i].X * cos - points[i].Y * sin; - var newY = points[i].Y * cos + points[i].X * sin; - vector[vector.length] = newX; - vector[vector.length] = newY; - sum += newX * newX + newY * newY; - } - var magnitude = Math.sqrt(sum); - for (var i = 0; i < vector.length; i++) { - vector[i] /= magnitude; - } - return vector; -} -function OptimalCosineDistance(v1: any, v2: any) // for Protractor -{ - var a = 0.0; - var b = 0.0; - for (var i = 0; i < v1.length; i += 2) { - a += v1[i] * v2[i] + v1[i + 1] * v2[i + 1]; - b += v1[i] * v2[i + 1] - v1[i + 1] * v2[i]; - } - var angle = Math.atan(b / a); - return Math.acos(a * Math.cos(angle) + b * Math.sin(angle)); -} -function DistanceAtBestAngle(points: any, T: any, a: any, b: any, threshold: any) { - var x1 = Phi * a + (1.0 - Phi) * b; - var f1 = DistanceAtAngle(points, T, x1); - var x2 = (1.0 - Phi) * a + Phi * b; - var f2 = DistanceAtAngle(points, T, x2); - while (Math.abs(b - a) > threshold) { - if (f1 < f2) { - b = x2; - x2 = x1; - f2 = f1; - x1 = Phi * a + (1.0 - Phi) * b; - f1 = DistanceAtAngle(points, T, x1); - } else { - a = x1; - x1 = x2; - f1 = f2; - x2 = (1.0 - Phi) * a + Phi * b; - f2 = DistanceAtAngle(points, T, x2); - } - } - return Math.min(f1, f2); -} -function DistanceAtAngle(points: any, T: any, radians: any) { - var newpoints = RotateBy(points, radians); - return PathDistance(newpoints, T.Points); -} -function Centroid(points: any) { - var x = 0.0, y = 0.0; - for (var i = 0; i < points.length; i++) { - x += points[i].X; - y += points[i].Y; - } - x /= points.length; - y /= points.length; - return new Point(x, y); -} -function BoundingBox(points: any) { - var minX = +Infinity, maxX = -Infinity, minY = +Infinity, maxY = -Infinity; - for (var i = 0; i < points.length; i++) { - minX = Math.min(minX, points[i].X); - minY = Math.min(minY, points[i].Y); - maxX = Math.max(maxX, points[i].X); - maxY = Math.max(maxY, points[i].Y); - } - return new Rectangle(minX, minY, maxX - minX, maxY - minY); -} -function PathDistance(pts1: any, pts2: any) // average distance between corresponding points in two paths -{ - var d = 0.0; - for (var i = 0; i < pts1.length; i++) // assumes pts1.length == pts2.length - d += Distance(pts1[i], pts2[i]); - return d / pts1.length; -} -function PathLength(points: any) // length traversed by a point path -{ - var d = 0.0; - for (var i = 1; i < points.length; i++) - d += Distance(points[i - 1], points[i]); - return d; -} -function Distance(p1: any, p2: any) // distance between two points -{ - var dx = p2.X - p1.X; - var dy = p2.Y - p1.Y; - return Math.sqrt(dx * dx + dy * dy); -} -function CalcStartUnitVector(points: any, index: any) // start angle from points[0] to points[index] normalized as a unit vector -{ - var v = new Point(points[index].X - points[0].X, points[index].Y - points[0].Y); - var len = Math.sqrt(v.X * v.X + v.Y * v.Y); - return new Point(v.X / len, v.Y / len); -} -function AngleBetweenUnitVectors(v1: any, v2: any) // gives acute angle between unit vectors from (0,0) to v1, and (0,0) to v2 -{ - var n = (v1.X * v2.X + v1.Y * v2.Y); - var c = Math.max(-1.0, Math.min(1.0, n)); // ensure [-1,+1] - return Math.acos(c); // arc cosine of the vector dot product -} -function Deg2Rad(d: any) { return (d * Math.PI / 180.0); } \ No newline at end of file diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts index 2d8bb582a..83d631958 100644 --- a/src/new_fields/InkField.ts +++ b/src/new_fields/InkField.ts @@ -13,14 +13,14 @@ export enum InkTool { } export interface PointData { - x: number; - y: number; + X: number; + Y: number; } export type InkData = Array; const pointSchema = createSimpleSchema({ - x: true, y: true + X: true, Y: true }); const strokeDataSchema = createSimpleSchema({ diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts new file mode 100644 index 000000000..caaa0736d --- /dev/null +++ b/src/pen-gestures/GestureUtils.ts @@ -0,0 +1,35 @@ +import { NDollarRecognizer } from "./ndollar"; +import { Type } from "typescript"; +import { InkField } from "../new_fields/InkField"; +import { Docs } from "../client/documents/Documents"; +import { Doc } from "../new_fields/Doc"; + +export namespace GestureUtils { + namespace GestureDataTypes { + export type BoxData = Doc[]; + } + + export const GestureRecognizer = new NDollarRecognizer(false); + + export enum Gestures { + Box = "box" + } + + export function GestureOptions(name: Gestures, gestureData: any): (() => any)[] { + switch (name) { + case Gestures.Box: + if (gestureData as GestureDataTypes.BoxData) { + return BoxOptions(gestureData as GestureDataTypes.BoxData); + } + break; + } + throw new Error("This means that you're trying to do something with the gesture that hasn't been defined yet. Define it in GestureUtils.ts"); + } + + function BoxOptions(gestureData: GestureDataTypes.BoxData): (() => any)[] { + if (gestureData instanceof Doc[]) { + return [() => Docs.Create.FreeformDocument(gestureData as Doc[], {})]; + } + return []; + } +} \ No newline at end of file diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts new file mode 100644 index 000000000..5d4384202 --- /dev/null +++ b/src/pen-gestures/ndollar.ts @@ -0,0 +1,529 @@ +import { GestureUtils } from "./GestureUtils"; + +/** + * The $N Multistroke Recognizer (JavaScript version) + * Converted to TypeScript -syip2 + * + * Lisa Anthony, Ph.D. + * UMBC + * Information Systems Department + * 1000 Hilltop Circle + * Baltimore, MD 21250 + * lanthony@umbc.edu + * + * Jacob O. Wobbrock, Ph.D. + * The Information School + * University of Washington + * Seattle, WA 98195-2840 + * wobbrock@uw.edu + * + * The academic publications for the $N recognizer, and what should be + * used to cite it, are: + * + * Anthony, L. and Wobbrock, J.O. (2010). A lightweight multistroke + * recognizer for user interface prototypes. Proceedings of Graphics + * Interface (GI '10). Ottawa, Ontario (May 31-June 2, 2010). Toronto, + * Ontario: Canadian Information Processing Society, pp. 245-252. + * https://dl.acm.org/citation.cfm?id=1839258 + * + * Anthony, L. and Wobbrock, J.O. (2012). $N-Protractor: A fast and + * accurate multistroke recognizer. Proceedings of Graphics Interface + * (GI '12). Toronto, Ontario (May 28-30, 2012). Toronto, Ontario: + * Canadian Information Processing Society, pp. 117-120. + * https://dl.acm.org/citation.cfm?id=2305296 + * + * The Protractor enhancement was separately published by Yang Li and programmed + * here by Jacob O. Wobbrock and Lisa Anthony: + * + * Li, Y. (2010). Protractor: A fast and accurate gesture + * recognizer. Proceedings of the ACM Conference on Human + * Factors in Computing Systems (CHI '10). Atlanta, Georgia + * (April 10-15, 2010). New York: ACM Press, pp. 2169-2172. + * https://dl.acm.org/citation.cfm?id=1753654 + * + * This software is distributed under the "New BSD License" agreement: + * + * Copyright (C) 2007-2011, Jacob O. Wobbrock and Lisa Anthony. + * All rights reserved. Last updated July 14, 2018. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of UMBC nor the University of Washington, + * nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Lisa Anthony OR Jacob O. Wobbrock + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. +**/ + +// +// Point class +// +export class Point { + constructor(public X: number, public Y: number) { } +} + +// +// Rectangle class +// +export class Rectangle { + constructor(public X: number, public Y: number, public Width: number, public Height: number) { } +} + +// +// Unistroke class: a unistroke template +// +export class Unistroke { + public Points: Point[]; + public StartUnitVector: Point; + public Vector: number[]; + + constructor(public Name: string, useBoundedRotationInvariance: boolean, points: Point[]) { + this.Points = Resample(points, NumPoints); + var radians = IndicativeAngle(this.Points); + this.Points = RotateBy(this.Points, -radians); + this.Points = ScaleDimTo(this.Points, SquareSize, OneDThreshold); + if (useBoundedRotationInvariance) { + this.Points = RotateBy(this.Points, +radians); // restore + } + this.Points = TranslateTo(this.Points, Origin); + this.StartUnitVector = CalcStartUnitVector(this.Points, StartAngleIndex); + this.Vector = Vectorize(this.Points, useBoundedRotationInvariance); // for Protractor + } +} +// +// Multistroke class: a container for unistrokes +// +export class Multistroke { + public NumStrokes: number; + public Unistrokes: Unistroke[]; + + constructor(public Name: string, useBoundedRotationInvariance: boolean, strokes: any[]) // constructor + { + this.NumStrokes = strokes.length; // number of individual strokes + + var order = new Array(strokes.length); // array of integer indices + for (var i = 0; i < strokes.length; i++) { + order[i] = i; // initialize + } + var orders = new Array(); // array of integer arrays + HeapPermute(strokes.length, order, /*out*/ orders); + + var unistrokes = MakeUnistrokes(strokes, orders); // returns array of point arrays + this.Unistrokes = new Array(unistrokes.length); // unistrokes for this multistroke + for (var j = 0; j < unistrokes.length; j++) { + this.Unistrokes[j] = new Unistroke(this.Name, useBoundedRotationInvariance, unistrokes[j]); + } + } +} + +// +// Result class +// +export class Result { + constructor(public Name: string, public Score: any, public Time: any) { } +} + +// +// NDollarRecognizer constants +// +const NumMultistrokes = 1; +const NumPoints = 96; +const SquareSize = 250.0; +const OneDThreshold = 0.25; // customize to desired gesture set (usually 0.20 - 0.35) +const Origin = new Point(0, 0); +const Diagonal = Math.sqrt(SquareSize * SquareSize + SquareSize * SquareSize); +const HalfDiagonal = 0.5 * Diagonal; +const AngleRange = Deg2Rad(45.0); +const AnglePrecision = Deg2Rad(2.0); +const Phi = 0.5 * (-1.0 + Math.sqrt(5.0)); // Golden Ratio +const StartAngleIndex = (NumPoints / 8); // eighth of gesture length +const AngleSimilarityThreshold = Deg2Rad(30.0); + +// +// NDollarRecognizer class +// +export class NDollarRecognizer { + public Multistrokes: Multistroke[]; + + constructor(useBoundedRotationInvariance: boolean) // constructor + { + // + // one predefined multistroke for each multistroke type + // + this.Multistrokes = new Array(NumMultistrokes); + this.Multistrokes[0] = new Multistroke(GestureUtils.Gestures.Box, useBoundedRotationInvariance, new Array( + new Array(new Point(30, 146), new Point(30, 222), new Point(106, 225), new Point(106, 146)) + )); + + // + // PREDEFINED STROKES + // + + // this.Multistrokes[0] = new Multistroke("T", useBoundedRotationInvariance, new Array( + // new Array(new Point(30, 7), new Point(103, 7)), + // new Array(new Point(66, 7), new Point(66, 87)) + // )); + // this.Multistrokes[1] = new Multistroke("N", useBoundedRotationInvariance, new Array( + // new Array(new Point(177, 92), new Point(177, 2)), + // new Array(new Point(182, 1), new Point(246, 95)), + // new Array(new Point(247, 87), new Point(247, 1)) + // )); + // this.Multistrokes[2] = new Multistroke("D", useBoundedRotationInvariance, new Array( + // new Array(new Point(345, 9), new Point(345, 87)), + // new Array(new Point(351, 8), new Point(363, 8), new Point(372, 9), new Point(380, 11), new Point(386, 14), new Point(391, 17), new Point(394, 22), new Point(397, 28), new Point(399, 34), new Point(400, 42), new Point(400, 50), new Point(400, 56), new Point(399, 61), new Point(397, 66), new Point(394, 70), new Point(391, 74), new Point(386, 78), new Point(382, 81), new Point(377, 83), new Point(372, 85), new Point(367, 87), new Point(360, 87), new Point(355, 88), new Point(349, 87)) + // )); + // this.Multistrokes[3] = new Multistroke("P", useBoundedRotationInvariance, new Array( + // new Array(new Point(507, 8), new Point(507, 87)), + // new Array(new Point(513, 7), new Point(528, 7), new Point(537, 8), new Point(544, 10), new Point(550, 12), new Point(555, 15), new Point(558, 18), new Point(560, 22), new Point(561, 27), new Point(562, 33), new Point(561, 37), new Point(559, 42), new Point(556, 45), new Point(550, 48), new Point(544, 51), new Point(538, 53), new Point(532, 54), new Point(525, 55), new Point(519, 55), new Point(513, 55), new Point(510, 55)) + // )); + // this.Multistrokes[4] = new Multistroke("X", useBoundedRotationInvariance, new Array( + // new Array(new Point(30, 146), new Point(106, 222)), + // new Array(new Point(30, 225), new Point(106, 146)) + // )); + // this.Multistrokes[5] = new Multistroke("H", useBoundedRotationInvariance, new Array( + // new Array(new Point(188, 137), new Point(188, 225)), + // new Array(new Point(188, 180), new Point(241, 180)), + // new Array(new Point(241, 137), new Point(241, 225)) + // )); + // this.Multistrokes[6] = new Multistroke("I", useBoundedRotationInvariance, new Array( + // new Array(new Point(371, 149), new Point(371, 221)), + // new Array(new Point(341, 149), new Point(401, 149)), + // new Array(new Point(341, 221), new Point(401, 221)) + // )); + // this.Multistrokes[7] = new Multistroke("exclamation", useBoundedRotationInvariance, new Array( + // new Array(new Point(526, 142), new Point(526, 204)), + // new Array(new Point(526, 221)) + // )); + // this.Multistrokes[8] = new Multistroke("line", useBoundedRotationInvariance, new Array( + // new Array(new Point(12, 347), new Point(119, 347)) + // )); + // this.Multistrokes[9] = new Multistroke("five-point star", useBoundedRotationInvariance, new Array( + // new Array(new Point(177, 396), new Point(223, 299), new Point(262, 396), new Point(168, 332), new Point(278, 332), new Point(184, 397)) + // )); + // this.Multistrokes[10] = new Multistroke("null", useBoundedRotationInvariance, new Array( + // new Array(new Point(382, 310), new Point(377, 308), new Point(373, 307), new Point(366, 307), new Point(360, 310), new Point(356, 313), new Point(353, 316), new Point(349, 321), new Point(347, 326), new Point(344, 331), new Point(342, 337), new Point(341, 343), new Point(341, 350), new Point(341, 358), new Point(342, 362), new Point(344, 366), new Point(347, 370), new Point(351, 374), new Point(356, 379), new Point(361, 382), new Point(368, 385), new Point(374, 387), new Point(381, 387), new Point(390, 387), new Point(397, 385), new Point(404, 382), new Point(408, 378), new Point(412, 373), new Point(416, 367), new Point(418, 361), new Point(419, 353), new Point(418, 346), new Point(417, 341), new Point(416, 336), new Point(413, 331), new Point(410, 326), new Point(404, 320), new Point(400, 317), new Point(393, 313), new Point(392, 312)), + // new Array(new Point(418, 309), new Point(337, 390)) + // )); + // this.Multistrokes[11] = new Multistroke("arrowhead", useBoundedRotationInvariance, new Array( + // new Array(new Point(506, 349), new Point(574, 349)), + // new Array(new Point(525, 306), new Point(584, 349), new Point(525, 388)) + // )); + // this.Multistrokes[12] = new Multistroke("pitchfork", useBoundedRotationInvariance, new Array( + // new Array(new Point(38, 470), new Point(36, 476), new Point(36, 482), new Point(37, 489), new Point(39, 496), new Point(42, 500), new Point(46, 503), new Point(50, 507), new Point(56, 509), new Point(63, 509), new Point(70, 508), new Point(75, 506), new Point(79, 503), new Point(82, 499), new Point(85, 493), new Point(87, 487), new Point(88, 480), new Point(88, 474), new Point(87, 468)), + // new Array(new Point(62, 464), new Point(62, 571)) + // )); + // this.Multistrokes[13] = new Multistroke("six-point star", useBoundedRotationInvariance, new Array( + // new Array(new Point(177, 554), new Point(223, 476), new Point(268, 554), new Point(183, 554)), + // new Array(new Point(177, 490), new Point(223, 568), new Point(268, 490), new Point(183, 490)) + // )); + // this.Multistrokes[14] = new Multistroke("asterisk", useBoundedRotationInvariance, new Array( + // new Array(new Point(325, 499), new Point(417, 557)), + // new Array(new Point(417, 499), new Point(325, 557)), + // new Array(new Point(371, 486), new Point(371, 571)) + // )); + // this.Multistrokes[15] = new Multistroke("half-note", useBoundedRotationInvariance, new Array( + // new Array(new Point(546, 465), new Point(546, 531)), + // new Array(new Point(540, 530), new Point(536, 529), new Point(533, 528), new Point(529, 529), new Point(524, 530), new Point(520, 532), new Point(515, 535), new Point(511, 539), new Point(508, 545), new Point(506, 548), new Point(506, 554), new Point(509, 558), new Point(512, 561), new Point(517, 564), new Point(521, 564), new Point(527, 563), new Point(531, 560), new Point(535, 557), new Point(538, 553), new Point(542, 548), new Point(544, 544), new Point(546, 540), new Point(546, 536)) + // )); + // + // The $N Gesture Recognizer API begins here -- 3 methods: Recognize(), AddGesture(), and DeleteUserGestures() + // + } + + Recognize = (strokes: any[], useBoundedRotationInvariance: boolean = false, requireSameNoOfStrokes: boolean = false, useProtractor: boolean = true) => { + var t0 = Date.now(); + var points = CombineStrokes(strokes); // make one connected unistroke from the given strokes + var candidate = new Unistroke("", useBoundedRotationInvariance, points); + + var u = -1; + var b = +Infinity; + for (var i = 0; i < this.Multistrokes.length; i++) // for each multistroke template + { + if (!requireSameNoOfStrokes || strokes.length == this.Multistrokes[i].NumStrokes) // optional -- only attempt match when same # of component strokes + { + for (var j = 0; j < this.Multistrokes[i].Unistrokes.length; j++) // for each unistroke within this multistroke + { + if (AngleBetweenUnitVectors(candidate.StartUnitVector, this.Multistrokes[i].Unistrokes[j].StartUnitVector) <= AngleSimilarityThreshold) // strokes start in the same direction + { + var d; + if (useProtractor) { + d = OptimalCosineDistance(this.Multistrokes[i].Unistrokes[j].Vector, candidate.Vector); // Protractor + } + else { + d = DistanceAtBestAngle(candidate.Points, this.Multistrokes[i].Unistrokes[j], -AngleRange, +AngleRange, AnglePrecision); // Golden Section Search (original $N) + } + if (d < b) { + b = d; // best (least) distance + u = i; // multistroke owner of unistroke + } + } + } + } + } + var t1 = Date.now(); + return (u == -1) ? null : new Result(this.Multistrokes[u].Name, useProtractor ? (1.0 - b) : (1.0 - b / HalfDiagonal), t1 - t0); + } + + AddGesture = (name: string, useBoundedRotationInvariance: boolean, strokes: any[]) => { + this.Multistrokes[this.Multistrokes.length] = new Multistroke(name, useBoundedRotationInvariance, strokes); + var num = 0; + for (var i = 0; i < this.Multistrokes.length; i++) { + if (this.Multistrokes[i].Name == name) { + num++; + } + } + return num; + } + + DeleteUserGestures = () => { + this.Multistrokes.length = NumMultistrokes; // clear any beyond the original set + return NumMultistrokes; + } +} + + +// +// Private helper functions from here on down +// +function HeapPermute(n: number, order: any[], /*out*/ orders: any[]) { + if (n == 1) { + orders[orders.length] = order.slice(); // append copy + } else { + for (var i = 0; i < n; i++) { + HeapPermute(n - 1, order, orders); + if (n % 2 == 1) { // swap 0, n-1 + var tmp = order[0]; + order[0] = order[n - 1]; + order[n - 1] = tmp; + } else { // swap i, n-1 + var tmp = order[i]; + order[i] = order[n - 1]; + order[n - 1] = tmp; + } + } + } +} + +function MakeUnistrokes(strokes: any, orders: any) { + var unistrokes = new Array(); // array of point arrays + for (var r = 0; r < orders.length; r++) { + for (var b = 0; b < Math.pow(2, orders[r].length); b++) // use b's bits for directions + { + var unistroke = new Array(); // array of points + for (var i = 0; i < orders[r].length; i++) { + var pts; + if (((b >> i) & 1) == 1) {// is b's bit at index i on? + pts = strokes[orders[r][i]].slice().reverse(); // copy and reverse + } + else { + pts = strokes[orders[r][i]].slice(); // copy + } + for (var p = 0; p < pts.length; p++) { + unistroke[unistroke.length] = pts[p]; // append points + } + } + unistrokes[unistrokes.length] = unistroke; // add one unistroke to set + } + } + return unistrokes; +} + +function CombineStrokes(strokes: any) { + var points = new Array(); + for (var s = 0; s < strokes.length; s++) { + for (var p = 0; p < strokes[s].length; p++) + points[points.length] = new Point(strokes[s][p].X, strokes[s][p].Y); + } + return points; +} +function Resample(points: any, n: any) { + var I = PathLength(points) / (n - 1); // interval length + var D = 0.0; + var newpoints = new Array(points[0]); + for (var i = 1; i < points.length; i++) { + var d = Distance(points[i - 1], points[i]); + if ((D + d) >= I) { + var qx = points[i - 1].X + ((I - D) / d) * (points[i].X - points[i - 1].X); + var qy = points[i - 1].Y + ((I - D) / d) * (points[i].Y - points[i - 1].Y); + var q = new Point(qx, qy); + newpoints[newpoints.length] = q; // append new point 'q' + points.splice(i, 0, q); // insert 'q' at position i in points s.t. 'q' will be the next i + D = 0.0; + } + else D += d; + } + if (newpoints.length == n - 1) // somtimes we fall a rounding-error short of adding the last point, so add it if so + newpoints[newpoints.length] = new Point(points[points.length - 1].X, points[points.length - 1].Y); + return newpoints; +} +function IndicativeAngle(points: any) { + var c = Centroid(points); + return Math.atan2(c.Y - points[0].Y, c.X - points[0].X); +} +function RotateBy(points: any, radians: any) // rotates points around centroid +{ + var c = Centroid(points); + var cos = Math.cos(radians); + var sin = Math.sin(radians); + var newpoints = new Array(); + for (var i = 0; i < points.length; i++) { + var qx = (points[i].X - c.X) * cos - (points[i].Y - c.Y) * sin + c.X + var qy = (points[i].X - c.X) * sin + (points[i].Y - c.Y) * cos + c.Y; + newpoints[newpoints.length] = new Point(qx, qy); + } + return newpoints; +} +function ScaleDimTo(points: any, size: any, ratio1D: any) // scales bbox uniformly for 1D, non-uniformly for 2D +{ + var B = BoundingBox(points); + var uniformly = Math.min(B.Width / B.Height, B.Height / B.Width) <= ratio1D; // 1D or 2D gesture test + var newpoints = new Array(); + for (var i = 0; i < points.length; i++) { + var qx = uniformly ? points[i].X * (size / Math.max(B.Width, B.Height)) : points[i].X * (size / B.Width); + var qy = uniformly ? points[i].Y * (size / Math.max(B.Width, B.Height)) : points[i].Y * (size / B.Height); + newpoints[newpoints.length] = new Point(qx, qy); + } + return newpoints; +} +function TranslateTo(points: any, pt: any) // translates points' centroid +{ + var c = Centroid(points); + var newpoints = new Array(); + for (var i = 0; i < points.length; i++) { + var qx = points[i].X + pt.X - c.X; + var qy = points[i].Y + pt.Y - c.Y; + newpoints[newpoints.length] = new Point(qx, qy); + } + return newpoints; +} +function Vectorize(points: any, useBoundedRotationInvariance: any) // for Protractor +{ + var cos = 1.0; + var sin = 0.0; + if (useBoundedRotationInvariance) { + var iAngle = Math.atan2(points[0].Y, points[0].X); + var baseOrientation = (Math.PI / 4.0) * Math.floor((iAngle + Math.PI / 8.0) / (Math.PI / 4.0)); + cos = Math.cos(baseOrientation - iAngle); + sin = Math.sin(baseOrientation - iAngle); + } + var sum = 0.0; + var vector = new Array(); + for (var i = 0; i < points.length; i++) { + var newX = points[i].X * cos - points[i].Y * sin; + var newY = points[i].Y * cos + points[i].X * sin; + vector[vector.length] = newX; + vector[vector.length] = newY; + sum += newX * newX + newY * newY; + } + var magnitude = Math.sqrt(sum); + for (var i = 0; i < vector.length; i++) { + vector[i] /= magnitude; + } + return vector; +} +function OptimalCosineDistance(v1: any, v2: any) // for Protractor +{ + var a = 0.0; + var b = 0.0; + for (var i = 0; i < v1.length; i += 2) { + a += v1[i] * v2[i] + v1[i + 1] * v2[i + 1]; + b += v1[i] * v2[i + 1] - v1[i + 1] * v2[i]; + } + var angle = Math.atan(b / a); + return Math.acos(a * Math.cos(angle) + b * Math.sin(angle)); +} +function DistanceAtBestAngle(points: any, T: any, a: any, b: any, threshold: any) { + var x1 = Phi * a + (1.0 - Phi) * b; + var f1 = DistanceAtAngle(points, T, x1); + var x2 = (1.0 - Phi) * a + Phi * b; + var f2 = DistanceAtAngle(points, T, x2); + while (Math.abs(b - a) > threshold) { + if (f1 < f2) { + b = x2; + x2 = x1; + f2 = f1; + x1 = Phi * a + (1.0 - Phi) * b; + f1 = DistanceAtAngle(points, T, x1); + } else { + a = x1; + x1 = x2; + f1 = f2; + x2 = (1.0 - Phi) * a + Phi * b; + f2 = DistanceAtAngle(points, T, x2); + } + } + return Math.min(f1, f2); +} +function DistanceAtAngle(points: any, T: any, radians: any) { + var newpoints = RotateBy(points, radians); + return PathDistance(newpoints, T.Points); +} +function Centroid(points: any) { + var x = 0.0, y = 0.0; + for (var i = 0; i < points.length; i++) { + x += points[i].X; + y += points[i].Y; + } + x /= points.length; + y /= points.length; + return new Point(x, y); +} +function BoundingBox(points: any) { + var minX = +Infinity, maxX = -Infinity, minY = +Infinity, maxY = -Infinity; + for (var i = 0; i < points.length; i++) { + minX = Math.min(minX, points[i].X); + minY = Math.min(minY, points[i].Y); + maxX = Math.max(maxX, points[i].X); + maxY = Math.max(maxY, points[i].Y); + } + return new Rectangle(minX, minY, maxX - minX, maxY - minY); +} +function PathDistance(pts1: any, pts2: any) // average distance between corresponding points in two paths +{ + var d = 0.0; + for (var i = 0; i < pts1.length; i++) // assumes pts1.length == pts2.length + d += Distance(pts1[i], pts2[i]); + return d / pts1.length; +} +function PathLength(points: any) // length traversed by a point path +{ + var d = 0.0; + for (var i = 1; i < points.length; i++) + d += Distance(points[i - 1], points[i]); + return d; +} +function Distance(p1: any, p2: any) // distance between two points +{ + var dx = p2.X - p1.X; + var dy = p2.Y - p1.Y; + return Math.sqrt(dx * dx + dy * dy); +} +function CalcStartUnitVector(points: any, index: any) // start angle from points[0] to points[index] normalized as a unit vector +{ + var v = new Point(points[index].X - points[0].X, points[index].Y - points[0].Y); + var len = Math.sqrt(v.X * v.X + v.Y * v.Y); + return new Point(v.X / len, v.Y / len); +} +function AngleBetweenUnitVectors(v1: any, v2: any) // gives acute angle between unit vectors from (0,0) to v1, and (0,0) to v2 +{ + var n = (v1.X * v2.X + v1.Y * v2.Y); + var c = Math.max(-1.0, Math.min(1.0, n)); // ensure [-1,+1] + return Math.acos(c); // arc cosine of the vector dot product +} +function Deg2Rad(d: any) { return (d * Math.PI / 180.0); } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 766e47cd144be6f0bcbb5787dbd174aa1bba3690 Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Sat, 7 Dec 2019 16:53:43 -0500 Subject: box !!!! --- src/client/util/InteractionUtils.ts | 2 +- src/client/views/Touchable.tsx | 4 ++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 23 ++++++++++++++++++---- src/client/views/nodes/DocumentView.tsx | 8 ++++---- src/pen-gestures/GestureUtils.ts | 16 ++++----------- src/pen-gestures/ndollar.ts | 2 +- 6 files changed, 31 insertions(+), 24 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/util/InteractionUtils.ts b/src/client/util/InteractionUtils.ts index 7390890c6..7c386abc2 100644 --- a/src/client/util/InteractionUtils.ts +++ b/src/client/util/InteractionUtils.ts @@ -53,7 +53,7 @@ export namespace InteractionUtils { * @param oldPoint2 - previous point 2 */ export function Pinching(pt1: React.Touch, pt2: React.Touch, oldPoint1: React.Touch, oldPoint2: React.Touch): number { - let threshold = 3; + let threshold = window.devicePixelRatio; let oldDist = TwoPointEuclidist(oldPoint1, oldPoint2); let newDist = TwoPointEuclidist(pt1, pt2); diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx index 5dcfec768..a647dec04 100644 --- a/src/client/views/Touchable.tsx +++ b/src/client/views/Touchable.tsx @@ -18,9 +18,9 @@ export abstract class Touchable extends React.Component { protected onTouchStart = (e: React.TouchEvent): void => { for (let i = 0; i < e.targetTouches.length; i++) { let pt: any = e.targetTouches.item(i); - // pen is also a touch, but with a radius of 0.5 (at least with the surface pens). i doubt anyone's fingers are 2 pixels wide, + // pen is also a touch, but with a radius of 0.5 (at least with the surface pens). // and this seems to be the only way of differentiating pen and touch on touch events - if (pt.radiusX > 2 && pt.radiusY > 2) { + if (pt.radiusX > 0.5 && pt.radiusY > 0.5) { this.prevPoints.set(pt.identifier, pt); } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 6dd472c84..bec0ace5a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -340,8 +340,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top })); let result = GestureUtils.GestureRecognizer.Recognize(new Array(points)); - if (result) { - console.log(result.Name); + if (result && result.Score > 0.75) { + switch (result.Name) { + case GestureUtils.Gestures.Box: + let bounds = { x: Math.min(...this._points.map(p => p.X)), r: Math.max(...this._points.map(p => p.X)), y: Math.min(...this._points.map(p => p.y)), b: Math.max(...this._points.map(p => p.Y)) }; + let sel = this.getActiveDocuments().filter(doc => { + let l = NumCast(doc.x); + let r = l + doc[WidthSym](); + let t = NumCast(doc.y); + let b = t + doc[HeightSym](); + doc.x = l - B.left - B.width / 2; + doc.y = t - B.top - B.height / 2; + return !(bounds.x > r || bounds.r < l || bounds.y > b || bounds.b < t); + }); + this.addDocument(Docs.Create.FreeformDocument(sel, { x: B.left, y: B.top, width: B.width, height: B.height, panX: 0, panY: 0 })); + sel.forEach(d => this.props.removeDocument(d)); + break; + } this._points = []; } else { @@ -474,8 +489,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let rawDelta = (dir * (d1 + d2)); // this floors and ceils the delta value to prevent jitteriness - let delta = Math.sign(rawDelta) * Math.min(Math.abs(rawDelta), 16); - this.zoom(centerX, centerY, delta); + let delta = Math.sign(rawDelta) * Math.min(Math.abs(rawDelta), 8); + this.zoom(centerX, centerY, delta * window.devicePixelRatio); this.prevPoints.set(pt1.identifier, pt1); this.prevPoints.set(pt2.identifier, pt2); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 38c46b258..dfeadb8c0 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -142,7 +142,7 @@ export class DocumentView extends DocComponent(Docu (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { e.stopPropagation(); let preventDefault = true; - if (this._doubleTap && this.props.renderDepth && !this.onClickHandler ?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click + if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click let fullScreenAlias = Doc.MakeAlias(this.props.Document); if (StrCast(fullScreenAlias.layoutKey) !== "layoutCustom" && fullScreenAlias.layoutCustom !== undefined) { fullScreenAlias.layoutKey = "layoutCustom"; @@ -362,7 +362,7 @@ export class DocumentView extends DocComponent(Docu @undoBatch @action setCustomView = (custom: boolean): void => { - if (this.props.ContainingCollectionView ?.props.DataDoc || this.props.ContainingCollectionView ?.props.Document.isTemplateDoc) { + if (this.props.ContainingCollectionView?.props.DataDoc || this.props.ContainingCollectionView?.props.Document.isTemplateDoc) { Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.ContainingCollectionView.props.Document); } else { custom ? DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc) : DocumentView.makeNativeViewClicked(this.props.Document); @@ -687,10 +687,10 @@ export class DocumentView extends DocComponent(Docu return
{ - console.log("Brush" + this.props.Document.title); + // console.log("Brush" + this.props.Document.title); Doc.BrushDoc(this.props.Document); }} onPointerLeave={e => { - console.log("UnBrush" + this.props.Document.title); + // console.log("UnBrush" + this.props.Document.title); Doc.UnBrushDoc(this.props.Document); }} diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts index 7a14452c8..955dad5b4 100644 --- a/src/pen-gestures/GestureUtils.ts +++ b/src/pen-gestures/GestureUtils.ts @@ -2,7 +2,9 @@ import { NDollarRecognizer } from "./ndollar"; import { Type } from "typescript"; import { InkField } from "../new_fields/InkField"; import { Docs } from "../client/documents/Documents"; -import { Doc } from "../new_fields/Doc"; +import { Doc, WidthSym, HeightSym } from "../new_fields/Doc"; +import { NumCast } from "../new_fields/Types"; +import { CollectionFreeFormView } from "../client/views/collections/collectionFreeForm/CollectionFreeFormView"; export namespace GestureUtils { namespace GestureDataTypes { @@ -15,21 +17,11 @@ export namespace GestureUtils { export const GestureRecognizer = new NDollarRecognizer(false); - export function GestureOptions(name: Gestures, gestureData: any): (() => any)[] { + export function GestureOptions(name: string, gestureData?: any): (params: {}) => any { switch (name) { case Gestures.Box: - if (gestureData as GestureDataTypes.BoxData) { - return BoxOptions(gestureData as GestureDataTypes.BoxData); - } break; } throw new Error("This means that you're trying to do something with the gesture that hasn't been defined yet. Define it in GestureUtils.ts"); } - - function BoxOptions(gestureData: GestureDataTypes.BoxData): (() => any)[] { - if (gestureData instanceof Array) { - return [() => Docs.Create.FreeformDocument(gestureData as Doc[], {})]; - } - return []; - } } \ No newline at end of file diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index 5d4384202..8c8e079a4 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -168,7 +168,7 @@ export class NDollarRecognizer { // this.Multistrokes = new Array(NumMultistrokes); this.Multistrokes[0] = new Multistroke(GestureUtils.Gestures.Box, useBoundedRotationInvariance, new Array( - new Array(new Point(30, 146), new Point(30, 222), new Point(106, 225), new Point(106, 146)) + new Array(new Point(30, 146), new Point(30, 222), new Point(106, 225), new Point(106, 146), new Point(30, 146)) )); // -- cgit v1.2.3-70-g09d2 From 3a2aaf5ffec2a568bb749c6ac0df8367a150af39 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Sun, 8 Dec 2019 14:46:46 -0500 Subject: links! --- .../collectionFreeForm/CollectionFreeFormView.tsx | 40 +++++++++++++++++++--- src/pen-gestures/GestureUtils.ts | 3 +- src/pen-gestures/ndollar.ts | 8 ++--- 3 files changed, 41 insertions(+), 10 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index bec0ace5a..5a7644d05 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -13,7 +13,7 @@ import { BoolCast, Cast, DateCast, NumCast, StrCast } from "../../../../new_fiel import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils"; import { aggregateBounds, emptyFunction, intersectRect, returnOne, Utils } from "../../../../Utils"; import { DocServer } from "../../../DocServer"; -import { Docs } from "../../../documents/Documents"; +import { Docs, DocUtils } from "../../../documents/Documents"; import { DocumentType } from "../../../documents/DocumentTypes"; import { DocumentManager } from "../../../util/DocumentManager"; import { DragManager } from "../../../util/DragManager"; @@ -42,6 +42,7 @@ import React = require("react"); import { computedFn, keepAlive } from "mobx-utils"; import { TraceMobx } from "../../../../new_fields/util"; import { GestureUtils } from "../../../../pen-gestures/GestureUtils"; +import { LinkManager } from "../../../util/LinkManager"; library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); @@ -340,7 +341,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top })); let result = GestureUtils.GestureRecognizer.Recognize(new Array(points)); - if (result && result.Score > 0.75) { + let actionPerformed = false; + if (result && result.Score > 0.7) { switch (result.Name) { case GestureUtils.Gestures.Box: let bounds = { x: Math.min(...this._points.map(p => p.X)), r: Math.max(...this._points.map(p => p.X)), y: Math.min(...this._points.map(p => p.y)), b: Math.max(...this._points.map(p => p.Y)) }; @@ -355,11 +357,39 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { }); this.addDocument(Docs.Create.FreeformDocument(sel, { x: B.left, y: B.top, width: B.width, height: B.height, panX: 0, panY: 0 })); sel.forEach(d => this.props.removeDocument(d)); + actionPerformed = true; + break; + case GestureUtils.Gestures.Line: + let ep1 = this._points[0]; + let ep2 = this._points[this._points.length - 1]; + let d1: Doc | undefined; + let d2: Doc | undefined; + this.getActiveDocuments().map(doc => { + let l = NumCast(doc.x); + let r = l + doc[WidthSym](); + let t = NumCast(doc.y); + let b = t + doc[HeightSym](); + if (!d1 && l < ep1.X && r > ep1.X && t < ep1.Y && b > ep1.Y) { + d1 = doc; + } + else if (!d2 && l < ep2.X && r > ep2.X && t < ep2.Y && b > ep2.Y) { + d2 = doc; + } + }); + if (d1 && d2) { + if (!LinkManager.Instance.doesLinkExist(d1, d2)) { + DocUtils.MakeLink({ doc: d1 }, { doc: d2 }); + actionPerformed = true; + } + } break; } - this._points = []; + if (actionPerformed) { + this._points = []; + } } - else { + + if (!actionPerformed) { let inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { width: B.width, height: B.height, x: B.left, y: B.top }); this.addDocument(inkDoc); this._points = []; @@ -880,7 +910,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let B = this.svgBounds; return ( - + {CreatePolyline(this._points, B.left, B.top)} ); diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts index 955dad5b4..59a85b66b 100644 --- a/src/pen-gestures/GestureUtils.ts +++ b/src/pen-gestures/GestureUtils.ts @@ -12,7 +12,8 @@ export namespace GestureUtils { } export enum Gestures { - Box = "box" + Box = "box", + Line = "line" } export const GestureRecognizer = new NDollarRecognizer(false); diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index 8c8e079a4..12c2b25bb 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -142,7 +142,7 @@ export class Result { // // NDollarRecognizer constants // -const NumMultistrokes = 1; +const NumMultistrokes = 2; const NumPoints = 96; const SquareSize = 250.0; const OneDThreshold = 0.25; // customize to desired gesture set (usually 0.20 - 0.35) @@ -170,6 +170,9 @@ export class NDollarRecognizer { this.Multistrokes[0] = new Multistroke(GestureUtils.Gestures.Box, useBoundedRotationInvariance, new Array( new Array(new Point(30, 146), new Point(30, 222), new Point(106, 225), new Point(106, 146), new Point(30, 146)) )); + this.Multistrokes[1] = new Multistroke(GestureUtils.Gestures.Line, useBoundedRotationInvariance, new Array( + new Array(new Point(12, 347), new Point(119, 347)) + )); // // PREDEFINED STROKES @@ -210,9 +213,6 @@ export class NDollarRecognizer { // new Array(new Point(526, 142), new Point(526, 204)), // new Array(new Point(526, 221)) // )); - // this.Multistrokes[8] = new Multistroke("line", useBoundedRotationInvariance, new Array( - // new Array(new Point(12, 347), new Point(119, 347)) - // )); // this.Multistrokes[9] = new Multistroke("five-point star", useBoundedRotationInvariance, new Array( // new Array(new Point(177, 396), new Point(223, 299), new Point(262, 396), new Point(168, 332), new Point(278, 332), new Point(184, 397)) // )); -- cgit v1.2.3-70-g09d2 From 4ead7eccb8ed9dd5708384315f8c5454b9725106 Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Sun, 8 Dec 2019 15:07:52 -0500 Subject: smal fix --- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5a7644d05..7b507f739 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -351,9 +351,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let r = l + doc[WidthSym](); let t = NumCast(doc.y); let b = t + doc[HeightSym](); - doc.x = l - B.left - B.width / 2; - doc.y = t - B.top - B.height / 2; - return !(bounds.x > r || bounds.r < l || bounds.y > b || bounds.b < t); + let pass = !(bounds.x > r || bounds.r < l || bounds.y > b || bounds.b < t); + if (pass) { + doc.x = l - B.left - B.width / 2; + doc.y = t - B.top - B.height / 2; + } + return pass; }); this.addDocument(Docs.Create.FreeformDocument(sel, { x: B.left, y: B.top, width: B.width, height: B.height, panX: 0, panY: 0 })); sel.forEach(d => this.props.removeDocument(d)); -- cgit v1.2.3-70-g09d2 From d16636a8246dadb486476fe98da63fc0db4d36dc Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Tue, 7 Jan 2020 14:49:27 -0500 Subject: resizing works, the math is just wrong looool --- src/client/util/InteractionUtils.ts | 2 +- src/client/views/Touchable.tsx | 21 ++- .../collectionFreeForm/CollectionFreeFormView.tsx | 44 ++++- src/client/views/nodes/DocumentView.tsx | 191 +++++++++++++++++---- src/client/views/nodes/FormattedTextBox.scss | 20 ++- 5 files changed, 220 insertions(+), 58 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/util/InteractionUtils.ts b/src/client/util/InteractionUtils.ts index 7c386abc2..2d3671041 100644 --- a/src/client/util/InteractionUtils.ts +++ b/src/client/util/InteractionUtils.ts @@ -8,7 +8,7 @@ export namespace InteractionUtils { const REACT_POINTER_PEN_BUTTON = 0; const ERASER_BUTTON = 5; - export function GetMyTargetTouches(e: TouchEvent, prevPoints: Map): React.Touch[] { + export function GetMyTargetTouches(e: TouchEvent | React.TouchEvent, prevPoints: Map): React.Touch[] { let myTouches = new Array(); for (let i = 0; i < e.targetTouches.length; i++) { let pt = e.targetTouches.item(i); diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx index a647dec04..7b0581376 100644 --- a/src/client/views/Touchable.tsx +++ b/src/client/views/Touchable.tsx @@ -26,7 +26,6 @@ export abstract class Touchable extends React.Component { } if (this.prevPoints.size) { - console.log(e.targetTouches.length); switch (this.prevPoints.size) { case 1: this.handle1PointerDown(e); @@ -35,11 +34,6 @@ export abstract class Touchable extends React.Component { this.handle2PointersDown(e); break; } - - document.removeEventListener("touchmove", this.onTouch); - document.addEventListener("touchmove", this.onTouch); - document.removeEventListener("touchend", this.onTouchEnd); - document.addEventListener("touchend", this.onTouchEnd); } } @@ -110,6 +104,17 @@ export abstract class Touchable extends React.Component { e.preventDefault(); } - handle1PointerDown = (e: React.TouchEvent): any => { }; - handle2PointersDown = (e: React.TouchEvent): any => { }; + handle1PointerDown = (e: React.TouchEvent): any => { + document.removeEventListener("touchmove", this.onTouch); + document.addEventListener("touchmove", this.onTouch); + document.removeEventListener("touchend", this.onTouchEnd); + document.addEventListener("touchend", this.onTouchEnd); + } + + handle2PointersDown = (e: React.TouchEvent): any => { + document.removeEventListener("touchmove", this.onTouch); + document.addEventListener("touchmove", this.onTouch); + document.removeEventListener("touchend", this.onTouchEnd); + document.addEventListener("touchend", this.onTouchEnd); + } } \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7b507f739..75690ab2c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -326,9 +326,30 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @action handle1PointerDown = (e: React.TouchEvent) => { + if (e.nativeEvent.cancelBubble) return; let pt = e.targetTouches.item(0); if (pt) { this._hitCluster = this.props.Document.useCluster ? this.pickCluster(this.getTransform().transformPoint(pt.clientX, pt.clientY)) !== -1 : false; + if (!e.shiftKey && !e.altKey && !e.ctrlKey && this.props.active(true)) { + document.removeEventListener("touchmove", this.onTouch); + document.addEventListener("touchmove", this.onTouch); + document.removeEventListener("touchend", this.onTouchEnd); + document.addEventListener("touchend", this.onTouchEnd); + if (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen) { + e.stopPropagation(); + e.preventDefault(); + let point = this.getTransform().transformPoint(pt.pageX, pt.pageY); + this._points.push({ X: point[0], Y: point[1] }); + } + else if (InkingControl.Instance.selectedTool === InkTool.None) { + this._lastX = pt.pageX; + this._lastY = pt.pageY; + } + else { + e.stopPropagation(); + e.preventDefault(); + } + } } } @@ -544,14 +565,21 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } handle2PointersDown = (e: React.TouchEvent) => { - let pt1: React.Touch | null = e.targetTouches.item(0); - let pt2: React.Touch | null = e.targetTouches.item(1); - if (!pt1 || !pt2) return; - - let centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2; - let centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2; - this._lastX = centerX; - this._lastY = centerY; + if (!e.nativeEvent.cancelBubble && this.props.active(true)) { + let pt1: React.Touch | null = e.targetTouches.item(0); + let pt2: React.Touch | null = e.targetTouches.item(1); + if (!pt1 || !pt2) return; + + let centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2; + let centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2; + this._lastX = centerX; + this._lastY = centerY; + document.removeEventListener("touchmove", this.onTouch); + document.addEventListener("touchmove", this.onTouch); + document.removeEventListener("touchend", this.onTouchEnd); + document.addEventListener("touchend", this.onTouchEnd); + e.stopPropagation(); + } } cleanUpInteractions = () => { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index dfeadb8c0..1780d9789 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -4,7 +4,7 @@ import { action, computed, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import * as rp from "request-promise"; import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../new_fields/Doc"; -import { Document } from '../../../new_fields/documentSchemas'; +import { Document, PositionDocument } from '../../../new_fields/documentSchemas'; import { Id } from '../../../new_fields/FieldSymbols'; import { listSpec } from "../../../new_fields/Schema"; import { ScriptField } from '../../../new_fields/ScriptField'; @@ -193,28 +193,165 @@ export class DocumentView extends DocComponent(Docu } } + handle1PointerDown = (e: React.TouchEvent) => { + if (!e.nativeEvent.cancelBubble) { + let touch = InteractionUtils.GetMyTargetTouches(e, this.prevPoints)[0]; + this._downX = touch.clientX; + this._downY = touch.clientY; + this._hitTemplateDrag = false; + for (let element = (e.target as any); element && !this._hitTemplateDrag; element = element.parentElement) { + if (element.className && element.className.toString() === "collectionViewBaseChrome-collapse") { + this._hitTemplateDrag = true; + } + } + if ((this.active || this.Document.onDragStart || this.Document.onClick) && !e.ctrlKey && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation(); + document.removeEventListener("touchmove", this.onTouch); + document.addEventListener("touchmove", this.onTouch); + document.removeEventListener("touchend", this.onTouchEnd); + document.addEventListener("touchend", this.onTouchEnd); + if ((e.nativeEvent as any).formattedHandled) e.stopPropagation(); + console.log("down") + } + } + + handle1PointerMove = (e: TouchEvent) => { + if ((e as any).formattedHandled) { e.stopPropagation; return; } + if (e.cancelBubble && this.active) { + document.removeEventListener("touchmove", this.onTouch); + } + else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.Document.onDragStart || this.Document.onClick) && !this.Document.lockedPosition && !this.Document.inOverlay) { + let touch = InteractionUtils.GetMyTargetTouches(e, this.prevPoints)[0]; + if (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3) { + if (!e.altKey && (!this.topMost || this.Document.onDragStart || this.Document.onClick)) { + document.removeEventListener("touchmove", this.onTouch); + document.removeEventListener("touchend", this.onTouchEnd); + this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined, this._hitTemplateDrag); + } + } + e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers + e.preventDefault(); + + } + } + + handle2PointersDown = (e: React.TouchEvent) => { + if (!e.nativeEvent.cancelBubble && !this.isSelected()) { + e.stopPropagation(); + e.preventDefault(); + + document.removeEventListener("touchmove", this.onTouch); + document.addEventListener("touchmove", this.onTouch); + document.removeEventListener("touchend", this.onTouchEnd); + document.addEventListener("touchend", this.onTouchEnd); + } + } + + @action + handle2PointersMove = (e: TouchEvent) => { + let myTouches = InteractionUtils.GetMyTargetTouches(e, this.prevPoints); + let pt1 = myTouches[0]; + let pt2 = myTouches[1]; + let oldPoint1 = this.prevPoints.get(pt1.identifier); + let oldPoint2 = this.prevPoints.get(pt2.identifier); + let pinching = InteractionUtils.Pinning(pt1, pt2, oldPoint1!, oldPoint2!); + if (pinching !== 0 && oldPoint1 && oldPoint2) { + // let dX = (Math.min(pt1.clientX, pt2.clientX) - Math.min(oldPoint1.clientX, oldPoint2.clientX)); + // let dY = (Math.min(pt1.clientY, pt2.clientY) - Math.min(oldPoint1.clientY, oldPoint2.clientY)); + // let dX = Math.sign(Math.abs(pt1.clientX - oldPoint1.clientX) - Math.abs(pt2.clientX - oldPoint2.clientX)); + // let dY = Math.sign(Math.abs(pt1.clientY - oldPoint1.clientY) - Math.abs(pt2.clientY - oldPoint2.clientY)); + // let dW = -dX; + // let dH = -dY; + let dW = (Math.abs(pt1.clientX - pt2.clientX) - Math.abs(oldPoint1.clientX - oldPoint2.clientX)); + let dH = (Math.abs(pt1.clientY - pt2.clientY) - Math.abs(oldPoint1.clientY - oldPoint2.clientY)); + let dX = -1 * Math.sign(dW); + let dY = -1 * Math.sign(dH); + + if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) { + let doc = PositionDocument(this.props.Document); + let layoutDoc = PositionDocument(Doc.Layout(this.props.Document)); + let nwidth = layoutDoc.nativeWidth || 0; + let nheight = layoutDoc.nativeHeight || 0; + let width = (layoutDoc.width || 0); + let height = (layoutDoc.height || (nheight / nwidth * width)); + let scale = this.props.ScreenToLocalTransform().Scale * this.props.ContentScaling(); + let actualdW = Math.max(width + (dW * scale), 20); + let actualdH = Math.max(height + (dH * scale), 20); + doc.x = (doc.x || 0) + dX * (actualdW - width); + doc.y = (doc.y || 0) + dY * (actualdH - height); + let fixedAspect = e.ctrlKey || (!layoutDoc.ignoreAspect && nwidth && nheight); + if (fixedAspect && e.ctrlKey && layoutDoc.ignoreAspect) { + layoutDoc.ignoreAspect = false; + layoutDoc.nativeWidth = nwidth = layoutDoc.width || 0; + layoutDoc.nativeHeight = nheight = layoutDoc.height || 0; + } + if (fixedAspect && (!nwidth || !nheight)) { + layoutDoc.nativeWidth = nwidth = layoutDoc.width || 0; + layoutDoc.nativeHeight = nheight = layoutDoc.height || 0; + } + if (nwidth > 0 && nheight > 0 && !layoutDoc.ignoreAspect) { + if (Math.abs(dW) > Math.abs(dH)) { + if (!fixedAspect) { + layoutDoc.nativeWidth = actualdW / (layoutDoc.width || 1) * (layoutDoc.nativeWidth || 0); + } + layoutDoc.width = actualdW; + if (fixedAspect && !layoutDoc.fitWidth) layoutDoc.height = nheight / nwidth * layoutDoc.width; + else layoutDoc.height = actualdH; + } + else { + if (!fixedAspect) { + layoutDoc.nativeHeight = actualdH / (layoutDoc.height || 1) * (doc.nativeHeight || 0); + } + layoutDoc.height = actualdH; + if (fixedAspect && !layoutDoc.fitWidth) layoutDoc.width = nwidth / nheight * layoutDoc.height; + else layoutDoc.width = actualdW; + } + } else { + dW && (layoutDoc.width = actualdW); + dH && (layoutDoc.height = actualdH); + dH && layoutDoc.autoHeight && (layoutDoc.autoHeight = false); + } + } + // let newWidth = Math.max(Math.abs(oldPoint1!.clientX - oldPoint2!.clientX), Math.abs(pt1.clientX - pt2.clientX)) + // this.props.Document.width = newWidth; + e.stopPropagation(); + e.preventDefault(); + } + } + onPointerDown = (e: React.PointerEvent): void => { - if ((e.nativeEvent.cancelBubble && (e.button === 0 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) - // return if we're inking, and not selecting a button document - || (InkingControl.Instance.selectedTool !== InkTool.None && !this.Document.onClick) - // return if using pen or eraser - || InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || InteractionUtils.IsType(e, InteractionUtils.ERASERTYPE)) return; - this._downX = e.clientX; - this._downY = e.clientY; - this._hitTemplateDrag = false; - // this whole section needs to move somewhere else. We're trying to initiate a special "template" drag where - // this document is the template and we apply it to whatever we drop it on. - for (let element = (e.target as any); element && !this._hitTemplateDrag; element = element.parentElement) { - if (element.className && element.className.toString() === "collectionViewBaseChrome-collapse") { - this._hitTemplateDrag = true; + // console.log(e.button) + // console.log(e.nativeEvent) + // continue if the event hasn't been canceled AND we are using a moues or this is has an onClick or onDragStart function (meaning it is a button document) + if (!InteractionUtils.IsType(e, InteractionUtils.MOUSETYPE)) { + e.stopPropagation(); + return; + } + if ((!e.nativeEvent.cancelBubble || this.Document.onClick || this.Document.onDragStart)) { + // if ((e.nativeEvent.cancelBubble && (e.button === 0 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) + // // return if we're inking, and not selecting a button document + // || (InkingControl.Instance.selectedTool !== InkTool.None && !this.Document.onClick) + // // return if using pen or eraser + // || InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || InteractionUtils.IsType(e, InteractionUtils.ERASERTYPE)) { + // return; + // } + + this._downX = e.clientX; + this._downY = e.clientY; + this._hitTemplateDrag = false; + // this whole section needs to move somewhere else. We're trying to initiate a special "template" drag where + // this document is the template and we apply it to whatever we drop it on. + for (let element = (e.target as any); element && !this._hitTemplateDrag; element = element.parentElement) { + if (element.className && element.className.toString() === "collectionViewBaseChrome-collapse") { + this._hitTemplateDrag = true; + } } + if ((this.active || this.Document.onDragStart || this.Document.onClick) && !e.ctrlKey && (e.button === 0 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation(); // events stop at the lowest document that is active. if right dragging, we let it go through though to allow for context menu clicks. PointerMove callbacks should remove themselves if the move event gets stopPropagated by a lower-level handler (e.g, marquee drag); + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointerup", this.onPointerUp); + if ((e.nativeEvent as any).formattedHandled) { e.stopPropagation(); } } - if ((this.active || this.Document.onDragStart || this.Document.onClick) && !e.ctrlKey && (e.button === 0 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation(); // events stop at the lowest document that is active. if right dragging, we let it go through though to allow for context menu clicks. PointerMove callbacks should remove themselves if the move event gets stopPropagated by a lower-level handler (e.g, marquee drag); - document.removeEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointermove", this.onPointerMove); - document.addEventListener("pointerup", this.onPointerUp); - if ((e.nativeEvent as any).formattedHandled) { e.stopPropagation(); } } onPointerMove = (e: PointerEvent): void => { @@ -649,20 +786,6 @@ export class DocumentView extends DocComponent(Docu return (this.Document.isBackground && !this.isSelected()) || (this.Document.type === DocumentType.INK && InkingControl.Instance.selectedTool !== InkTool.None); } - @action - handle2PointersMove = (e: TouchEvent) => { - let myTouches = InteractionUtils.GetMyTargetTouches(e, this.prevPoints); - let pt1 = myTouches[0]; - let pt2 = myTouches[1]; - let oldPoint1 = this.prevPoints.get(pt1.identifier); - let oldPoint2 = this.prevPoints.get(pt2.identifier); - let pinching = InteractionUtils.Pinning(pt1, pt2, oldPoint1!, oldPoint2!); - if (pinching !== 0) { - let newWidth = Math.max(Math.abs(oldPoint1!.clientX - oldPoint2!.clientX), Math.abs(pt1.clientX - pt2.clientX)) - this.props.Document.width = newWidth; - } - } - render() { if (!this.props.Document) return (null); const ruleColor = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleColor_" + this.Document.heading]) : undefined; diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 77cdd3d42..2e5848db4 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -11,6 +11,7 @@ } .formattedTextBox-cont { + touch-action: none; cursor: text; background: inherit; padding: 0; @@ -50,6 +51,7 @@ width: 100%; height: 100%; } + .formattedTextBox-sidebar-handle { position: absolute; top: calc(50% - 17.5px); @@ -58,19 +60,23 @@ background: lightgray; border-radius: 20px; } -.formattedTextBox-cont > .formattedTextBox-sidebar-handle { + +.formattedTextBox-cont>.formattedTextBox-sidebar-handle { right: 0; left: unset; } -.formattedTextBox-sidebar, .formattedTextBox-sidebar-inking { - border-left: dashed 1px black; - height: 100%; + +.formattedTextBox-sidebar, +.formattedTextBox-sidebar-inking { + border-left: dashed 1px black; + height: 100%; display: inline-block; position: absolute; right: 0; - > .formattedTextBox-sidebar-handle { - right:unset; - left:-5; + + >.formattedTextBox-sidebar-handle { + right: unset; + left: -5; } } -- cgit v1.2.3-70-g09d2 From 1b68d5a89abdd8a7db4d4762a3ee44c3363e9a74 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 8 Jan 2020 12:19:28 -0500 Subject: cleaned up searchBox. fixed parentdocument context menu placement. --- solr-8.3.1/server/solr/dash/core.properties | 6 ++ solr-8.3.1/server/solr/dash/data/index/_hs.dii | Bin 0 -> 118 bytes solr-8.3.1/server/solr/dash/data/index/_hs.dim | Bin 0 -> 12859 bytes solr-8.3.1/server/solr/dash/data/index/_hs.fdt | Bin 0 -> 65104 bytes solr-8.3.1/server/solr/dash/data/index/_hs.fdx | Bin 0 -> 107 bytes solr-8.3.1/server/solr/dash/data/index/_hs.fnm | Bin 0 -> 10795 bytes solr-8.3.1/server/solr/dash/data/index/_hs.nvd | Bin 0 -> 8896 bytes solr-8.3.1/server/solr/dash/data/index/_hs.nvm | Bin 0 -> 1543 bytes solr-8.3.1/server/solr/dash/data/index/_hs.si | Bin 0 -> 568 bytes solr-8.3.1/server/solr/dash/data/index/_hs_1.liv | Bin 0 -> 187 bytes .../server/solr/dash/data/index/_hs_Lucene50_0.doc | Bin 0 -> 98608 bytes .../server/solr/dash/data/index/_hs_Lucene50_0.pos | Bin 0 -> 94372 bytes .../server/solr/dash/data/index/_hs_Lucene50_0.tim | Bin 0 -> 255019 bytes .../server/solr/dash/data/index/_hs_Lucene50_0.tip | Bin 0 -> 4992 bytes .../server/solr/dash/data/index/_hs_Lucene80_0.dvd | Bin 0 -> 37542 bytes .../server/solr/dash/data/index/_hs_Lucene80_0.dvm | Bin 0 -> 250 bytes solr-8.3.1/server/solr/dash/data/index/_j7.dii | Bin 0 -> 97 bytes solr-8.3.1/server/solr/dash/data/index/_j7.dim | Bin 0 -> 1395 bytes solr-8.3.1/server/solr/dash/data/index/_j7.fdt | Bin 0 -> 4956 bytes solr-8.3.1/server/solr/dash/data/index/_j7.fdx | Bin 0 -> 84 bytes solr-8.3.1/server/solr/dash/data/index/_j7.fnm | Bin 0 -> 7628 bytes solr-8.3.1/server/solr/dash/data/index/_j7.nvd | Bin 0 -> 1121 bytes solr-8.3.1/server/solr/dash/data/index/_j7.nvm | Bin 0 -> 1003 bytes solr-8.3.1/server/solr/dash/data/index/_j7.si | Bin 0 -> 569 bytes solr-8.3.1/server/solr/dash/data/index/_j7_1.liv | Bin 0 -> 75 bytes .../server/solr/dash/data/index/_j7_Lucene50_0.doc | Bin 0 -> 6814 bytes .../server/solr/dash/data/index/_j7_Lucene50_0.pos | Bin 0 -> 8190 bytes .../server/solr/dash/data/index/_j7_Lucene50_0.tim | Bin 0 -> 38547 bytes .../server/solr/dash/data/index/_j7_Lucene50_0.tip | Bin 0 -> 1461 bytes .../server/solr/dash/data/index/_j7_Lucene80_0.dvd | Bin 0 -> 2851 bytes .../server/solr/dash/data/index/_j7_Lucene80_0.dvm | Bin 0 -> 249 bytes solr-8.3.1/server/solr/dash/data/index/_jf.dii | Bin 0 -> 75 bytes solr-8.3.1/server/solr/dash/data/index/_jf.dim | Bin 0 -> 570 bytes solr-8.3.1/server/solr/dash/data/index/_jf.fdt | Bin 0 -> 1949 bytes solr-8.3.1/server/solr/dash/data/index/_jf.fdx | Bin 0 -> 84 bytes solr-8.3.1/server/solr/dash/data/index/_jf.fnm | Bin 0 -> 2578 bytes solr-8.3.1/server/solr/dash/data/index/_jf.nvd | Bin 0 -> 1146 bytes solr-8.3.1/server/solr/dash/data/index/_jf.nvm | Bin 0 -> 607 bytes solr-8.3.1/server/solr/dash/data/index/_jf.si | Bin 0 -> 531 bytes solr-8.3.1/server/solr/dash/data/index/_jf_2.liv | Bin 0 -> 75 bytes .../server/solr/dash/data/index/_jf_Lucene50_0.doc | Bin 0 -> 7866 bytes .../server/solr/dash/data/index/_jf_Lucene50_0.pos | Bin 0 -> 7835 bytes .../server/solr/dash/data/index/_jf_Lucene50_0.tim | Bin 0 -> 12788 bytes .../server/solr/dash/data/index/_jf_Lucene50_0.tip | Bin 0 -> 735 bytes .../server/solr/dash/data/index/_jf_Lucene80_0.dvd | Bin 0 -> 683 bytes .../server/solr/dash/data/index/_jf_Lucene80_0.dvm | Bin 0 -> 249 bytes solr-8.3.1/server/solr/dash/data/index/_ji.dii | Bin 0 -> 72 bytes solr-8.3.1/server/solr/dash/data/index/_ji.dim | Bin 0 -> 242 bytes solr-8.3.1/server/solr/dash/data/index/_ji.fdt | Bin 0 -> 215 bytes solr-8.3.1/server/solr/dash/data/index/_ji.fdx | Bin 0 -> 84 bytes solr-8.3.1/server/solr/dash/data/index/_ji.fnm | Bin 0 -> 377 bytes solr-8.3.1/server/solr/dash/data/index/_ji.nvd | Bin 0 -> 59 bytes solr-8.3.1/server/solr/dash/data/index/_ji.nvm | Bin 0 -> 103 bytes solr-8.3.1/server/solr/dash/data/index/_ji.si | Bin 0 -> 531 bytes solr-8.3.1/server/solr/dash/data/index/_ji_1.liv | Bin 0 -> 67 bytes .../server/solr/dash/data/index/_ji_Lucene50_0.doc | Bin 0 -> 360 bytes .../server/solr/dash/data/index/_ji_Lucene50_0.pos | Bin 0 -> 725 bytes .../server/solr/dash/data/index/_ji_Lucene50_0.tim | Bin 0 -> 2775 bytes .../server/solr/dash/data/index/_ji_Lucene50_0.tip | Bin 0 -> 145 bytes .../server/solr/dash/data/index/_ji_Lucene80_0.dvd | Bin 0 -> 110 bytes .../server/solr/dash/data/index/_ji_Lucene80_0.dvm | Bin 0 -> 249 bytes solr-8.3.1/server/solr/dash/data/index/_jo.dii | Bin 0 -> 72 bytes solr-8.3.1/server/solr/dash/data/index/_jo.dim | Bin 0 -> 218 bytes solr-8.3.1/server/solr/dash/data/index/_jo.fdt | Bin 0 -> 651 bytes solr-8.3.1/server/solr/dash/data/index/_jo.fdx | Bin 0 -> 84 bytes solr-8.3.1/server/solr/dash/data/index/_jo.fnm | Bin 0 -> 2347 bytes solr-8.3.1/server/solr/dash/data/index/_jo.nvd | Bin 0 -> 353 bytes solr-8.3.1/server/solr/dash/data/index/_jo.nvm | Bin 0 -> 643 bytes solr-8.3.1/server/solr/dash/data/index/_jo.si | Bin 0 -> 531 bytes solr-8.3.1/server/solr/dash/data/index/_jo_1.liv | Bin 0 -> 67 bytes .../server/solr/dash/data/index/_jo_Lucene50_0.doc | Bin 0 -> 2526 bytes .../server/solr/dash/data/index/_jo_Lucene50_0.pos | Bin 0 -> 2723 bytes .../server/solr/dash/data/index/_jo_Lucene50_0.tim | Bin 0 -> 9422 bytes .../server/solr/dash/data/index/_jo_Lucene50_0.tip | Bin 0 -> 657 bytes .../server/solr/dash/data/index/_jo_Lucene80_0.dvd | Bin 0 -> 205 bytes .../server/solr/dash/data/index/_jo_Lucene80_0.dvm | Bin 0 -> 249 bytes solr-8.3.1/server/solr/dash/data/index/_jp.dii | Bin 0 -> 72 bytes solr-8.3.1/server/solr/dash/data/index/_jp.dim | Bin 0 -> 229 bytes solr-8.3.1/server/solr/dash/data/index/_jp.fdt | Bin 0 -> 398 bytes solr-8.3.1/server/solr/dash/data/index/_jp.fdx | Bin 0 -> 84 bytes solr-8.3.1/server/solr/dash/data/index/_jp.fnm | Bin 0 -> 1081 bytes solr-8.3.1/server/solr/dash/data/index/_jp.nvd | Bin 0 -> 235 bytes solr-8.3.1/server/solr/dash/data/index/_jp.nvm | Bin 0 -> 355 bytes solr-8.3.1/server/solr/dash/data/index/_jp.si | Bin 0 -> 531 bytes solr-8.3.1/server/solr/dash/data/index/_jp_1.liv | Bin 0 -> 67 bytes .../server/solr/dash/data/index/_jp_Lucene50_0.doc | Bin 0 -> 2635 bytes .../server/solr/dash/data/index/_jp_Lucene50_0.pos | Bin 0 -> 2579 bytes .../server/solr/dash/data/index/_jp_Lucene50_0.tim | Bin 0 -> 3558 bytes .../server/solr/dash/data/index/_jp_Lucene50_0.tip | Bin 0 -> 304 bytes .../server/solr/dash/data/index/_jp_Lucene80_0.dvd | Bin 0 -> 121 bytes .../server/solr/dash/data/index/_jp_Lucene80_0.dvm | Bin 0 -> 249 bytes solr-8.3.1/server/solr/dash/data/index/_jq.dii | Bin 0 -> 78 bytes solr-8.3.1/server/solr/dash/data/index/_jq.dim | Bin 0 -> 291 bytes solr-8.3.1/server/solr/dash/data/index/_jq.fdt | Bin 0 -> 719 bytes solr-8.3.1/server/solr/dash/data/index/_jq.fdx | Bin 0 -> 84 bytes solr-8.3.1/server/solr/dash/data/index/_jq.fnm | Bin 0 -> 1282 bytes solr-8.3.1/server/solr/dash/data/index/_jq.nvd | Bin 0 -> 131 bytes solr-8.3.1/server/solr/dash/data/index/_jq.nvm | Bin 0 -> 283 bytes solr-8.3.1/server/solr/dash/data/index/_jq.si | Bin 0 -> 531 bytes solr-8.3.1/server/solr/dash/data/index/_jq_2.liv | Bin 0 -> 67 bytes .../server/solr/dash/data/index/_jq_Lucene50_0.doc | Bin 0 -> 116 bytes .../server/solr/dash/data/index/_jq_Lucene50_0.pos | Bin 0 -> 458 bytes .../server/solr/dash/data/index/_jq_Lucene50_0.tim | Bin 0 -> 5813 bytes .../server/solr/dash/data/index/_jq_Lucene50_0.tip | Bin 0 -> 366 bytes .../server/solr/dash/data/index/_jq_Lucene80_0.dvd | Bin 0 -> 190 bytes .../server/solr/dash/data/index/_jq_Lucene80_0.dvm | Bin 0 -> 249 bytes solr-8.3.1/server/solr/dash/data/index/_jr.dii | Bin 0 -> 69 bytes solr-8.3.1/server/solr/dash/data/index/_jr.dim | Bin 0 -> 124 bytes solr-8.3.1/server/solr/dash/data/index/_jr.fdt | Bin 0 -> 226 bytes solr-8.3.1/server/solr/dash/data/index/_jr.fdx | Bin 0 -> 84 bytes solr-8.3.1/server/solr/dash/data/index/_jr.fnm | Bin 0 -> 445 bytes solr-8.3.1/server/solr/dash/data/index/_jr.si | Bin 0 -> 496 bytes solr-8.3.1/server/solr/dash/data/index/_jr_1.liv | Bin 0 -> 67 bytes .../server/solr/dash/data/index/_jr_Lucene50_0.doc | Bin 0 -> 114 bytes .../server/solr/dash/data/index/_jr_Lucene50_0.tim | Bin 0 -> 520 bytes .../server/solr/dash/data/index/_jr_Lucene50_0.tip | Bin 0 -> 145 bytes .../server/solr/dash/data/index/_jr_Lucene80_0.dvd | Bin 0 -> 110 bytes .../server/solr/dash/data/index/_jr_Lucene80_0.dvm | Bin 0 -> 249 bytes solr-8.3.1/server/solr/dash/data/index/segments_d | Bin 0 -> 649 bytes solr-8.3.1/server/solr/dash/data/index/write.lock | 0 .../solr/dash/data/tlog/tlog.0000000000000000011 | Bin 0 -> 1291205 bytes .../solr/dash/data/tlog/tlog.0000000000000000012 | Bin 0 -> 196943 bytes solr-8.3.1/server/solr/dash/data2/index/_199_1.liv | Bin 0 -> 67 bytes solr-8.3.1/server/solr/dash/data2/index/_19h_1.liv | Bin 0 -> 67 bytes solr-8.3.1/server/solr/dash/data2/index/write.lock | 0 .../solr/dash/data2/tlog/tlog.0000000000000000012 | Bin 0 -> 269779 bytes .../tmp/start_1669159736908453662.properties | 11 +++ .../tmp/start_5906520416860122978.properties | 11 +++ src/client/views/MainView.tsx | 2 +- .../views/collections/ParentDocumentSelector.tsx | 10 +- src/client/views/nodes/DocumentView.tsx | 3 +- src/client/views/search/SearchBox.scss | 3 +- src/client/views/search/SearchBox.tsx | 3 +- src/client/views/search/SearchItem.scss | 107 +++++---------------- src/client/views/search/SearchItem.tsx | 87 +++++++++-------- 135 files changed, 112 insertions(+), 131 deletions(-) create mode 100644 solr-8.3.1/server/solr/dash/core.properties create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs.dii create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs.dim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs.fdt create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs.fdx create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs.fnm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs.nvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs.nvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs.si create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs_1.liv create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.doc create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.pos create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.tim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.tip create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs_Lucene80_0.dvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_hs_Lucene80_0.dvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7.dii create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7.dim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7.fdt create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7.fdx create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7.fnm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7.nvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7.nvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7.si create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7_1.liv create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.doc create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.pos create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.tim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.tip create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7_Lucene80_0.dvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_j7_Lucene80_0.dvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf.dii create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf.dim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf.fdt create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf.fdx create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf.fnm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf.nvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf.nvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf.si create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf_2.liv create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.doc create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.pos create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.tim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.tip create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf_Lucene80_0.dvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jf_Lucene80_0.dvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji.dii create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji.dim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji.fdt create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji.fdx create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji.fnm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji.nvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji.nvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji.si create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji_1.liv create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.doc create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.pos create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.tim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.tip create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji_Lucene80_0.dvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_ji_Lucene80_0.dvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo.dii create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo.dim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo.fdt create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo.fdx create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo.fnm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo.nvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo.nvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo.si create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo_1.liv create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.doc create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.pos create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.tim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.tip create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo_Lucene80_0.dvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jo_Lucene80_0.dvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp.dii create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp.dim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp.fdt create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp.fdx create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp.fnm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp.nvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp.nvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp.si create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp_1.liv create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.doc create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.pos create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.tim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.tip create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp_Lucene80_0.dvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jp_Lucene80_0.dvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq.dii create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq.dim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq.fdt create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq.fdx create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq.fnm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq.nvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq.nvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq.si create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq_2.liv create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.doc create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.pos create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.tim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.tip create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq_Lucene80_0.dvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jq_Lucene80_0.dvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr.dii create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr.dim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr.fdt create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr.fdx create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr.fnm create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr.si create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr_1.liv create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.doc create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.tim create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.tip create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr_Lucene80_0.dvd create mode 100644 solr-8.3.1/server/solr/dash/data/index/_jr_Lucene80_0.dvm create mode 100644 solr-8.3.1/server/solr/dash/data/index/segments_d create mode 100644 solr-8.3.1/server/solr/dash/data/index/write.lock create mode 100644 solr-8.3.1/server/solr/dash/data/tlog/tlog.0000000000000000011 create mode 100644 solr-8.3.1/server/solr/dash/data/tlog/tlog.0000000000000000012 create mode 100644 solr-8.3.1/server/solr/dash/data2/index/_199_1.liv create mode 100644 solr-8.3.1/server/solr/dash/data2/index/_19h_1.liv create mode 100644 solr-8.3.1/server/solr/dash/data2/index/write.lock create mode 100644 solr-8.3.1/server/solr/dash/data2/tlog/tlog.0000000000000000012 create mode 100644 solr-8.3.1/server/tmp/start_1669159736908453662.properties create mode 100644 solr-8.3.1/server/tmp/start_5906520416860122978.properties (limited to 'src/client/views/collections') diff --git a/solr-8.3.1/server/solr/dash/core.properties b/solr-8.3.1/server/solr/dash/core.properties new file mode 100644 index 000000000..0912a8303 --- /dev/null +++ b/solr-8.3.1/server/solr/dash/core.properties @@ -0,0 +1,6 @@ +#Written by CorePropertiesLocator +#Wed Jan 08 14:44:34 UTC 2020 +name=dash +config=solrconfig.xml +schema=schema.xml +dataDir=data diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs.dii b/solr-8.3.1/server/solr/dash/data/index/_hs.dii new file mode 100644 index 000000000..c2207a7b5 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs.dii differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs.dim b/solr-8.3.1/server/solr/dash/data/index/_hs.dim new file mode 100644 index 000000000..808fdf537 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs.dim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs.fdt b/solr-8.3.1/server/solr/dash/data/index/_hs.fdt new file mode 100644 index 000000000..54fb57b98 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs.fdt differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs.fdx b/solr-8.3.1/server/solr/dash/data/index/_hs.fdx new file mode 100644 index 000000000..02a54c916 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs.fdx differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs.fnm b/solr-8.3.1/server/solr/dash/data/index/_hs.fnm new file mode 100644 index 000000000..2bb9517ac Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs.fnm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs.nvd b/solr-8.3.1/server/solr/dash/data/index/_hs.nvd new file mode 100644 index 000000000..994cb90ad Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs.nvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs.nvm b/solr-8.3.1/server/solr/dash/data/index/_hs.nvm new file mode 100644 index 000000000..a452ff4f2 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs.nvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs.si b/solr-8.3.1/server/solr/dash/data/index/_hs.si new file mode 100644 index 000000000..eeb2bc77e Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs.si differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs_1.liv b/solr-8.3.1/server/solr/dash/data/index/_hs_1.liv new file mode 100644 index 000000000..9e1e90cb8 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs_1.liv differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.doc b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.doc new file mode 100644 index 000000000..3f3c7dffa Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.doc differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.pos b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.pos new file mode 100644 index 000000000..9f2d9f805 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.pos differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.tim b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.tim new file mode 100644 index 000000000..1fb544956 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.tim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.tip b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.tip new file mode 100644 index 000000000..9c97fbbf2 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene50_0.tip differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene80_0.dvd b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene80_0.dvd new file mode 100644 index 000000000..e566bb7ed Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene80_0.dvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene80_0.dvm b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene80_0.dvm new file mode 100644 index 000000000..722d76cf9 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_hs_Lucene80_0.dvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7.dii b/solr-8.3.1/server/solr/dash/data/index/_j7.dii new file mode 100644 index 000000000..7d4c5af95 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7.dii differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7.dim b/solr-8.3.1/server/solr/dash/data/index/_j7.dim new file mode 100644 index 000000000..c6101943f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7.dim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7.fdt b/solr-8.3.1/server/solr/dash/data/index/_j7.fdt new file mode 100644 index 000000000..e89db4ed5 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7.fdt differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7.fdx b/solr-8.3.1/server/solr/dash/data/index/_j7.fdx new file mode 100644 index 000000000..a589f2dcd Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7.fdx differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7.fnm b/solr-8.3.1/server/solr/dash/data/index/_j7.fnm new file mode 100644 index 000000000..78d59368b Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7.fnm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7.nvd b/solr-8.3.1/server/solr/dash/data/index/_j7.nvd new file mode 100644 index 000000000..984fb854c Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7.nvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7.nvm b/solr-8.3.1/server/solr/dash/data/index/_j7.nvm new file mode 100644 index 000000000..aa478973c Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7.nvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7.si b/solr-8.3.1/server/solr/dash/data/index/_j7.si new file mode 100644 index 000000000..5ce51e20f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7.si differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7_1.liv b/solr-8.3.1/server/solr/dash/data/index/_j7_1.liv new file mode 100644 index 000000000..65e825f18 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7_1.liv differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.doc b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.doc new file mode 100644 index 000000000..3158e0d7f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.doc differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.pos b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.pos new file mode 100644 index 000000000..e5b3f12f9 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.pos differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.tim b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.tim new file mode 100644 index 000000000..db0ddd7dd Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.tim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.tip b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.tip new file mode 100644 index 000000000..6d06bbc8a Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene50_0.tip differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene80_0.dvd b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene80_0.dvd new file mode 100644 index 000000000..06dc34e64 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene80_0.dvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene80_0.dvm b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene80_0.dvm new file mode 100644 index 000000000..7f69f1665 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_j7_Lucene80_0.dvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf.dii b/solr-8.3.1/server/solr/dash/data/index/_jf.dii new file mode 100644 index 000000000..0627e1127 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf.dii differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf.dim b/solr-8.3.1/server/solr/dash/data/index/_jf.dim new file mode 100644 index 000000000..1a489cd18 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf.dim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf.fdt b/solr-8.3.1/server/solr/dash/data/index/_jf.fdt new file mode 100644 index 000000000..5fce34b2c Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf.fdt differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf.fdx b/solr-8.3.1/server/solr/dash/data/index/_jf.fdx new file mode 100644 index 000000000..14aaf8fc0 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf.fdx differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf.fnm b/solr-8.3.1/server/solr/dash/data/index/_jf.fnm new file mode 100644 index 000000000..eff2f74b7 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf.fnm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf.nvd b/solr-8.3.1/server/solr/dash/data/index/_jf.nvd new file mode 100644 index 000000000..2bffbd106 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf.nvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf.nvm b/solr-8.3.1/server/solr/dash/data/index/_jf.nvm new file mode 100644 index 000000000..02a616913 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf.nvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf.si b/solr-8.3.1/server/solr/dash/data/index/_jf.si new file mode 100644 index 000000000..b776600c1 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf.si differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf_2.liv b/solr-8.3.1/server/solr/dash/data/index/_jf_2.liv new file mode 100644 index 000000000..49e851d49 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf_2.liv differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.doc b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.doc new file mode 100644 index 000000000..f951b0e3a Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.doc differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.pos b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.pos new file mode 100644 index 000000000..7bc297568 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.pos differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.tim b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.tim new file mode 100644 index 000000000..874b3807c Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.tim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.tip b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.tip new file mode 100644 index 000000000..b835a3e5f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene50_0.tip differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene80_0.dvd b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene80_0.dvd new file mode 100644 index 000000000..04b2e5a6c Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene80_0.dvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene80_0.dvm b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene80_0.dvm new file mode 100644 index 000000000..b68fbf656 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jf_Lucene80_0.dvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji.dii b/solr-8.3.1/server/solr/dash/data/index/_ji.dii new file mode 100644 index 000000000..fdef5b441 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji.dii differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji.dim b/solr-8.3.1/server/solr/dash/data/index/_ji.dim new file mode 100644 index 000000000..2155d1932 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji.dim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji.fdt b/solr-8.3.1/server/solr/dash/data/index/_ji.fdt new file mode 100644 index 000000000..e7fdec3fb Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji.fdt differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji.fdx b/solr-8.3.1/server/solr/dash/data/index/_ji.fdx new file mode 100644 index 000000000..86c01bbd4 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji.fdx differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji.fnm b/solr-8.3.1/server/solr/dash/data/index/_ji.fnm new file mode 100644 index 000000000..d3925b485 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji.fnm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji.nvd b/solr-8.3.1/server/solr/dash/data/index/_ji.nvd new file mode 100644 index 000000000..205e2b1cd Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji.nvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji.nvm b/solr-8.3.1/server/solr/dash/data/index/_ji.nvm new file mode 100644 index 000000000..21f18e60a Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji.nvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji.si b/solr-8.3.1/server/solr/dash/data/index/_ji.si new file mode 100644 index 000000000..b7126893f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji.si differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji_1.liv b/solr-8.3.1/server/solr/dash/data/index/_ji_1.liv new file mode 100644 index 000000000..753deb733 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji_1.liv differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.doc b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.doc new file mode 100644 index 000000000..060372c58 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.doc differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.pos b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.pos new file mode 100644 index 000000000..466c55484 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.pos differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.tim b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.tim new file mode 100644 index 000000000..ca4000e9c Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.tim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.tip b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.tip new file mode 100644 index 000000000..a749cb1b9 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene50_0.tip differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene80_0.dvd b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene80_0.dvd new file mode 100644 index 000000000..de1318ae2 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene80_0.dvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene80_0.dvm b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene80_0.dvm new file mode 100644 index 000000000..c273ad653 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_ji_Lucene80_0.dvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo.dii b/solr-8.3.1/server/solr/dash/data/index/_jo.dii new file mode 100644 index 000000000..d621dc010 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo.dii differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo.dim b/solr-8.3.1/server/solr/dash/data/index/_jo.dim new file mode 100644 index 000000000..a9d846c55 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo.dim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo.fdt b/solr-8.3.1/server/solr/dash/data/index/_jo.fdt new file mode 100644 index 000000000..69d7ce59c Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo.fdt differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo.fdx b/solr-8.3.1/server/solr/dash/data/index/_jo.fdx new file mode 100644 index 000000000..71a73ac09 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo.fdx differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo.fnm b/solr-8.3.1/server/solr/dash/data/index/_jo.fnm new file mode 100644 index 000000000..b02414ef0 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo.fnm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo.nvd b/solr-8.3.1/server/solr/dash/data/index/_jo.nvd new file mode 100644 index 000000000..993fa7ddc Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo.nvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo.nvm b/solr-8.3.1/server/solr/dash/data/index/_jo.nvm new file mode 100644 index 000000000..4397e5533 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo.nvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo.si b/solr-8.3.1/server/solr/dash/data/index/_jo.si new file mode 100644 index 000000000..2f0aefd63 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo.si differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo_1.liv b/solr-8.3.1/server/solr/dash/data/index/_jo_1.liv new file mode 100644 index 000000000..46316505e Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo_1.liv differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.doc b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.doc new file mode 100644 index 000000000..1cbf85053 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.doc differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.pos b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.pos new file mode 100644 index 000000000..97206ebfa Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.pos differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.tim b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.tim new file mode 100644 index 000000000..d06a85746 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.tim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.tip b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.tip new file mode 100644 index 000000000..fd9ff3dae Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene50_0.tip differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene80_0.dvd b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene80_0.dvd new file mode 100644 index 000000000..602ba23e7 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene80_0.dvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene80_0.dvm b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene80_0.dvm new file mode 100644 index 000000000..1fd81041f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jo_Lucene80_0.dvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp.dii b/solr-8.3.1/server/solr/dash/data/index/_jp.dii new file mode 100644 index 000000000..c39beb1bd Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp.dii differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp.dim b/solr-8.3.1/server/solr/dash/data/index/_jp.dim new file mode 100644 index 000000000..87a5071d7 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp.dim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp.fdt b/solr-8.3.1/server/solr/dash/data/index/_jp.fdt new file mode 100644 index 000000000..a232efdf8 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp.fdt differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp.fdx b/solr-8.3.1/server/solr/dash/data/index/_jp.fdx new file mode 100644 index 000000000..0b5e95a9a Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp.fdx differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp.fnm b/solr-8.3.1/server/solr/dash/data/index/_jp.fnm new file mode 100644 index 000000000..c09282147 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp.fnm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp.nvd b/solr-8.3.1/server/solr/dash/data/index/_jp.nvd new file mode 100644 index 000000000..12dcf3d4d Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp.nvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp.nvm b/solr-8.3.1/server/solr/dash/data/index/_jp.nvm new file mode 100644 index 000000000..4bde4b5f0 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp.nvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp.si b/solr-8.3.1/server/solr/dash/data/index/_jp.si new file mode 100644 index 000000000..40cd02b98 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp.si differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp_1.liv b/solr-8.3.1/server/solr/dash/data/index/_jp_1.liv new file mode 100644 index 000000000..be94523f4 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp_1.liv differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.doc b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.doc new file mode 100644 index 000000000..90774bb6f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.doc differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.pos b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.pos new file mode 100644 index 000000000..b4814c1f7 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.pos differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.tim b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.tim new file mode 100644 index 000000000..f8a7871e1 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.tim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.tip b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.tip new file mode 100644 index 000000000..c29ac6ed5 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene50_0.tip differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene80_0.dvd b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene80_0.dvd new file mode 100644 index 000000000..41afd53b9 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene80_0.dvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene80_0.dvm b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene80_0.dvm new file mode 100644 index 000000000..527eed668 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jp_Lucene80_0.dvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq.dii b/solr-8.3.1/server/solr/dash/data/index/_jq.dii new file mode 100644 index 000000000..a0a86dfd0 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq.dii differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq.dim b/solr-8.3.1/server/solr/dash/data/index/_jq.dim new file mode 100644 index 000000000..e69c06061 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq.dim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq.fdt b/solr-8.3.1/server/solr/dash/data/index/_jq.fdt new file mode 100644 index 000000000..c49ed904f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq.fdt differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq.fdx b/solr-8.3.1/server/solr/dash/data/index/_jq.fdx new file mode 100644 index 000000000..85d62a39c Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq.fdx differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq.fnm b/solr-8.3.1/server/solr/dash/data/index/_jq.fnm new file mode 100644 index 000000000..b3aa23794 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq.fnm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq.nvd b/solr-8.3.1/server/solr/dash/data/index/_jq.nvd new file mode 100644 index 000000000..fb74de020 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq.nvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq.nvm b/solr-8.3.1/server/solr/dash/data/index/_jq.nvm new file mode 100644 index 000000000..b407b1b63 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq.nvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq.si b/solr-8.3.1/server/solr/dash/data/index/_jq.si new file mode 100644 index 000000000..cdf2673ca Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq.si differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq_2.liv b/solr-8.3.1/server/solr/dash/data/index/_jq_2.liv new file mode 100644 index 000000000..0ae2a2dc3 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq_2.liv differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.doc b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.doc new file mode 100644 index 000000000..91ae597e1 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.doc differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.pos b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.pos new file mode 100644 index 000000000..047dd7ae9 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.pos differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.tim b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.tim new file mode 100644 index 000000000..352a6b592 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.tim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.tip b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.tip new file mode 100644 index 000000000..ca0b2688d Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene50_0.tip differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene80_0.dvd b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene80_0.dvd new file mode 100644 index 000000000..7a5fbcef3 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene80_0.dvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene80_0.dvm b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene80_0.dvm new file mode 100644 index 000000000..228fc7b0a Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jq_Lucene80_0.dvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr.dii b/solr-8.3.1/server/solr/dash/data/index/_jr.dii new file mode 100644 index 000000000..7bec10455 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr.dii differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr.dim b/solr-8.3.1/server/solr/dash/data/index/_jr.dim new file mode 100644 index 000000000..cdf02c5fb Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr.dim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr.fdt b/solr-8.3.1/server/solr/dash/data/index/_jr.fdt new file mode 100644 index 000000000..183dda424 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr.fdt differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr.fdx b/solr-8.3.1/server/solr/dash/data/index/_jr.fdx new file mode 100644 index 000000000..96942bc74 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr.fdx differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr.fnm b/solr-8.3.1/server/solr/dash/data/index/_jr.fnm new file mode 100644 index 000000000..34731760f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr.fnm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr.si b/solr-8.3.1/server/solr/dash/data/index/_jr.si new file mode 100644 index 000000000..bc131eb25 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr.si differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr_1.liv b/solr-8.3.1/server/solr/dash/data/index/_jr_1.liv new file mode 100644 index 000000000..22da1aa4f Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr_1.liv differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.doc b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.doc new file mode 100644 index 000000000..94df5353c Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.doc differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.tim b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.tim new file mode 100644 index 000000000..2f078b0f1 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.tim differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.tip b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.tip new file mode 100644 index 000000000..b6239f17d Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene50_0.tip differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene80_0.dvd b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene80_0.dvd new file mode 100644 index 000000000..171be787e Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene80_0.dvd differ diff --git a/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene80_0.dvm b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene80_0.dvm new file mode 100644 index 000000000..f76033c91 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/_jr_Lucene80_0.dvm differ diff --git a/solr-8.3.1/server/solr/dash/data/index/segments_d b/solr-8.3.1/server/solr/dash/data/index/segments_d new file mode 100644 index 000000000..1e98e2f77 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/index/segments_d differ diff --git a/solr-8.3.1/server/solr/dash/data/index/write.lock b/solr-8.3.1/server/solr/dash/data/index/write.lock new file mode 100644 index 000000000..e69de29bb diff --git a/solr-8.3.1/server/solr/dash/data/tlog/tlog.0000000000000000011 b/solr-8.3.1/server/solr/dash/data/tlog/tlog.0000000000000000011 new file mode 100644 index 000000000..12ce36e19 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/tlog/tlog.0000000000000000011 differ diff --git a/solr-8.3.1/server/solr/dash/data/tlog/tlog.0000000000000000012 b/solr-8.3.1/server/solr/dash/data/tlog/tlog.0000000000000000012 new file mode 100644 index 000000000..c2322ffbe Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data/tlog/tlog.0000000000000000012 differ diff --git a/solr-8.3.1/server/solr/dash/data2/index/_199_1.liv b/solr-8.3.1/server/solr/dash/data2/index/_199_1.liv new file mode 100644 index 000000000..d339cd0c7 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data2/index/_199_1.liv differ diff --git a/solr-8.3.1/server/solr/dash/data2/index/_19h_1.liv b/solr-8.3.1/server/solr/dash/data2/index/_19h_1.liv new file mode 100644 index 000000000..de5c10cc7 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data2/index/_19h_1.liv differ diff --git a/solr-8.3.1/server/solr/dash/data2/index/write.lock b/solr-8.3.1/server/solr/dash/data2/index/write.lock new file mode 100644 index 000000000..e69de29bb diff --git a/solr-8.3.1/server/solr/dash/data2/tlog/tlog.0000000000000000012 b/solr-8.3.1/server/solr/dash/data2/tlog/tlog.0000000000000000012 new file mode 100644 index 000000000..039bba561 Binary files /dev/null and b/solr-8.3.1/server/solr/dash/data2/tlog/tlog.0000000000000000012 differ diff --git a/solr-8.3.1/server/tmp/start_1669159736908453662.properties b/solr-8.3.1/server/tmp/start_1669159736908453662.properties new file mode 100644 index 000000000..07a40cbdc --- /dev/null +++ b/solr-8.3.1/server/tmp/start_1669159736908453662.properties @@ -0,0 +1,11 @@ +#start.jar properties +#Wed Jan 08 14:37:59 UTC 2020 +java.version.platform=8 +java.version=1.8.0_211 +java.version.micro=0 +jetty.home=C\:\\gitstuff\\GitCode\\Dash-Web\\solr-8.3.1\\server +java.version.minor=8 +jetty.home.uri=file\:///C\:/gitstuff/GitCode/Dash-Web/solr-8.3.1/server +jetty.base=C\:\\gitstuff\\GitCode\\Dash-Web\\solr-8.3.1\\server +java.version.major=1 +jetty.base.uri=file\:///C\:/gitstuff/GitCode/Dash-Web/solr-8.3.1/server diff --git a/solr-8.3.1/server/tmp/start_5906520416860122978.properties b/solr-8.3.1/server/tmp/start_5906520416860122978.properties new file mode 100644 index 000000000..4177968f4 --- /dev/null +++ b/solr-8.3.1/server/tmp/start_5906520416860122978.properties @@ -0,0 +1,11 @@ +#start.jar properties +#Wed Jan 08 14:30:05 UTC 2020 +java.version.platform=8 +java.version=1.8.0_211 +java.version.micro=0 +jetty.home=c\:\\gitstuff\\GitCode\\Dash-Web\\solr-8.3.1\\server +java.version.minor=8 +jetty.home.uri=file\:///c\:/gitstuff/GitCode/Dash-Web/solr-8.3.1/server +jetty.base=c\:\\gitstuff\\GitCode\\Dash-Web\\solr-8.3.1\\server +java.version.major=1 +jetty.base.uri=file\:///c\:/gitstuff/GitCode/Dash-Web/solr-8.3.1/server diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index db2a3c298..a1196ee1c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -386,7 +386,7 @@ export class MainView extends React.Component { getScale={returnOne}>
-
+
{
); - return
e.stopPropagation()} className="parentDocumentSelector-linkFlyout"> - e.stopPropagation()} className="parentDocumentSelector-linkFlyout"> + -

^

+
; @@ -124,7 +124,7 @@ export class ButtonSelector extends React.Component<{ Document: Doc, Stack: any
); return e.stopPropagation()} className="buttonSelector"> - + ; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 63c17b1f6..29e7edd97 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -742,7 +742,8 @@ export class DocumentView extends DocComponent(Docu const highlightColors = ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"]; const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"]; - const highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc.viewType !== CollectionViewType.Linear; + let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc.viewType !== CollectionViewType.Linear; + highlighting = highlighting && this.props.focus !== emptyFunction; // bcz: hack to turn off highlighting onsidebar panel documents. need to flag a document as not highlightable in a more direct way return
Doc.BrushDoc(this.props.Document)} onPointerLeave={e => Doc.UnBrushDoc(this.props.Document)} diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index 4eb992d36..0825580b7 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -70,8 +70,7 @@ display: flex; flex-direction: column; height: 100%; - overflow: hidden; - overflow-y: auto; + overflow: visible; .no-result { width: 500px; diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 2f28ebf76..dd1ac7421 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -353,7 +353,8 @@ export class SearchBox extends React.Component {
{this._visibleElements}
diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss index 82ff96700..469f062b2 100644 --- a/src/client/views/search/SearchItem.scss +++ b/src/client/views/search/SearchItem.scss @@ -1,22 +1,14 @@ @import "../globalCssVariables"; -.search-overview { +.searchItem-overview { display: flex; flex-direction: reverse; justify-content: flex-end; z-index: 0; } -.link-count { - background: black; - border-radius: 20px; - color: white; - width: 15px; - text-align: center; - margin-top: 5px; -} .searchBox-placeholder, -.search-overview .search-item { +.searchItem-overview .searchItem { width: 100%; background: $light-color-secondary; border-color: $intermediate-color; @@ -26,19 +18,19 @@ max-height: 150px; height: auto; z-index: 0; - display: inline-block; - overflow: auto; + display: flex; + overflow: visible; - .main-search-info { + .searchItem-body { display: flex; flex-direction: row; width: 100%; - .search-title-container { + .searchItem-title-container { width: 100%; overflow: hidden; - .search-title { + .searchItem-title { text-transform: uppercase; text-align: left; width: 100%; @@ -46,75 +38,28 @@ } } - .search-info { + .searchItem-info { display: flex; justify-content: flex-end; - .link-container.item { - margin-left: auto; - margin-right: auto; - height: 26px; - width: 26px; - border-radius: 13px; - background: $dark-color; - color: $light-color-secondary; - display: flex; - justify-content: center; - align-items: center; - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - transform-origin: top right; - overflow: hidden; - position: relative; - - - .link-extended { - // display: none; - visibility: hidden; - opacity: 0; - position: relative; - z-index: 500; - overflow: hidden; - -webkit-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; - -moz-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; - -o-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; - transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; - // transition-delay: 1s; - } - - } - - .link-container.item:hover { - width: 70px; - } - - .link-container.item:hover .link-count { - opacity: 0; - } - - .link-container.item:hover .link-extended { - opacity: 1; - visibility: visible; - // display: inline; - } - .icon-icons { width: 50px } .icon-live { width: 175px; + height: 0px; } + .icon-icons { + height:auto; + } .icon-icons, .icon-live { - height: auto; margin: auto; - overflow: hidden; + overflow: visible; - .search-type { + .searchItem-type { display: inline-block; width: 100%; position: absolute; @@ -133,11 +78,11 @@ } } - .search-type:hover+.search-label { + .searchItem-type:hover+.searchItem-label { opacity: 1; } - .search-label { + .searchItem-label { font-size: 10; position: relative; right: 0px; @@ -151,8 +96,6 @@ } .icon-live:hover { - height: 175px; - .pdfBox-cont { img { width: 100% !important; @@ -161,42 +104,44 @@ } } - .search-info:hover { + .searchItem-info:hover { width: 60%; } } } -.search-item:hover~.searchBox-instances, +.searchItem:hover~.searchBox-instances, .searchBox-instances:hover, .searchBox-instances:active { opacity: 1; background: $lighter-alt-accent; - width:150px } -.search-item:hover { +.searchItem:hover { transition: all 0.2s; background: $lighter-alt-accent; } -.search-highlighting { +.searchItem-highlighting { overflow: hidden; text-overflow: ellipsis; white-space: pre; } .searchBox-instances { - float: left; opacity: 1; - width: 0px; + width:40px; + height:40px; + background: gray; transition: all 0.2s ease; color: black; overflow: hidden; + right:-100; + display:inline-block; } -.search-overview:hover { +.searchItem-overview:hover { z-index: 1; } diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index 673cb7937..32ba5d19d 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -17,11 +17,11 @@ import { SEARCH_THUMBNAIL_SIZE } from "../../views/globalCssVariables.scss"; import { CollectionViewType } from "../collections/CollectionView"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { ContextMenu } from "../ContextMenu"; -import { DocumentView } from "../nodes/DocumentView"; import { SearchBox } from "./SearchBox"; import "./SearchItem.scss"; import "./SelectorContextMenu.scss"; import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView"; +import { ButtonSelector, ParentDocSelector } from "../collections/ParentDocumentSelector"; export interface SearchItemProps { doc: Doc; @@ -188,24 +188,12 @@ export class SearchItem extends React.Component { layoutresult.indexOf(DocumentType.HIST) !== -1 ? faChartBar : layoutresult.indexOf(DocumentType.WEB) !== -1 ? faGlobeAsia : faCaretUp; - return
{ this._useIcons = false; this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); })} > + return
{ this._useIcons = false; this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); })} >
; } collectionRef = React.createRef(); - startDocDrag = () => { - const doc = this.props.doc; - const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); - if (isProto) { - return Doc.MakeDelegate(doc); - } else { - return Doc.MakeAlias(doc); - } - } - - @computed - get linkCount() { return DocListCast(this.props.doc.links).length; } @action pointerDown = (e: React.PointerEvent) => { e.preventDefault(); e.button === 0 && SearchBox.Instance.openSearch(e); } @@ -258,43 +246,62 @@ export class SearchItem extends React.Component { ContextMenu.Instance.displayMenu(e.clientX, e.clientY); } + _downX = 0; + _downY = 0; + _target: any; onPointerDown = (e: React.PointerEvent) => { + this._downX = e.clientX; + this._downY = e.clientY; e.stopPropagation(); - const doc = Doc.IsPrototype(this.props.doc) ? Doc.MakeDelegate(this.props.doc) : this.props.doc; - DragManager.StartDocumentDrag([e.currentTarget], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY); + this._target = e.currentTarget; + document.removeEventListener("pointermove", this.onPointerMoved); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointermove", this.onPointerMoved); + document.addEventListener("pointerup", this.onPointerUp); + } + onPointerMoved = (e: PointerEvent) => { + if (Math.abs(e.clientX - this._downX) > Utils.DRAG_THRESHOLD || + Math.abs(e.clientY - this._downY) > Utils.DRAG_THRESHOLD) { + console.log("DRAGGIGNG"); + document.removeEventListener("pointermove", this.onPointerMoved); + document.removeEventListener("pointerup", this.onPointerUp); + const doc = Doc.IsPrototype(this.props.doc) ? Doc.MakeDelegate(this.props.doc) : this.props.doc; + DragManager.StartDocumentDrag([this._target], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY); + } + } + onPointerUp = (e: PointerEvent) => { + document.removeEventListener("pointermove", this.onPointerMoved); + document.removeEventListener("pointerup", this.onPointerUp); + } + + @computed + get contextButton() { + return CollectionDockingView.AddRightSplit(doc, data)} />; } render() { const doc1 = Cast(this.props.doc.anchor1, Doc); const doc2 = Cast(this.props.doc.anchor2, Doc); - return ( -
-
-
-
-
-
{this.linkCount}
-
-
-
-
{StrCast(this.props.doc.title)}
-
{this.props.highlighting.length ? "Matched fields:" + this.props.highlighting.join(", ") : this.props.lines.length ? this.props.lines[0] : ""}
- {this.props.lines.filter((m, i) => i).map((l, i) =>
`${l}`
)} -
-
-
-
{this.DocumentIcon()}
-
{this.props.doc.type ? this.props.doc.type : "Other"}
-
-
+ return
+
+
+
+
{StrCast(this.props.doc.title)}
+
{this.props.highlighting.length ? "Matched fields:" + this.props.highlighting.join(", ") : this.props.lines.length ? this.props.lines[0] : ""}
+ {this.props.lines.filter((m, i) => i).map((l, i) =>
`${l}`
)}
-
+
+
+
{this.DocumentIcon()}
+
{this.props.doc.type ? this.props.doc.type : "Other"}
+
+
+
{(doc1 instanceof Doc && doc2 instanceof Doc) && this.props.doc.type === DocumentType.LINK ? : - } + this.contextButton}
- ); +
; } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From d8fc218f3481728f221ceacc60ac4bc553f8e295 Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Wed, 8 Jan 2020 12:50:56 -0500 Subject: starting something --- .../views/collections/CollectionDockingView.tsx | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 75d92105b..57c59def6 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -32,6 +32,7 @@ import React = require("react"); import { ButtonSelector } from './ParentDocumentSelector'; import { DocumentType } from '../../documents/DocumentTypes'; import { ComputedField } from '../../../new_fields/ScriptField'; +import { InteractionUtils } from '../../util/InteractionUtils'; library.add(faFile); const _global = (window /* browser */ || global /* node */) as any; @@ -493,6 +494,28 @@ export class CollectionDockingView extends React.Component { + // if (e.targetTouches.length === 2) { + // let pt1 = e.targetTouches.item(0); + // let pt2 = e.targetTouches.item(1); + // let threshold = 40 * window.devicePixelRatio; + // if (pt1 && pt2 && InteractionUtils.TwoPointEuclidist(pt1, pt2) < threshold) { + // let edgeThreshold = 30 * window.devicePixelRatio; + // let center = InteractionUtils.CenterPoint([pt1, pt2]); + // let stackRect: DOMRect = stack.element.getBoundingClientRect(); + // let nearLeft = center.X - stackRect.x < edgeThreshold; + // let nearTop = center.Y - stackRect.y < edgeThreshold; + // let nearRight = stackRect.right - center.X < edgeThreshold; + // let nearBottom = stackRect.bottom - center.Y < edgeThreshold; + // let ns = [nearLeft, nearTop, nearRight, nearBottom].filter(n => n); + // if (ns.length === 1) { + + // } + // } + // } + // }); stack.header.controlsContainer.find('.lm_close') //get the close icon .off('click') //unbind the current click handler .click(action(async function () { -- cgit v1.2.3-70-g09d2 From 540bda7295f6ee7c2eed848598de6f5df74b2723 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 9 Jan 2020 10:04:24 -0500 Subject: fixed many warnings --- src/client/util/TooltipTextMenu.tsx | 4 +- .../CollectionFreeFormLinkView.tsx | 12 +- src/client/views/nodes/DocumentView.tsx | 1 - src/pen-gestures/ndollar.ts | 122 +++++++++++---------- 4 files changed, 71 insertions(+), 68 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 8aa304fad..e56930624 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -80,7 +80,7 @@ export class TooltipTextMenu { span.appendChild(svg); return span; - } + }; const basicItems = [ // init basicItems in minimized toolbar -- paths to svgs are obtained from fontawesome { mark: schema.marks.strong, dom: svgIcon("strong", "Bold", "M333.49 238a122 122 0 0 0 27-65.21C367.87 96.49 308 32 233.42 32H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h31.87v288H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h209.32c70.8 0 134.14-51.75 141-122.4 4.74-48.45-16.39-92.06-50.83-119.6zM145.66 112h87.76a48 48 0 0 1 0 96h-87.76zm87.76 288h-87.76V288h87.76a56 56 0 0 1 0 112z") }, @@ -883,7 +883,7 @@ export class TooltipTextMenu { if (!lastState || !lastState.doc.eq(view.state.doc) || !lastState.selection.eq(view.state.selection)) { // UPDATE LINK DROPDOWN - const linkTarget = await this.getTextLinkTargetTitle() + const linkTarget = await this.getTextLinkTargetTitle(); const linkDom = this.createLinkTool(linkTarget ? true : false).render(this.view).dom; const linkDropdownDom = this.createLinkDropdown(linkTarget).render(this.view).dom; this.linkDom && this.tooltip.replaceChild(linkDom, this.linkDom); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 178a5bcdc..b8fbaef5c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -54,8 +54,8 @@ export class CollectionFreeFormLinkView extends React.Component { (this.props.A.props.Document[(this.props.A.props as any).fieldKey] as Doc); - let m = targetBhyperlink.getBoundingClientRect(); - let mp = this.props.A.props.ScreenToLocalTransform().transformPoint(m.right, m.top + 5); + const m = targetBhyperlink.getBoundingClientRect(); + const mp = this.props.A.props.ScreenToLocalTransform().transformPoint(m.right, m.top + 5); this.props.A.props.Document[afield + "_x"] = mp[0] / this.props.A.props.PanelWidth() * 100; this.props.A.props.Document[afield + "_y"] = mp[1] / this.props.A.props.PanelHeight() * 100; }, 0); @@ -66,8 +66,8 @@ export class CollectionFreeFormLinkView extends React.Component { (this.props.B.props.Document[(this.props.B.props as any).fieldKey] as Doc); - let m = targetAhyperlink.getBoundingClientRect(); - let mp = this.props.B.props.ScreenToLocalTransform().transformPoint(m.right, m.top + 5); + const m = targetAhyperlink.getBoundingClientRect(); + const mp = this.props.B.props.ScreenToLocalTransform().transformPoint(m.right, m.top + 5); this.props.B.props.Document[afield + "_x"] = mp[0] / this.props.B.props.PanelWidth() * 100; this.props.B.props.Document[afield + "_y"] = mp[1] / this.props.B.props.PanelHeight() * 100; }, 0); @@ -93,8 +93,8 @@ export class CollectionFreeFormLinkView extends React.Component(Docu document.removeEventListener("touchend", this.onTouchEnd); document.addEventListener("touchend", this.onTouchEnd); if ((e.nativeEvent as any).formattedHandled) e.stopPropagation(); - console.log("down") } } diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts index 12c2b25bb..872c524d6 100644 --- a/src/pen-gestures/ndollar.ts +++ b/src/pen-gestures/ndollar.ts @@ -95,7 +95,7 @@ export class Unistroke { constructor(public Name: string, useBoundedRotationInvariance: boolean, points: Point[]) { this.Points = Resample(points, NumPoints); - var radians = IndicativeAngle(this.Points); + const radians = IndicativeAngle(this.Points); this.Points = RotateBy(this.Points, -radians); this.Points = ScaleDimTo(this.Points, SquareSize, OneDThreshold); if (useBoundedRotationInvariance) { @@ -117,14 +117,14 @@ export class Multistroke { { this.NumStrokes = strokes.length; // number of individual strokes - var order = new Array(strokes.length); // array of integer indices + const order = new Array(strokes.length); // array of integer indices for (var i = 0; i < strokes.length; i++) { order[i] = i; // initialize } - var orders = new Array(); // array of integer arrays + const orders = new Array(); // array of integer arrays HeapPermute(strokes.length, order, /*out*/ orders); - var unistrokes = MakeUnistrokes(strokes, orders); // returns array of point arrays + const unistrokes = MakeUnistrokes(strokes, orders); // returns array of point arrays this.Unistrokes = new Array(unistrokes.length); // unistrokes for this multistroke for (var j = 0; j < unistrokes.length; j++) { this.Unistrokes[j] = new Unistroke(this.Name, useBoundedRotationInvariance, unistrokes[j]); @@ -247,15 +247,15 @@ export class NDollarRecognizer { } Recognize = (strokes: any[], useBoundedRotationInvariance: boolean = false, requireSameNoOfStrokes: boolean = false, useProtractor: boolean = true) => { - var t0 = Date.now(); - var points = CombineStrokes(strokes); // make one connected unistroke from the given strokes - var candidate = new Unistroke("", useBoundedRotationInvariance, points); + const t0 = Date.now(); + const points = CombineStrokes(strokes); // make one connected unistroke from the given strokes + const candidate = new Unistroke("", useBoundedRotationInvariance, points); var u = -1; var b = +Infinity; for (var i = 0; i < this.Multistrokes.length; i++) // for each multistroke template { - if (!requireSameNoOfStrokes || strokes.length == this.Multistrokes[i].NumStrokes) // optional -- only attempt match when same # of component strokes + if (!requireSameNoOfStrokes || strokes.length === this.Multistrokes[i].NumStrokes) // optional -- only attempt match when same # of component strokes { for (var j = 0; j < this.Multistrokes[i].Unistrokes.length; j++) // for each unistroke within this multistroke { @@ -276,15 +276,15 @@ export class NDollarRecognizer { } } } - var t1 = Date.now(); - return (u == -1) ? null : new Result(this.Multistrokes[u].Name, useProtractor ? (1.0 - b) : (1.0 - b / HalfDiagonal), t1 - t0); + const t1 = Date.now(); + return (u === -1) ? null : new Result(this.Multistrokes[u].Name, useProtractor ? (1.0 - b) : (1.0 - b / HalfDiagonal), t1 - t0); } AddGesture = (name: string, useBoundedRotationInvariance: boolean, strokes: any[]) => { this.Multistrokes[this.Multistrokes.length] = new Multistroke(name, useBoundedRotationInvariance, strokes); var num = 0; for (var i = 0; i < this.Multistrokes.length; i++) { - if (this.Multistrokes[i].Name == name) { + if (this.Multistrokes[i].Name === name) { num++; } } @@ -302,17 +302,17 @@ export class NDollarRecognizer { // Private helper functions from here on down // function HeapPermute(n: number, order: any[], /*out*/ orders: any[]) { - if (n == 1) { + if (n === 1) { orders[orders.length] = order.slice(); // append copy } else { for (var i = 0; i < n; i++) { HeapPermute(n - 1, order, orders); - if (n % 2 == 1) { // swap 0, n-1 - var tmp = order[0]; + if (n % 2 === 1) { // swap 0, n-1 + const tmp = order[0]; order[0] = order[n - 1]; order[n - 1] = tmp; } else { // swap i, n-1 - var tmp = order[i]; + const tmp = order[i]; order[i] = order[n - 1]; order[n - 1] = tmp; } @@ -321,14 +321,14 @@ function HeapPermute(n: number, order: any[], /*out*/ orders: any[]) { } function MakeUnistrokes(strokes: any, orders: any) { - var unistrokes = new Array(); // array of point arrays + const unistrokes = new Array(); // array of point arrays for (var r = 0; r < orders.length; r++) { for (var b = 0; b < Math.pow(2, orders[r].length); b++) // use b's bits for directions { - var unistroke = new Array(); // array of points + const unistroke = new Array(); // array of points for (var i = 0; i < orders[r].length; i++) { var pts; - if (((b >> i) & 1) == 1) {// is b's bit at index i on? + if (((b >> i) & 1) === 1) {// is b's bit at index i on? pts = strokes[orders[r][i]].slice().reverse(); // copy and reverse } else { @@ -345,69 +345,71 @@ function MakeUnistrokes(strokes: any, orders: any) { } function CombineStrokes(strokes: any) { - var points = new Array(); + const points = new Array(); for (var s = 0; s < strokes.length; s++) { - for (var p = 0; p < strokes[s].length; p++) + for (var p = 0; p < strokes[s].length; p++) { points[points.length] = new Point(strokes[s][p].X, strokes[s][p].Y); + } } return points; } function Resample(points: any, n: any) { - var I = PathLength(points) / (n - 1); // interval length + const I = PathLength(points) / (n - 1); // interval length var D = 0.0; - var newpoints = new Array(points[0]); + const newpoints = new Array(points[0]); for (var i = 1; i < points.length; i++) { - var d = Distance(points[i - 1], points[i]); + const d = Distance(points[i - 1], points[i]); if ((D + d) >= I) { - var qx = points[i - 1].X + ((I - D) / d) * (points[i].X - points[i - 1].X); - var qy = points[i - 1].Y + ((I - D) / d) * (points[i].Y - points[i - 1].Y); - var q = new Point(qx, qy); + const qx = points[i - 1].X + ((I - D) / d) * (points[i].X - points[i - 1].X); + const qy = points[i - 1].Y + ((I - D) / d) * (points[i].Y - points[i - 1].Y); + const q = new Point(qx, qy); newpoints[newpoints.length] = q; // append new point 'q' points.splice(i, 0, q); // insert 'q' at position i in points s.t. 'q' will be the next i D = 0.0; } else D += d; } - if (newpoints.length == n - 1) // somtimes we fall a rounding-error short of adding the last point, so add it if so + if (newpoints.length === n - 1) {// sometimes we fall a rounding-error short of adding the last point, so add it if so newpoints[newpoints.length] = new Point(points[points.length - 1].X, points[points.length - 1].Y); + } return newpoints; } function IndicativeAngle(points: any) { - var c = Centroid(points); + const c = Centroid(points); return Math.atan2(c.Y - points[0].Y, c.X - points[0].X); } function RotateBy(points: any, radians: any) // rotates points around centroid { - var c = Centroid(points); - var cos = Math.cos(radians); - var sin = Math.sin(radians); - var newpoints = new Array(); + const c = Centroid(points); + const cos = Math.cos(radians); + const sin = Math.sin(radians); + const newpoints = new Array(); for (var i = 0; i < points.length; i++) { - var qx = (points[i].X - c.X) * cos - (points[i].Y - c.Y) * sin + c.X - var qy = (points[i].X - c.X) * sin + (points[i].Y - c.Y) * cos + c.Y; + const qx = (points[i].X - c.X) * cos - (points[i].Y - c.Y) * sin + c.X; + const qy = (points[i].X - c.X) * sin + (points[i].Y - c.Y) * cos + c.Y; newpoints[newpoints.length] = new Point(qx, qy); } return newpoints; } function ScaleDimTo(points: any, size: any, ratio1D: any) // scales bbox uniformly for 1D, non-uniformly for 2D { - var B = BoundingBox(points); - var uniformly = Math.min(B.Width / B.Height, B.Height / B.Width) <= ratio1D; // 1D or 2D gesture test - var newpoints = new Array(); + const B = BoundingBox(points); + const uniformly = Math.min(B.Width / B.Height, B.Height / B.Width) <= ratio1D; // 1D or 2D gesture test + const newpoints = new Array(); for (var i = 0; i < points.length; i++) { - var qx = uniformly ? points[i].X * (size / Math.max(B.Width, B.Height)) : points[i].X * (size / B.Width); - var qy = uniformly ? points[i].Y * (size / Math.max(B.Width, B.Height)) : points[i].Y * (size / B.Height); + const qx = uniformly ? points[i].X * (size / Math.max(B.Width, B.Height)) : points[i].X * (size / B.Width); + const qy = uniformly ? points[i].Y * (size / Math.max(B.Width, B.Height)) : points[i].Y * (size / B.Height); newpoints[newpoints.length] = new Point(qx, qy); } return newpoints; } function TranslateTo(points: any, pt: any) // translates points' centroid { - var c = Centroid(points); - var newpoints = new Array(); + const c = Centroid(points); + const newpoints = new Array(); for (var i = 0; i < points.length; i++) { - var qx = points[i].X + pt.X - c.X; - var qy = points[i].Y + pt.Y - c.Y; + const qx = points[i].X + pt.X - c.X; + const qy = points[i].Y + pt.Y - c.Y; newpoints[newpoints.length] = new Point(qx, qy); } return newpoints; @@ -417,21 +419,21 @@ function Vectorize(points: any, useBoundedRotationInvariance: any) // for Protra var cos = 1.0; var sin = 0.0; if (useBoundedRotationInvariance) { - var iAngle = Math.atan2(points[0].Y, points[0].X); - var baseOrientation = (Math.PI / 4.0) * Math.floor((iAngle + Math.PI / 8.0) / (Math.PI / 4.0)); + const iAngle = Math.atan2(points[0].Y, points[0].X); + const baseOrientation = (Math.PI / 4.0) * Math.floor((iAngle + Math.PI / 8.0) / (Math.PI / 4.0)); cos = Math.cos(baseOrientation - iAngle); sin = Math.sin(baseOrientation - iAngle); } var sum = 0.0; - var vector = new Array(); + const vector = new Array(); for (var i = 0; i < points.length; i++) { - var newX = points[i].X * cos - points[i].Y * sin; - var newY = points[i].Y * cos + points[i].X * sin; + const newX = points[i].X * cos - points[i].Y * sin; + const newY = points[i].Y * cos + points[i].X * sin; vector[vector.length] = newX; vector[vector.length] = newY; sum += newX * newX + newY * newY; } - var magnitude = Math.sqrt(sum); + const magnitude = Math.sqrt(sum); for (var i = 0; i < vector.length; i++) { vector[i] /= magnitude; } @@ -445,7 +447,7 @@ function OptimalCosineDistance(v1: any, v2: any) // for Protractor a += v1[i] * v2[i] + v1[i + 1] * v2[i + 1]; b += v1[i] * v2[i + 1] - v1[i + 1] * v2[i]; } - var angle = Math.atan(b / a); + const angle = Math.atan(b / a); return Math.acos(a * Math.cos(angle) + b * Math.sin(angle)); } function DistanceAtBestAngle(points: any, T: any, a: any, b: any, threshold: any) { @@ -471,7 +473,7 @@ function DistanceAtBestAngle(points: any, T: any, a: any, b: any, threshold: any return Math.min(f1, f2); } function DistanceAtAngle(points: any, T: any, radians: any) { - var newpoints = RotateBy(points, radians); + const newpoints = RotateBy(points, radians); return PathDistance(newpoints, T.Points); } function Centroid(points: any) { @@ -497,33 +499,35 @@ function BoundingBox(points: any) { function PathDistance(pts1: any, pts2: any) // average distance between corresponding points in two paths { var d = 0.0; - for (var i = 0; i < pts1.length; i++) // assumes pts1.length == pts2.length + for (var i = 0; i < pts1.length; i++) {// assumes pts1.length == pts2.length d += Distance(pts1[i], pts2[i]); + } return d / pts1.length; } function PathLength(points: any) // length traversed by a point path { var d = 0.0; - for (var i = 1; i < points.length; i++) + for (var i = 1; i < points.length; i++) { d += Distance(points[i - 1], points[i]); + } return d; } function Distance(p1: any, p2: any) // distance between two points { - var dx = p2.X - p1.X; - var dy = p2.Y - p1.Y; + const dx = p2.X - p1.X; + const dy = p2.Y - p1.Y; return Math.sqrt(dx * dx + dy * dy); } function CalcStartUnitVector(points: any, index: any) // start angle from points[0] to points[index] normalized as a unit vector { - var v = new Point(points[index].X - points[0].X, points[index].Y - points[0].Y); - var len = Math.sqrt(v.X * v.X + v.Y * v.Y); + const v = new Point(points[index].X - points[0].X, points[index].Y - points[0].Y); + const len = Math.sqrt(v.X * v.X + v.Y * v.Y); return new Point(v.X / len, v.Y / len); } function AngleBetweenUnitVectors(v1: any, v2: any) // gives acute angle between unit vectors from (0,0) to v1, and (0,0) to v2 { - var n = (v1.X * v2.X + v1.Y * v2.Y); - var c = Math.max(-1.0, Math.min(1.0, n)); // ensure [-1,+1] + const n = (v1.X * v2.X + v1.Y * v2.Y); + const c = Math.max(-1.0, Math.min(1.0, n)); // ensure [-1,+1] return Math.acos(c); // arc cosine of the vector dot product } function Deg2Rad(d: any) { return (d * Math.PI / 180.0); } \ No newline at end of file -- cgit v1.2.3-70-g09d2