mirror of
https://github.com/penpot/penpot.git
synced 2025-05-10 22:16:38 +02:00
WIP: partial grid.
This commit is contained in:
parent
64c9360b38
commit
a2c313dfc0
6 changed files with 266 additions and 60 deletions
|
@ -16,4 +16,5 @@
|
||||||
(println "BOOTSTRAP")
|
(println "BOOTSTRAP")
|
||||||
(ui/init)
|
(ui/init)
|
||||||
(rs/emit! (dl/load-data))
|
(rs/emit! (dl/load-data))
|
||||||
(rx/on-value s/stream #(dl/persist-state %))))
|
(rx/on-value s/stream #(dl/persist-state %))
|
||||||
|
1))
|
||||||
|
|
|
@ -15,9 +15,20 @@
|
||||||
(reify
|
(reify
|
||||||
rs/UpdateEvent
|
rs/UpdateEvent
|
||||||
(-apply-update [_ state]
|
(-apply-update [_ state]
|
||||||
(println "KAKAKA" (get-in state [:workspace :visible-pagebar]))
|
(update-in state [:workspace :pagesbar-enabled] (fnil not false)))
|
||||||
(update-in state [:workspace :visible-pagebar] (fnil not false)))
|
|
||||||
|
|
||||||
IPrintWithWriter
|
IPrintWithWriter
|
||||||
(-pr-writer [mv writer _]
|
(-pr-writer [mv writer _]
|
||||||
(-write writer "#<event:u.s.p/toggle-pagebar>"))))
|
(-write writer "#<event:u.s.p/toggle-pagebar>"))))
|
||||||
|
|
||||||
|
(defn toggle-grid
|
||||||
|
[]
|
||||||
|
(reify
|
||||||
|
rs/UpdateEvent
|
||||||
|
(-apply-update [_ state]
|
||||||
|
(println "toggle-grid")
|
||||||
|
(update-in state [:workspace :grid-enabled] (fnil not false)))
|
||||||
|
|
||||||
|
IPrintWithWriter
|
||||||
|
(-pr-writer [mv writer _]
|
||||||
|
(-write writer "#<event:u.s.p/toggle-grid>"))))
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
(defn workspace-render
|
(defn workspace-render
|
||||||
[own projectid]
|
[own projectid]
|
||||||
|
(println "workspace-render")
|
||||||
(html
|
(html
|
||||||
[:div
|
[:div
|
||||||
(wb/header)
|
(wb/header)
|
||||||
|
@ -30,7 +31,7 @@
|
||||||
(wr/v-rule)
|
(wr/v-rule)
|
||||||
|
|
||||||
;; Canvas
|
;; Canvas
|
||||||
;; (wa/working-area)
|
(wa/workarea)
|
||||||
;; (working-area conn @open-toolboxes page project shapes (rum/react ws/zoom) (rum/react ws/grid?))
|
;; (working-area conn @open-toolboxes page project shapes (rum/react ws/zoom) (rum/react ws/grid?))
|
||||||
;; ;; Aside
|
;; ;; Aside
|
||||||
;; (when-not (empty? @open-toolboxes)
|
;; (when-not (empty? @open-toolboxes)
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
(as-> (l/in [:workspace]) $
|
(as-> (l/in [:workspace]) $
|
||||||
(l/focus-atom $ s/state)))
|
(l/focus-atom $ s/state)))
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Streams
|
;; Streams
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -51,6 +50,16 @@
|
||||||
(defonce top-scroll (rx/to-atom top-scroll-s))
|
(defonce top-scroll (rx/to-atom top-scroll-s))
|
||||||
(defonce left-scroll (rx/to-atom left-scroll-s))
|
(defonce left-scroll (rx/to-atom left-scroll-s))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Constants
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(def viewport-height 3000)
|
||||||
|
(def viewport-width 3000)
|
||||||
|
|
||||||
|
(def document-start-x 50)
|
||||||
|
(def document-start-y 50)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Header
|
;; Header
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -67,49 +76,52 @@
|
||||||
|
|
||||||
(defn header-render
|
(defn header-render
|
||||||
[own]
|
[own]
|
||||||
(let [page (rum/react page-state)
|
(letfn [(toggle-pagesbar [e]
|
||||||
toggle #(rs/emit! (dw/toggle-pagesbar))]
|
(rs/emit! (dw/toggle-pagesbar)))
|
||||||
(html
|
(toggle-grid [e]
|
||||||
[:header#workspace-bar.workspace-bar
|
(rs/emit! (dw/toggle-grid)))]
|
||||||
[:div.main-icon
|
(let [page (rum/react page-state)]
|
||||||
(nav/link (r/route-for :dashboard/projects) i/logo-icon)]
|
(html
|
||||||
[:div.project-tree-btn
|
[:header#workspace-bar.workspace-bar
|
||||||
{:on-click toggle}
|
[:div.main-icon
|
||||||
i/project-tree
|
(nav/link (r/route-for :dashboard/projects) i/logo-icon)]
|
||||||
[:span (:name page)]]
|
[:div.project-tree-btn
|
||||||
[:div.workspace-options
|
{:on-click toggle-pagesbar}
|
||||||
[:ul.options-btn
|
i/project-tree
|
||||||
[:li.tooltip.tooltip-bottom {:alt "Undo (Ctrl + Z)"}
|
[:span (:name page)]]
|
||||||
i/undo]
|
[:div.workspace-options
|
||||||
[:li.tooltip.tooltip-bottom {:alt "Redo (Ctrl + Shift + Z)"}
|
[:ul.options-btn
|
||||||
i/redo]]
|
[:li.tooltip.tooltip-bottom {:alt "Undo (Ctrl + Z)"}
|
||||||
[:ul.options-btn
|
i/undo]
|
||||||
;; TODO: refactor
|
[:li.tooltip.tooltip-bottom {:alt "Redo (Ctrl + Shift + Z)"}
|
||||||
[:li.tooltip.tooltip-bottom
|
i/redo]]
|
||||||
{:alt "Export (Ctrl + E)"}
|
[:ul.options-btn
|
||||||
;; page-title
|
;; TODO: refactor
|
||||||
[:a {:download (str (:name page) ".svg")
|
[:li.tooltip.tooltip-bottom
|
||||||
:href "#" :on-click on-download-clicked}
|
{:alt "Export (Ctrl + E)"}
|
||||||
i/export]]
|
;; page-title
|
||||||
[:li.tooltip.tooltip-bottom
|
[:a {:download (str (:name page) ".svg")
|
||||||
{:alt "Image (Ctrl + I)"}
|
:href "#" :on-click on-download-clicked}
|
||||||
i/image]]
|
i/export]]
|
||||||
[:ul.options-btn
|
[:li.tooltip.tooltip-bottom
|
||||||
[:li.tooltip.tooltip-bottom
|
{:alt "Image (Ctrl + I)"}
|
||||||
{:alt "Ruler (Ctrl + R)"}
|
i/image]]
|
||||||
i/ruler]
|
[:ul.options-btn
|
||||||
[:li.tooltip.tooltip-bottom
|
[:li.tooltip.tooltip-bottom
|
||||||
{:alt "Grid (Ctrl + G)"
|
{:alt "Ruler (Ctrl + R)"}
|
||||||
:class (when false "selected")
|
i/ruler]
|
||||||
:on-click (constantly nil)}
|
[:li.tooltip.tooltip-bottom
|
||||||
i/grid]
|
{:alt "Grid (Ctrl + G)"
|
||||||
[:li.tooltip.tooltip-bottom
|
:class (when false "selected")
|
||||||
{:alt "Align (Ctrl + A)"}
|
:on-click toggle-grid}
|
||||||
i/alignment]
|
i/grid]
|
||||||
[:li.tooltip.tooltip-bottom
|
[:li.tooltip.tooltip-bottom
|
||||||
{:alt "Organize (Ctrl + O)"}
|
{:alt "Align (Ctrl + A)"}
|
||||||
i/organize]]]
|
i/alignment]
|
||||||
(ui.u/user)])))
|
[:li.tooltip.tooltip-bottom
|
||||||
|
{:alt "Organize (Ctrl + O)"}
|
||||||
|
i/organize]]]
|
||||||
|
(ui.u/user)]))))
|
||||||
|
|
||||||
(def header
|
(def header
|
||||||
(util/component
|
(util/component
|
||||||
|
@ -272,7 +284,7 @@
|
||||||
project (rum/react project-state)]
|
project (rum/react project-state)]
|
||||||
(html
|
(html
|
||||||
[:div#project-bar.project-bar
|
[:div#project-bar.project-bar
|
||||||
(when-not (:visible-pagebar workspace false)
|
(when-not (:pagesbar-enabled workspace false)
|
||||||
{:class "toggle"})
|
{:class "toggle"})
|
||||||
(if (:edit @local)
|
(if (:edit @local)
|
||||||
(project-sidebar-form local)
|
(project-sidebar-form local)
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
;; Coordinates Debug
|
;; Coordinates Debug
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defonce canvas-coordinates (atom {}))
|
(defonce canvas-coordinates (atom [1 1]))
|
||||||
|
|
||||||
(defn coordenates-render
|
(defn coordenates-render
|
||||||
[]
|
[]
|
||||||
|
@ -23,12 +23,13 @@
|
||||||
[:div
|
[:div
|
||||||
{:style {:position "absolute" :left "80px" :top "20px"}}
|
{:style {:position "absolute" :left "80px" :top "20px"}}
|
||||||
[:table
|
[:table
|
||||||
[:tr
|
[:tbody
|
||||||
[:td "X:"]
|
[:tr
|
||||||
[:td (or x 1)]]
|
[:td "X:"]
|
||||||
[:tr
|
[:td x]]
|
||||||
[:td "Y:"]
|
[:tr
|
||||||
[:td y]]]])))
|
[:td "Y:"]
|
||||||
|
[:td y]]]]])))
|
||||||
|
|
||||||
(def coordinates
|
(def coordinates
|
||||||
(util/component
|
(util/component
|
||||||
|
@ -46,7 +47,179 @@
|
||||||
(util/component
|
(util/component
|
||||||
{:render background-render
|
{:render background-render
|
||||||
:name "background"
|
:name "background"
|
||||||
:mixins [rum/static]}))
|
:mixins [util/static]}))
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Grid
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(def ^:static grid-color "#cccccc")
|
||||||
|
|
||||||
|
(defn grid-render
|
||||||
|
[own enabled? width height start-width start-height zoom]
|
||||||
|
(println "grid-render")
|
||||||
|
(letfn [(vertical-line [position value padding]
|
||||||
|
(let [ticks-mod (/ 100 zoom)
|
||||||
|
step-size (/ 10 zoom)]
|
||||||
|
(if (< (mod value ticks-mod) step-size)
|
||||||
|
(html [:line {:key position
|
||||||
|
:y1 padding
|
||||||
|
:y2 width
|
||||||
|
:x1 position
|
||||||
|
:x2 position
|
||||||
|
:stroke grid-color
|
||||||
|
:stroke-width (/ 0.5 zoom)
|
||||||
|
:opacity 0.75}])
|
||||||
|
(html [:line {:key position
|
||||||
|
:y1 padding
|
||||||
|
:y2 width
|
||||||
|
:x1 position
|
||||||
|
:x2 position
|
||||||
|
:stroke grid-color
|
||||||
|
:stroke-width (/ 0.5 zoom)
|
||||||
|
:opacity 0.25}]))))
|
||||||
|
(horizontal-line [position value padding]
|
||||||
|
(let [ticks-mod (/ 100 zoom)
|
||||||
|
step-size (/ 10 zoom)]
|
||||||
|
(if (< (mod value ticks-mod) step-size)
|
||||||
|
(html [:line {:key position
|
||||||
|
:y1 position
|
||||||
|
:y2 position
|
||||||
|
:x1 padding
|
||||||
|
:x2 height
|
||||||
|
:stroke grid-color
|
||||||
|
:stroke-width (/ 0.5 zoom)
|
||||||
|
:opacity 0.75}])
|
||||||
|
(html [:line {:key position
|
||||||
|
:y1 position
|
||||||
|
:y2 position
|
||||||
|
:x1 padding
|
||||||
|
:x2 height
|
||||||
|
:stroke grid-color
|
||||||
|
:stroke-width (/ 0.5 zoom)
|
||||||
|
:opacity 0.25}]))))]
|
||||||
|
(let [padding (* 20 zoom)
|
||||||
|
ticks-mod (/ 100 zoom)
|
||||||
|
step-size (/ 10 zoom)
|
||||||
|
vertical-ticks (range (- padding start-height)
|
||||||
|
(- height start-height padding) step-size)
|
||||||
|
horizontal-ticks (range (- padding start-width)
|
||||||
|
(- width start-width padding) step-size)]
|
||||||
|
(html
|
||||||
|
[:g.grid
|
||||||
|
{:style {:display (if enabled? "block" "none")}}
|
||||||
|
(for [tick vertical-ticks]
|
||||||
|
(let [position (+ tick start-width)
|
||||||
|
line (vertical-line position tick padding)]
|
||||||
|
(rum/with-key line (str "tick-" tick))))
|
||||||
|
(for [tick horizontal-ticks]
|
||||||
|
(let [position (+ tick start-height)
|
||||||
|
line (horizontal-line position tick padding)]
|
||||||
|
(rum/with-key line (str "tick-" tick))))]))))
|
||||||
|
|
||||||
|
|
||||||
|
(def grid
|
||||||
|
(util/component
|
||||||
|
{:render grid-render
|
||||||
|
:name "grid"
|
||||||
|
:mixins [util/static]}))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Canvas
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; (rum/defc canvas < rum/reactive
|
||||||
|
;; shapes-push-mixin
|
||||||
|
;; (mx/cmds-mixin
|
||||||
|
;; [::draw draw! (fn [[conn page] shape]
|
||||||
|
;; (actions/draw-shape conn page shape))]
|
||||||
|
|
||||||
|
;; [::move move! (fn [[conn] selections]
|
||||||
|
;; (actions/update-shapes conn selections))])
|
||||||
|
;; [conn
|
||||||
|
;; page
|
||||||
|
;; shapes
|
||||||
|
;; {:keys [viewport-height
|
||||||
|
;; viewport-width
|
||||||
|
;; document-start-x
|
||||||
|
;; document-start-y]}]
|
||||||
|
|
||||||
|
(defn canvas-render
|
||||||
|
[]
|
||||||
|
(let [page (rum/react wb/page-state)
|
||||||
|
page-width (:width page)
|
||||||
|
page-height (:height page)
|
||||||
|
;; selection-uuids (rum/react selected-ids)
|
||||||
|
;; selected-shapes (rum/react selected-shapes)
|
||||||
|
;; raw-shapes (into []
|
||||||
|
;; (comp
|
||||||
|
;; (filter :shape/visible?)
|
||||||
|
;; (filter #(not (contains? selection-uuids (:shape/uuid %))))
|
||||||
|
;; (map :shape/data))
|
||||||
|
;; shapes)
|
||||||
|
]
|
||||||
|
(html
|
||||||
|
[:svg#page-canvas
|
||||||
|
{:x wb/document-start-x
|
||||||
|
:y wb/document-start-y
|
||||||
|
:width page-width
|
||||||
|
:height page-height
|
||||||
|
;; :on-mouse-down cs/on-mouse-down
|
||||||
|
;; :on-mouse-up cs/on-mouse-up
|
||||||
|
}
|
||||||
|
(background)
|
||||||
|
#_(apply vector :svg#page-layout (map shapes/shape->svg raw-shapes))
|
||||||
|
#_(when-let [shape (rum/react drawing)]
|
||||||
|
(shapes/shape->drawing-svg shape))
|
||||||
|
#_(when-not (empty? selected-shapes)
|
||||||
|
(let [rs selected-shapes]
|
||||||
|
(vec (cons :g
|
||||||
|
(concat
|
||||||
|
(map shapes/shape->selected-svg rs)
|
||||||
|
(map shapes/shape->svg rs))))))])))
|
||||||
|
|
||||||
|
(def canvas
|
||||||
|
(util/component
|
||||||
|
{:render canvas-render
|
||||||
|
:name "canvas"
|
||||||
|
:mixins [rum/reactive]}))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Viewport
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn viewport-render
|
||||||
|
[]
|
||||||
|
(let [workspace (rum/react wb/workspace-state)
|
||||||
|
zoom 1]
|
||||||
|
(println "viewport-render" (:grid-enabled workspace true))
|
||||||
|
(html
|
||||||
|
[:svg#viewport
|
||||||
|
{:width wb/viewport-height
|
||||||
|
:height wb/viewport-width}
|
||||||
|
[:g.zoom
|
||||||
|
{:transform (str "scale(" zoom ", " zoom ")")}
|
||||||
|
(canvas)
|
||||||
|
#_(canvas conn
|
||||||
|
page
|
||||||
|
shapes
|
||||||
|
{:viewport-height wb/viewport-height
|
||||||
|
:viewport-width wb/viewport-width
|
||||||
|
:document-start-x wb/document-start-x
|
||||||
|
:document-start-y wb/document-start-y})
|
||||||
|
(grid (:grid-enabled workspace true)
|
||||||
|
wb/viewport-width
|
||||||
|
wb/viewport-height
|
||||||
|
wb/document-start-x
|
||||||
|
wb/document-start-y
|
||||||
|
zoom)]])))
|
||||||
|
|
||||||
|
(def viewport
|
||||||
|
(util/component
|
||||||
|
{:render viewport-render
|
||||||
|
:name "viewport"
|
||||||
|
:mixins [rum/reactive]}))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Work Area
|
;; Work Area
|
||||||
|
@ -54,8 +227,10 @@
|
||||||
|
|
||||||
(defn working-area-render
|
(defn working-area-render
|
||||||
[own]
|
[own]
|
||||||
|
(println "working-area-render")
|
||||||
(html
|
(html
|
||||||
[:section.workspace-canvas
|
[:section.workspace-canvas
|
||||||
|
{:class "no-tool-bar"}
|
||||||
#_{:class (when (empty? open-setting-boxes)
|
#_{:class (when (empty? open-setting-boxes)
|
||||||
"no-tool-bar")
|
"no-tool-bar")
|
||||||
:on-scroll (constantly nil)}
|
:on-scroll (constantly nil)}
|
||||||
|
@ -66,11 +241,11 @@
|
||||||
zoom-cursor
|
zoom-cursor
|
||||||
shapes-cursor))
|
shapes-cursor))
|
||||||
(coordinates)
|
(coordinates)
|
||||||
#_(viewport conn page shapes zoom grid?)]))
|
(viewport)]))
|
||||||
|
|
||||||
(def working-area
|
(def workarea
|
||||||
(util/component
|
(util/component
|
||||||
{:render working-area-render
|
{:render working-area-render
|
||||||
:name "working-area"
|
:name "workarea"
|
||||||
:mixins []}))
|
:mixins []}))
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,12 @@
|
||||||
(assoc state key local-state)))
|
(assoc state key local-state)))
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
|
(def static
|
||||||
|
{:should-update
|
||||||
|
(fn [old-state new-state]
|
||||||
|
(not= (:rum/props old-state) (:rum/props new-state)))})
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Lenses & Helpers
|
;; Lenses & Helpers
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue