dash_kit 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +170 -0
  4. data/Rakefile +18 -0
  5. data/app/assets/builds/dash_kit/dashboard_grid.css +1 -0
  6. data/app/assets/builds/dash_kit/dashboard_grid.js +5 -0
  7. data/app/assets/javascripts/dash_kit/index.js +2 -0
  8. data/app/assets/stylesheets/dash_kit/application.css +15 -0
  9. data/app/controllers/dash_kit/application_controller.rb +6 -0
  10. data/app/controllers/dash_kit/dashboards_controller.rb +139 -0
  11. data/app/controllers/dash_kit/widget_definitions_controller.rb +33 -0
  12. data/app/controllers/dash_kit/widgets_controller.rb +39 -0
  13. data/app/helpers/dash_kit/application_helper.rb +4 -0
  14. data/app/helpers/dash_kit/dashboard_helper.rb +130 -0
  15. data/app/javascript/dash_kit/dashboard_grid.jsx +10 -0
  16. data/app/models/concerns/dash_kit/widget_management.rb +16 -0
  17. data/app/models/dash_kit/application_record.rb +5 -0
  18. data/app/models/dash_kit/dashboard.rb +53 -0
  19. data/app/models/dash_kit/widget_definition.rb +9 -0
  20. data/app/views/dash_kit/dashboards/_widgets.html.erb +1 -0
  21. data/app/views/dash_kit/dashboards/edit.html.erb +21 -0
  22. data/app/views/dash_kit/dashboards/index.html.erb +34 -0
  23. data/app/views/dash_kit/dashboards/new.html.erb +28 -0
  24. data/app/views/dash_kit/widget_definitions/_missing_renderer.html.erb +3 -0
  25. data/app/views/layouts/dash_kit/application.html.erb +17 -0
  26. data/config/importmap.rb +1 -0
  27. data/config/routes.rb +16 -0
  28. data/lib/dash_kit/configuration_backfill.rb +27 -0
  29. data/lib/dash_kit/engine.rb +19 -0
  30. data/lib/dash_kit/reference/guide.md +289 -0
  31. data/lib/dash_kit/reference.rb +11 -0
  32. data/lib/dash_kit/renderer_registry.rb +21 -0
  33. data/lib/dash_kit/the_local/agents/dash_kit-develop.md +298 -0
  34. data/lib/dash_kit/the_local/agents/dash_kit-info.md +298 -0
  35. data/lib/dash_kit/the_local/agents/dash_kit-install.md +298 -0
  36. data/lib/dash_kit/the_local.rb +34 -0
  37. data/lib/dash_kit/version.rb +3 -0
  38. data/lib/dash_kit/widget_registry.rb +69 -0
  39. data/lib/dash_kit.rb +72 -0
  40. data/lib/generators/dash_kit/install_generator.rb +79 -0
  41. data/lib/generators/dash_kit/templates/create_dash_kit_dashboards.rb.tt +20 -0
  42. data/lib/generators/dash_kit/templates/create_dash_kit_widget_definitions.rb.tt +12 -0
  43. data/lib/generators/dash_kit/templates/dash_kit.rb.tt +16 -0
  44. data/lib/tasks/dash_kit_tasks.rake +9 -0
  45. metadata +147 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2ec76c48c05ce86854dd0b5e5311ab5471ec2760545dcc4f66becd44ca7db2b9
4
+ data.tar.gz: 37023a5c9040d15f02706a50f169ef3a265b7bb9c96209b934380d085da3f543
5
+ SHA512:
6
+ metadata.gz: 5eb37c702f9f31e693f3817aa65c707bf25ad905fde6bccb161849efebd0f324cdaf12b07f5b2c48a2a6cc0f896e4e6fbe07a29fa54ce5aec2c30eef4768a5d1
7
+ data.tar.gz: e81a29aae7a41bcb15af136a5bb2f9cfba1c6c6fd56c9f701784c2c9a13a9fd3d9dd556b4288b921936af6103f9bd61845eadc25ce93f4a9828e3997c707342d
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright tylercschneider
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # DashKit
2
+
3
+ ## What DashKit Is
4
+
5
+ DashKit is a Ruby / Rails UI engine for composing, configuring, and rendering dashboards. It provides a presentation and interaction layer that lets teams build reusable dashboards and widgets without tying the UI to any specific backend or data system.
6
+
7
+ ## What DashKit Is Not
8
+
9
+ DashKit does **not**:
10
+
11
+ - Define metrics or their meaning.
12
+ - Query databases or execute data retrieval logic.
13
+ - Validate metric correctness or enforce business rules.
14
+ - Assume any specific backend or analytics engine.
15
+
16
+ DashKit expects an external data provider to supply datasets. It focuses solely on rendering dashboards from those datasets.
17
+
18
+ ## High-Level Architecture
19
+
20
+ ```
21
+ UI events → DataProvider → Dataset → Rendering
22
+ ```
23
+
24
+ DashKit turns user intent (filters, time ranges, widget configs) into a request for a data provider, receives a dataset, and renders it into the dashboard UI.
25
+
26
+ ## Dashboards & Widgets
27
+
28
+ **Dashboard**
29
+ - A container for layout, shared filters, and widget configuration.
30
+ - Responsible for composition and reuse of dashboard layouts.
31
+
32
+ **Widget**
33
+ - A visual unit (chart, table, single value) backed by a data request.
34
+ - Each widget describes what it needs, but does not know how data is fetched.
35
+
36
+ **Filters and Layouts**
37
+ - Filters are passed through as generic values.
38
+ - Layout is a configuration concern (positions, sizes, grouping).
39
+ - DashKit does not validate filter meaning or enforce data semantics.
40
+
41
+ ## Data Provider Interface
42
+
43
+ DashKit integrates with any backend through a pluggable data provider. The provider receives normalized requests and returns datasets in a generic structure.
44
+
45
+ Minimal interface sketch:
46
+
47
+ ```ruby
48
+ class MyProvider
49
+ # request is a plain object or hash describing widget intent
50
+ def fetch(request)
51
+ # return a dataset hash
52
+ end
53
+ end
54
+ ```
55
+
56
+ DashKit does not care how data is fetched. It only requires that the provider responds to requests and returns datasets that match the contract.
57
+
58
+ ## Dataset Contract
59
+
60
+ DashKit renders datasets with a predictable structure, while leaving meaning and correctness to the provider.
61
+
62
+ Example dataset:
63
+
64
+ ```json
65
+ {
66
+ "series": [
67
+ { "name": "Revenue", "points": [ { "x": "2024-01", "y": 120 } ] }
68
+ ],
69
+ "rows": [ { "label": "Total", "value": 120 } ],
70
+ "meta": { "unit": "USD" }
71
+ }
72
+ ```
73
+
74
+ DashKit expects:
75
+
76
+ - Consistent keys and array shapes per widget type.
77
+ - Values that can be rendered without additional interpretation.
78
+
79
+ DashKit does **not** define:
80
+
81
+ - What series or rows mean.
82
+ - Which fields are required beyond a widget’s renderer.
83
+ - How values are derived.
84
+
85
+ ## Installation
86
+
87
+ Add the gem to your Gemfile:
88
+
89
+ ```ruby
90
+ gem "dash_kit", github: "DYB-Development/dash_kit"
91
+ ```
92
+
93
+ Run the install generator:
94
+
95
+ ```bash
96
+ bundle install
97
+ rails generate dash_kit:install
98
+ rails db:migrate
99
+ ```
100
+
101
+ The generator creates the migration, initializer, and engine route. You still need to complete these manual steps:
102
+
103
+ ### 1. Add the association to your owner model
104
+
105
+ ```ruby
106
+ # app/models/account.rb (or whichever model owns dashboards)
107
+ has_many :dash_kit_configurations, class_name: "DashKit::Configuration",
108
+ as: :owner, dependent: :destroy
109
+ ```
110
+
111
+ ### 2. Pin sortablejs for drag-and-drop reordering
112
+
113
+ ```ruby
114
+ # config/importmap.rb
115
+ pin "sortablejs"
116
+ ```
117
+
118
+ ### 3. Register Stimulus controllers
119
+
120
+ ```js
121
+ // app/javascript/controllers/index.js
122
+ import { registerControllers as registerDashKitControllers } from "dash_kit/index"
123
+ registerDashKitControllers(application)
124
+ ```
125
+
126
+ ### 4. Configure the initializer
127
+
128
+ ```ruby
129
+ # config/initializers/dash_kit.rb
130
+ DashKit.parent_controller = "ApplicationController"
131
+ DashKit.current_owner_method = :current_account
132
+
133
+ DashKit.configure do |config|
134
+ config.register(:home) do |d|
135
+ d.widget :on_deck, label: "On Deck", partial: "widgets/home/on_deck"
136
+ d.widget :tasks, label: "Tasks", partial: "widgets/home/tasks"
137
+ end
138
+ end
139
+ ```
140
+
141
+ - `parent_controller` — the controller DashKit inherits from (gives it access to authentication and helpers)
142
+ - `current_owner_method` — the method DashKit calls to scope configurations to the current owner
143
+
144
+ ### 5. Create a dashboard controller and view
145
+
146
+ ```ruby
147
+ # app/controllers/dashboard_controller.rb
148
+ class DashboardController < ApplicationController
149
+ def show
150
+ @dashboard_config = DashKit::Configuration.for_owner(current_account, :home)
151
+ @dashboard_config.save! if @dashboard_config.new_record?
152
+ end
153
+ end
154
+ ```
155
+
156
+ ```erb
157
+ <%# app/views/dashboard/show.html.erb %>
158
+ <%= dash_kit_settings_button_attributes %>
159
+ <%= dash_kit_settings_modal(config: @dashboard_config) %>
160
+
161
+ <div class="mt-4 space-y-6">
162
+ <% @dashboard_config.ordered_visible_widgets.each do |widget_key| %>
163
+ <%= render "widgets/widget_frame", widget_key: widget_key %>
164
+ <% end %>
165
+ </div>
166
+ ```
167
+
168
+ ## Design Philosophy
169
+
170
+ DashKit avoids data semantics by design. It treats datasets as opaque structures that can be rendered consistently, allowing teams to replace or evolve backends without rewriting dashboards. This deliberate decoupling keeps DashKit focused, composable, and stable over time.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ begin
6
+ require "dash_kit/the_local"
7
+ require "the_local/rake"
8
+ rescue LoadError
9
+ # the_local provides the_local:build/install tasks when present.
10
+ end
11
+
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << "test"
14
+ t.libs << "lib"
15
+ t.test_files = FileList["test/**/*_test.rb"]
16
+ end
17
+
18
+ task default: :test
@@ -0,0 +1 @@
1
+ .react-grid-layout{position:relative;transition:height .2s ease}.react-grid-item{transition:all .2s ease;transition-property:left,top,width,height}.react-grid-item img{pointer-events:none;user-select:none}.react-grid-item.cssTransforms{transition-property:transform,width,height}.react-grid-item.resizing{transition:none;z-index:1;will-change:width,height}.react-grid-item.react-draggable-dragging{transition:none;z-index:3;will-change:transform}.react-grid-item.dropping{visibility:hidden}.react-grid-item.react-grid-placeholder{background:red;opacity:.2;transition-duration:.1s;z-index:2;user-select:none}.react-grid-item.react-grid-placeholder.placeholder-resizing{transition:none}.react-grid-item>.react-resizable-handle{position:absolute;width:20px;height:20px;opacity:0}.react-grid-item:hover>.react-resizable-handle{opacity:1}.react-grid-item>.react-resizable-handle:after{content:"";position:absolute;right:3px;bottom:3px;width:5px;height:5px;border-right:2px solid rgba(0,0,0,.4);border-bottom:2px solid rgba(0,0,0,.4)}.react-resizable-hide>.react-resizable-handle{display:none}.react-grid-item>.react-resizable-handle.react-resizable-handle-sw{bottom:0;left:0;cursor:sw-resize;transform:rotate(90deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-se{bottom:0;right:0;cursor:se-resize}.react-grid-item>.react-resizable-handle.react-resizable-handle-nw{top:0;left:0;cursor:nw-resize;transform:rotate(180deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-ne{top:0;right:0;cursor:ne-resize;transform:rotate(270deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-w,.react-grid-item>.react-resizable-handle.react-resizable-handle-e{top:50%;margin-top:-10px;cursor:ew-resize}.react-grid-item>.react-resizable-handle.react-resizable-handle-w{left:0;transform:rotate(135deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-e{right:0;transform:rotate(315deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-n,.react-grid-item>.react-resizable-handle.react-resizable-handle-s{left:50%;margin-left:-10px;cursor:ns-resize}.react-grid-item>.react-resizable-handle.react-resizable-handle-n{top:0;transform:rotate(225deg)}.react-grid-item>.react-resizable-handle.react-resizable-handle-s{bottom:0;transform:rotate(45deg)}@media(hover:none){.react-grid-item>.react-resizable-handle{opacity:1}}[data-block-handle]{cursor:grab;touch-action:none;line-height:1;user-select:none}[data-block-handle]:active{cursor:grabbing}[data-block]{touch-action:pan-y}
@@ -0,0 +1,5 @@
1
+ (()=>{var os=Object.create;var rn=Object.defineProperty;var ss=Object.getOwnPropertyDescriptor;var as=Object.getOwnPropertyNames;var is=Object.getPrototypeOf,ls=Object.prototype.hasOwnProperty;var Dr=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var Mt=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(n){throw e=0,n}},Cr=(t,e)=>{for(var n in e)rn(t,n,{get:e[n],enumerable:!0})},Rr=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of as(e))!ls.call(t,o)&&o!==n&&rn(t,o,{get:()=>e[o],enumerable:!(r=ss(e,o))||r.enumerable});return t};var on=(t,e,n)=>(n=t!=null?os(is(t)):{},Rr(e||!t||!t.__esModule?rn(n,"default",{value:t,enumerable:!0}):n,t)),ge=t=>Rr(rn({},"__esModule",{value:!0}),t);var On={};Cr(On,{createPortal:()=>cs,createRoot:()=>zn,default:()=>_e,flushSync:()=>us,hydrateRoot:()=>ds,preconnect:()=>fs,prefetchDNS:()=>ps,preinit:()=>hs,preinitModule:()=>gs,preload:()=>ms,preloadModule:()=>ys,requestFormReset:()=>bs,unstable_batchedUpdates:()=>vs,useFormState:()=>ws,useFormStatus:()=>Ss,version:()=>xs});var Er,_e,cs,zn,us,ds,fs,ps,hs,gs,ms,ys,bs,vs,ws,Ss,xs,Ce=Dr(()=>{Er=globalThis.ReactDOM,_e=Er,{createPortal:cs,createRoot:zn,flushSync:us,hydrateRoot:ds,preconnect:fs,prefetchDNS:ps,preinit:hs,preinitModule:gs,preload:ms,preloadModule:ys,requestFormReset:bs,unstable_batchedUpdates:vs,useFormState:ws,useFormStatus:Ss,version:xs}=Er});var ne={};Cr(ne,{Children:()=>Te,Component:()=>je,Fragment:()=>Ds,PureComponent:()=>Cs,StrictMode:()=>Rs,Suspense:()=>Es,cloneElement:()=>He,createContext:()=>zs,createElement:()=>Pn,createRef:()=>Os,default:()=>p,forwardRef:()=>Ps,isValidElement:()=>ks,lazy:()=>Ms,memo:()=>Ls,startTransition:()=>Ns,useCallback:()=>U,useContext:()=>_s,useDebugValue:()=>Ts,useDeferredValue:()=>js,useEffect:()=>It,useId:()=>Hs,useImperativeHandle:()=>Bs,useLayoutEffect:()=>Ws,useMemo:()=>Ct,useReducer:()=>As,useRef:()=>I,useState:()=>st,useSyncExternalStore:()=>qs,useTransition:()=>Is});var zr,p,Te,je,Ds,Cs,Rs,Es,He,zs,Pn,Os,Ps,ks,Ms,Ls,Ns,U,_s,Ts,js,It,Hs,Bs,Ws,Ct,As,I,st,qs,Is,ct=Dr(()=>{zr=globalThis.React,p=zr,{Children:Te,Component:je,Fragment:Ds,PureComponent:Cs,StrictMode:Rs,Suspense:Es,cloneElement:He,createContext:zs,createElement:Pn,createRef:Os,forwardRef:Ps,isValidElement:ks,lazy:Ms,memo:Ls,startTransition:Ns,useCallback:U,useContext:_s,useDebugValue:Ts,useDeferredValue:js,useEffect:It,useId:Hs,useImperativeHandle:Bs,useLayoutEffect:Ws,useMemo:Ct,useReducer:As,useRef:I,useState:st,useSyncExternalStore:qs,useTransition:Is}=zr});var Gr=Mt((cn,$r)=>{(function(t,e){typeof cn=="object"&&typeof $r<"u"?e(cn):typeof define=="function"&&define.amd?define(["exports"],e):(t=typeof globalThis<"u"?globalThis:t||self,e(t["fast-equals"]={}))})(cn,(function(t){"use strict";function e(d){return function(k,y,x,D,j,F,W){return d(k,y,W)}}function n(d){return function(k,y,x,D){if(!k||!y||typeof k!="object"||typeof y!="object")return d(k,y,x,D);var j=D.get(k),F=D.get(y);if(j&&F)return j===y&&F===k;D.set(k,y),D.set(y,k);var W=d(k,y,x,D);return D.delete(k),D.delete(y),W}}function r(d,m){var k={};for(var y in d)k[y]=d[y];for(var y in m)k[y]=m[y];return k}function o(d){return d.constructor===Object||d.constructor==null}function a(d){return typeof d.then=="function"}function s(d,m){return d===m||d!==d&&m!==m}var i="[object Arguments]",l="[object Boolean]",c="[object Date]",f="[object RegExp]",u="[object Map]",g="[object Number]",z="[object Object]",w="[object Set]",P="[object String]",S=Object.prototype.toString;function b(d){var m=d.areArraysEqual,k=d.areDatesEqual,y=d.areMapsEqual,x=d.areObjectsEqual,D=d.areRegExpsEqual,j=d.areSetsEqual,F=d.createIsNestedEqual,W=F(ot);function ot(M,N,pt){if(M===N)return!0;if(!M||!N||typeof M!="object"||typeof N!="object")return M!==M&&N!==N;if(o(M)&&o(N))return x(M,N,W,pt);var X=Array.isArray(M),B=Array.isArray(N);if(X||B)return X===B&&m(M,N,W,pt);var $=S.call(M);return $!==S.call(N)?!1:$===c?k(M,N,W,pt):$===f?D(M,N,W,pt):$===u?y(M,N,W,pt):$===w?j(M,N,W,pt):$===z||$===i?a(M)||a(N)?!1:x(M,N,W,pt):$===l||$===g||$===P?s(M.valueOf(),N.valueOf()):!1}return ot}function K(d,m,k,y){var x=d.length;if(m.length!==x)return!1;for(;x-- >0;)if(!k(d[x],m[x],x,x,d,m,y))return!1;return!0}var J=n(K);function at(d,m){return s(d.valueOf(),m.valueOf())}function ut(d,m,k,y){var x=d.size===m.size;if(!x)return!1;if(!d.size)return!0;var D={},j=0;return d.forEach(function(F,W){if(x){var ot=!1,M=0;m.forEach(function(N,pt){!ot&&!D[M]&&(ot=k(W,pt,j,M,d,m,y)&&k(F,N,W,pt,d,m,y))&&(D[M]=!0),M++}),j++,x=ot}}),x}var it=n(ut),rt="_owner",et=Object.prototype.hasOwnProperty;function lt(d,m,k,y){var x=Object.keys(d),D=x.length;if(Object.keys(m).length!==D)return!1;for(var j;D-- >0;){if(j=x[D],j===rt){var F=!!d.$$typeof,W=!!m.$$typeof;if((F||W)&&F!==W)return!1}if(!et.call(m,j)||!k(d[j],m[j],j,j,d,m,y))return!1}return!0}var Rt=n(lt);function Wt(d,m){return d.source===m.source&&d.flags===m.flags}function C(d,m,k,y){var x=d.size===m.size;if(!x)return!1;if(!d.size)return!0;var D={};return d.forEach(function(j,F){if(x){var W=!1,ot=0;m.forEach(function(M,N){!W&&!D[ot]&&(W=k(j,M,F,N,d,m,y))&&(D[ot]=!0),ot++}),x=W}}),x}var R=n(C),Y=Object.freeze({areArraysEqual:K,areDatesEqual:at,areMapsEqual:ut,areObjectsEqual:lt,areRegExpsEqual:Wt,areSetsEqual:C,createIsNestedEqual:e}),Ot=Object.freeze({areArraysEqual:J,areDatesEqual:at,areMapsEqual:it,areObjectsEqual:Rt,areRegExpsEqual:Wt,areSetsEqual:R,createIsNestedEqual:e}),xt=b(Y);function Et(d,m){return xt(d,m,void 0)}var ue=b(r(Y,{createIsNestedEqual:function(){return s}}));function de(d,m){return ue(d,m,void 0)}var Nt=b(Ot);function Vt(d,m){return Nt(d,m,new WeakMap)}var Kt=b(r(Ot,{createIsNestedEqual:function(){return s}}));function fe(d,m){return Kt(d,m,new WeakMap)}function pe(d){return b(r(Y,d(Y)))}function he(d){var m=b(r(Ot,d(Ot)));return(function(k,y,x){return x===void 0&&(x=new WeakMap),m(k,y,x)})}t.circularDeepEqual=Vt,t.circularShallowEqual=fe,t.createCustomCircularEqual=he,t.createCustomEqual=pe,t.deepEqual=Et,t.sameValueZeroEqual=s,t.shallowEqual=de,Object.defineProperty(t,"__esModule",{value:!0})}))});var Ur=Mt((il,Fr)=>{"use strict";var ia="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";Fr.exports=ia});var Zr=Mt((ll,Jr)=>{"use strict";var la=Ur();function Vr(){}function Kr(){}Kr.resetWarningCache=Vr;Jr.exports=function(){function t(r,o,a,s,i,l){if(l!==la){var c=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw c.name="Invariant Violation",c}}t.isRequired=t;function e(){return t}var n={array:t,bigint:t,bool:t,func:t,number:t,object:t,string:t,symbol:t,any:t,arrayOf:e,element:t,elementType:t,instanceOf:e,node:t,objectOf:e,oneOf:e,oneOfType:e,shape:e,exact:e,checkPropTypes:Kr,resetWarningCache:Vr};return n.PropTypes=n,n}});var me=Mt((dl,Qr)=>{Qr.exports=Zr()();var cl,ul});var uo=Mt((Sl,Zn)=>{function co(t){var e,n,r="";if(typeof t=="string"||typeof t=="number")r+=t;else if(typeof t=="object")if(Array.isArray(t)){var o=t.length;for(e=0;e<o;e++)t[e]&&(n=co(t[e]))&&(r&&(r+=" "),r+=n)}else for(n in t)t[n]&&(r&&(r+=" "),r+=n);return r}function lo(){for(var t,e,n=0,r="",o=arguments.length;n<o;n++)(t=arguments[n])&&(e=co(t))&&(r&&(r+=" "),r+=e);return r}Zn.exports=lo,Zn.exports.clsx=lo});var xo=Mt((xl,So)=>{"use strict";var Ma=Object.create,fn=Object.defineProperty,La=Object.getOwnPropertyDescriptor,Na=Object.getOwnPropertyNames,_a=Object.getPrototypeOf,Ta=Object.prototype.hasOwnProperty,ja=(t,e)=>{for(var n in e)fn(t,n,{get:e[n],enumerable:!0})},yo=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Na(e))!Ta.call(t,o)&&o!==n&&fn(t,o,{get:()=>e[o],enumerable:!(r=La(e,o))||r.enumerable});return t},Pe=(t,e,n)=>(n=t!=null?Ma(_a(t)):{},yo(e||!t||!t.__esModule?fn(n,"default",{value:t,enumerable:!0}):n,t)),Ha=t=>yo(fn({},"__esModule",{value:!0}),t),bo={};ja(bo,{DraggableCore:()=>ve,default:()=>pn});So.exports=Ha(bo);var dn=Pe((ct(),ge(ne))),V=Pe(me()),Ba=Pe((Ce(),ge(On))),Wa=uo();function ar(t,e){for(let n=0,r=t.length;n<r;n++)if(e.apply(e,[t[n],n,t]))return t[n]}function fo(t){return typeof t=="function"||Object.prototype.toString.call(t)==="[object Function]"}function $e(t){return typeof t=="number"&&!isNaN(t)}function vt(t){return parseInt(t,10)}function Oe(t,e,n){if(t[e])return new Error(`Invalid prop ${e} passed to ${n} - do not set this, set it on the child.`)}var Qn=["Moz","Webkit","O","ms"];function Aa(t="transform"){var e,n;if(typeof window>"u")return"";let r=(n=(e=window.document)==null?void 0:e.documentElement)==null?void 0:n.style;if(!r||t in r)return"";for(let o=0;o<Qn.length;o++)if(vo(t,Qn[o])in r)return Qn[o];return""}function vo(t,e){return e?`${e}${qa(t)}`:t}function qa(t){let e="",n=!0;for(let r=0;r<t.length;r++)n?(e+=t[r].toUpperCase(),n=!1):t[r]==="-"?n=!0:e+=t[r];return e}var Ia=Aa(),tr="";function Ya(t,e){var n;tr||(tr=(n=ar(["matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector"],function(o){return fo(t[o])}))!=null?n:"");let r=t[tr];return fo(r)?!!r.call(t,e):!1}function po(t,e,n){let r=t;do{if(Ya(r,e))return!0;if(r===n)return!1;r=r.parentNode}while(r);return!1}function er(t,e,n,r){if(!t)return;let o={capture:!0,...r},a=n;t.addEventListener?t.addEventListener(e,a,o):t.attachEvent?t.attachEvent("on"+e,a):t["on"+e]=a}function be(t,e,n,r){if(!t)return;let o={capture:!0,...r},a=n;t.removeEventListener?t.removeEventListener(e,a,o):t.detachEvent?t.detachEvent("on"+e,a):t["on"+e]=null}function Xa(t){let e=t.clientHeight,n=t.ownerDocument.defaultView.getComputedStyle(t);return e+=vt(n.borderTopWidth),e+=vt(n.borderBottomWidth),e}function $a(t){let e=t.clientWidth,n=t.ownerDocument.defaultView.getComputedStyle(t);return e+=vt(n.borderLeftWidth),e+=vt(n.borderRightWidth),e}function Ga(t){let e=t.clientHeight,n=t.ownerDocument.defaultView.getComputedStyle(t);return e-=vt(n.paddingTop),e-=vt(n.paddingBottom),e}function Fa(t){let e=t.clientWidth,n=t.ownerDocument.defaultView.getComputedStyle(t);return e-=vt(n.paddingLeft),e-=vt(n.paddingRight),e}function Ua(t,e,n){let o=e===e.ownerDocument.body?{left:0,top:0}:e.getBoundingClientRect(),a=(t.clientX+e.scrollLeft-o.left)/n,s=(t.clientY+e.scrollTop-o.top)/n;return{x:a,y:s}}function Va(t,e){let n=wo(t,e,"px");return{[vo("transform",Ia)]:n}}function Ka(t,e){return wo(t,e,"")}function wo({x:t,y:e},n,r){let o=`translate(${t}${r},${e}${r})`;if(n){let a=`${typeof n.x=="string"?n.x:n.x+r}`,s=`${typeof n.y=="string"?n.y:n.y+r}`;o=`translate(${a}, ${s})`+o}return o}function Ja(t,e){return t.targetTouches&&ar(t.targetTouches,n=>e===n.identifier)||t.changedTouches&&ar(t.changedTouches,n=>e===n.identifier)}function Za(t){if(t.targetTouches&&t.targetTouches[0])return t.targetTouches[0].identifier;if(t.changedTouches&&t.changedTouches[0])return t.changedTouches[0].identifier}function Qa(){return typeof __webpack_nonce__<"u"?__webpack_nonce__:void 0}function ti(t,e){if(!t)return;let n=t.getElementById("react-draggable-style-el");if(!n){n=t.createElement("style"),n.type="text/css",n.id="react-draggable-style-el";let r=e??Qa();r&&n.setAttribute("nonce",r),n.innerHTML=`.react-draggable-transparent-selection *::-moz-selection {all: inherit;}
2
+ `,n.innerHTML+=`.react-draggable-transparent-selection *::selection {all: inherit;}
3
+ `,t.getElementsByTagName("head")[0].appendChild(n)}t.body&&ei(t.body,"react-draggable-transparent-selection")}function ho(t){window.requestAnimationFrame?window.requestAnimationFrame(()=>{go(t)}):go(t)}function go(t){if(t)try{t.body&&ni(t.body,"react-draggable-transparent-selection");let e=t.selection;if(e)e.empty();else{let n=(t.defaultView||window).getSelection();n&&n.type!=="Caret"&&n.removeAllRanges()}}catch{}}function ei(t,e){t.classList?t.classList.add(e):t.className.match(new RegExp(`(?:^|\\s)${e}(?!\\S)`))||(t.className+=` ${e}`)}function ni(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp(`(?:^|\\s)${e}(?!\\S)`,"g"),"")}function ri(t,e,n){if(!t.props.bounds)return[e,n];let{bounds:r}=t.props;r=typeof r=="string"?r:ai(r);let o=ir(t);if(typeof r=="string"){let{ownerDocument:a}=o,s=a.defaultView;if(!s)throw new Error("Cannot resolve the owner window of the draggable node.");let i;if(r==="parent"?i=o.parentNode:i=o.getRootNode().querySelector(r),!(i instanceof s.HTMLElement))throw new Error('Bounds selector "'+r+'" could not find an element.');let l=i,c=s.getComputedStyle(o),f=s.getComputedStyle(l);r={left:-o.offsetLeft+vt(f.paddingLeft)+vt(c.marginLeft),top:-o.offsetTop+vt(f.paddingTop)+vt(c.marginTop),right:Fa(l)-$a(o)-o.offsetLeft+vt(f.paddingRight)-vt(c.marginRight),bottom:Ga(l)-Xa(o)-o.offsetTop+vt(f.paddingBottom)-vt(c.marginBottom)}}return $e(r.right)&&(e=Math.min(e,r.right)),$e(r.bottom)&&(n=Math.min(n,r.bottom)),$e(r.left)&&(e=Math.max(e,r.left)),$e(r.top)&&(n=Math.max(n,r.top)),[e,n]}function mo(t,e,n){let r=Math.round(e/t[0])*t[0],o=Math.round(n/t[1])*t[1];return[r,o]}function oi(t){return t.props.axis==="both"||t.props.axis==="x"}function si(t){return t.props.axis==="both"||t.props.axis==="y"}function nr(t,e,n){let r=typeof e=="number"?Ja(t,e):null;if(typeof e=="number"&&!r)return null;let o=ir(n),a=n.props.offsetParent||o.offsetParent||o.ownerDocument.body;return Ua(r||t,a,n.props.scale)}function rr(t,e,n){let r=!$e(t.lastX),o=ir(t);return r?{node:o,deltaX:0,deltaY:0,lastX:e,lastY:n,x:e,y:n}:{node:o,deltaX:e-t.lastX,deltaY:n-t.lastY,lastX:t.lastX,lastY:t.lastY,x:e,y:n}}function or(t,e){let n=t.props.scale;return{node:e.node,x:t.state.x+e.deltaX/n,y:t.state.y+e.deltaY/n,deltaX:e.deltaX/n,deltaY:e.deltaY/n,lastX:t.state.x,lastY:t.state.y}}function ai(t){return{left:t.left,top:t.top,right:t.right,bottom:t.bottom}}function ir(t){let e=t.findDOMNode();if(!e)throw new Error("<DraggableCore>: Unmounted during event!");return e}var sr=Pe((ct(),ge(ne))),bt=Pe(me()),ii=Pe((Ce(),ge(On))),li=typeof process<"u"&&process.env.DRAGGABLE_DEBUG?console.log.bind(console):function(){},Xt=li,Bt={touch:{start:"touchstart",move:"touchmove",stop:"touchend"},mouse:{start:"mousedown",move:"mousemove",stop:"mouseup"}},le=Bt.mouse,ve=class extends sr.Component{constructor(){super(...arguments),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,this.touchIdentifier=null,this.mounted=!1,this.handleDragStart=t=>{if(this.props.onMouseDown(t),!this.props.allowAnyClick&&(typeof t.button=="number"&&t.button!==0||t.ctrlKey))return!1;let e=this.findDOMNode();if(!e||!e.ownerDocument||!e.ownerDocument.body)throw new Error("<DraggableCore> not mounted on DragStart!");let{ownerDocument:n}=e;if(this.props.disabled||!(t.target instanceof n.defaultView.Node)||this.props.handle&&!po(t.target,this.props.handle,e)||this.props.cancel&&po(t.target,this.props.cancel,e))return;t.type==="touchstart"&&!this.props.allowMobileScroll&&t.preventDefault();let r=Za(t);this.touchIdentifier=r;let o=nr(t,r,this);if(o==null)return;let{x:a,y:s}=o,i=rr(this,a,s);Xt("DraggableCore: handleDragStart: %j",i),Xt("calling",this.props.onStart),!(this.props.onStart(t,i)===!1||this.mounted===!1)&&(this.props.enableUserSelectHack&&ti(n,this.props.nonce),this.dragging=!0,this.lastX=a,this.lastY=s,er(n,le.move,this.handleDrag),er(n,le.stop,this.handleDragStop))},this.handleDrag=t=>{let e=nr(t,this.touchIdentifier,this);if(e==null)return;let{x:n,y:r}=e;if(Array.isArray(this.props.grid)){let s=n-this.lastX,i=r-this.lastY;if([s,i]=mo(this.props.grid,s,i),!s&&!i)return;n=this.lastX+s,r=this.lastY+i}let o=rr(this,n,r);if(Xt("DraggableCore: handleDrag: %j",o),this.props.onDrag(t,o)===!1||this.mounted===!1){try{this.handleDragStop(new MouseEvent("mouseup"))}catch{let s=document.createEvent("MouseEvents");s.initMouseEvent("mouseup",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),this.handleDragStop(s)}return}this.lastX=n,this.lastY=r},this.handleDragStop=t=>{if(!this.dragging)return;let e=nr(t,this.touchIdentifier,this);if(e==null)return;let{x:n,y:r}=e;if(Array.isArray(this.props.grid)){let i=n-this.lastX||0,l=r-this.lastY||0;[i,l]=mo(this.props.grid,i,l),n=this.lastX+i,r=this.lastY+l}let o=rr(this,n,r);if(this.props.onStop(t,o)===!1||this.mounted===!1)return!1;let s=this.findDOMNode();s&&this.props.enableUserSelectHack&&ho(s.ownerDocument),Xt("DraggableCore: handleDragStop: %j",o),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,s&&(Xt("DraggableCore: Removing handlers"),be(s.ownerDocument,le.move,this.handleDrag),be(s.ownerDocument,le.stop,this.handleDragStop))},this.onMouseDown=t=>(le=Bt.mouse,this.handleDragStart(t)),this.onMouseUp=t=>(le=Bt.mouse,this.handleDragStop(t)),this.onTouchStart=t=>(le=Bt.touch,this.handleDragStart(t)),this.onTouchEnd=t=>(le=Bt.touch,this.handleDragStop(t))}componentDidMount(){this.mounted=!0;let t=this.findDOMNode();t&&er(t,Bt.touch.start,this.onTouchStart,{passive:!1})}componentWillUnmount(){this.mounted=!1;let t=this.findDOMNode();if(t){let{ownerDocument:e}=t;be(e,Bt.mouse.move,this.handleDrag),be(e,Bt.touch.move,this.handleDrag),be(e,Bt.mouse.stop,this.handleDragStop),be(e,Bt.touch.stop,this.handleDragStop),be(t,Bt.touch.start,this.onTouchStart,{passive:!1}),this.props.enableUserSelectHack&&ho(e)}}findDOMNode(){var t;if((t=this.props)!=null&&t.nodeRef)return this.props.nodeRef.current;let e=ii.default;return typeof e.findDOMNode=="function"?e.findDOMNode(this):(Xt("react-draggable: ReactDOM.findDOMNode is not available in React 19+. You must provide a nodeRef prop. See: https://github.com/react-grid-layout/react-draggable#noderef"),null)}render(){return sr.cloneElement(sr.Children.only(this.props.children),{onMouseDown:this.onMouseDown,onMouseUp:this.onMouseUp,onTouchEnd:this.onTouchEnd})}};ve.displayName="DraggableCore";ve.propTypes={allowAnyClick:bt.default.bool,allowMobileScroll:bt.default.bool,children:bt.default.node.isRequired,disabled:bt.default.bool,enableUserSelectHack:bt.default.bool,offsetParent:function(t,e){if(t[e]&&t[e].nodeType!==1)throw new Error("Draggable's offsetParent must be a DOM Node.")},grid:bt.default.arrayOf(bt.default.number),handle:bt.default.string,cancel:bt.default.string,nodeRef:bt.default.object,nonce:bt.default.string,onStart:bt.default.func,onDrag:bt.default.func,onStop:bt.default.func,onMouseDown:bt.default.func,scale:bt.default.number,className:Oe,style:Oe,transform:Oe};ve.defaultProps={allowAnyClick:!1,allowMobileScroll:!1,disabled:!1,enableUserSelectHack:!0,onStart:function(){},onDrag:function(){},onStop:function(){},onMouseDown:function(){},scale:1};var pn=class extends dn.Component{constructor(t){super(t),this.onDragStart=(e,n)=>{if(Xt("Draggable: onDragStart: %j",n),this.props.onStart(e,or(this,n))===!1)return!1;this.setState({dragging:!0,dragged:!0})},this.onDrag=(e,n)=>{if(!this.state.dragging)return!1;Xt("Draggable: onDrag: %j",n);let r=or(this,n),o={x:r.x,y:r.y,slackX:0,slackY:0};if(this.props.bounds){let{x:s,y:i}=o;o.x+=this.state.slackX,o.y+=this.state.slackY;let[l,c]=ri(this,o.x,o.y);o.x=l,o.y=c,o.slackX=this.state.slackX+(s-o.x),o.slackY=this.state.slackY+(i-o.y),r.x=o.x,r.y=o.y,r.deltaX=o.x-this.state.x,r.deltaY=o.y-this.state.y}if(this.props.onDrag(e,r)===!1)return!1;this.setState(o)},this.onDragStop=(e,n)=>{if(!this.state.dragging||this.props.onStop(e,or(this,n))===!1)return!1;Xt("Draggable: onDragStop: %j",n);let o={dragging:!1,slackX:0,slackY:0};if(!!this.props.position){let{x:s,y:i}=this.props.position;o.x=s,o.y=i}this.setState(o)},this.state={dragging:!1,dragged:!1,x:t.position?t.position.x:t.defaultPosition.x,y:t.position?t.position.y:t.defaultPosition.y,prevPropsPosition:{...t.position},slackX:0,slackY:0,isElementSVG:!1},t.position&&!(t.onDrag||t.onStop)&&console.warn("A `position` was applied to this <Draggable>, without drag handlers. This will make this component effectively undraggable. Please attach `onDrag` or `onStop` handlers so you can adjust the `position` of this element.")}static getDerivedStateFromProps({position:t},{prevPropsPosition:e}){return t&&(!e||t.x!==e.x||t.y!==e.y)?(Xt("Draggable: getDerivedStateFromProps %j",{position:t,prevPropsPosition:e}),{x:t.x,y:t.y,prevPropsPosition:{...t}}):null}componentDidMount(){typeof window.SVGElement<"u"&&this.findDOMNode()instanceof window.SVGElement&&this.setState({isElementSVG:!0})}componentWillUnmount(){this.state.dragging&&this.setState({dragging:!1})}findDOMNode(){var t;if((t=this.props)!=null&&t.nodeRef)return this.props.nodeRef.current;let e=Ba.default;return typeof e.findDOMNode=="function"?e.findDOMNode(this):null}render(){let{axis:t,bounds:e,children:n,defaultPosition:r,defaultClassName:o,defaultClassNameDragging:a,defaultClassNameDragged:s,position:i,positionOffset:l,scale:c,...f}=this.props,u={},g=null,w=!!!i||this.state.dragging,P=i||r,S={x:oi(this)&&w?this.state.x:P.x,y:si(this)&&w?this.state.y:P.y};this.state.isElementSVG?g=Ka(S,l):u=Va(S,l);let b=dn.Children.only(n),K=(0,Wa.clsx)(b.props.className||"",o,{[a]:this.state.dragging,[s]:this.state.dragged});return dn.createElement(ve,{...f,onStart:this.onDragStart,onDrag:this.onDrag,onStop:this.onDragStop},dn.cloneElement(b,{className:K,style:{...b.props.style,...u},transform:g}))}};pn.displayName="Draggable";pn.propTypes={...ve.propTypes,axis:V.default.oneOf(["both","x","y","none"]),bounds:V.default.oneOfType([V.default.shape({left:V.default.number,right:V.default.number,top:V.default.number,bottom:V.default.number}),V.default.string,V.default.oneOf([!1])]),defaultClassName:V.default.string,defaultClassNameDragging:V.default.string,defaultClassNameDragged:V.default.string,defaultPosition:V.default.shape({x:V.default.number,y:V.default.number}),positionOffset:V.default.shape({x:V.default.oneOfType([V.default.number,V.default.string]),y:V.default.oneOfType([V.default.number,V.default.string])}),position:V.default.shape({x:V.default.number,y:V.default.number}),className:Oe,style:Oe,transform:Oe};pn.defaultProps={...ve.defaultProps,axis:"both",bounds:!1,defaultClassName:"react-draggable",defaultClassNameDragging:"react-draggable-dragging",defaultClassNameDragged:"react-draggable-dragged",defaultPosition:{x:0,y:0},scale:1}});var cr=Mt((Rl,hn)=>{"use strict";var lr=xo(),ci=lr.DraggableCore,Do=lr.default||lr;hn.exports=Do;hn.exports.default=Do;hn.exports.DraggableCore=ci});var Eo=Mt(ur=>{"use strict";ur.__esModule=!0;ur.cloneElement=gi;var ui=di((ct(),ge(ne)));function di(t){return t&&t.__esModule?t:{default:t}}function Co(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(o){return Object.getOwnPropertyDescriptor(t,o).enumerable})),n.push.apply(n,r)}return n}function Ro(t){for(var e=1;e<arguments.length;e++){var n=arguments[e]!=null?arguments[e]:{};e%2?Co(Object(n),!0).forEach(function(r){fi(t,r,n[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):Co(Object(n)).forEach(function(r){Object.defineProperty(t,r,Object.getOwnPropertyDescriptor(n,r))})}return t}function fi(t,e,n){return(e=pi(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function pi(t){var e=hi(t,"string");return typeof e=="symbol"?e:e+""}function hi(t,e){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var r=n.call(t,e||"default");if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(t)}function gi(t,e){return e.style&&t.props.style&&(e.style=Ro(Ro({},t.props.style),e.style)),e.className&&t.props.className&&(e.className=t.props.className+" "+e.className),ui.default.cloneElement(t,e)}});var dr=Mt(gn=>{"use strict";gn.__esModule=!0;gn.resizableProps=void 0;var E=mi(me()),zl=cr();function mi(t){return t&&t.__esModule?t:{default:t}}var Ol=gn.resizableProps={axis:E.default.oneOf(["both","x","y","none"]),className:E.default.string,children:E.default.element.isRequired,draggableOpts:E.default.shape({allowAnyClick:E.default.bool,cancel:E.default.string,children:E.default.node,disabled:E.default.bool,enableUserSelectHack:E.default.bool,offsetParent:typeof Element<"u"?E.default.instanceOf(Element):E.default.any,grid:E.default.arrayOf(E.default.number),handle:E.default.string,nodeRef:E.default.object,onStart:E.default.func,onDrag:E.default.func,onStop:E.default.func,onMouseDown:E.default.func,scale:E.default.number}),height:function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];let r=e[0];return r.axis==="both"||r.axis==="y"?E.default.number.isRequired(...e):E.default.number(...e)},handle:E.default.oneOfType([E.default.node,E.default.func]),handleSize:E.default.arrayOf(E.default.number),lockAspectRatio:E.default.bool,maxConstraints:E.default.arrayOf(E.default.number),minConstraints:E.default.arrayOf(E.default.number),onResizeStop:E.default.func,onResizeStart:E.default.func,onResize:E.default.func,resizeHandles:E.default.arrayOf(E.default.oneOf(["s","w","e","n","sw","nw","se","ne"])),transformScale:E.default.number,width:function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];let r=e[0];return r.axis==="both"||r.axis==="x"?E.default.number.isRequired(...e):E.default.number(...e)}}});var hr=Mt(mn=>{"use strict";mn.__esModule=!0;mn.default=void 0;var ke=Oo((ct(),ge(ne))),yi=cr(),bi=Eo(),vi=dr(),wi=["children","className","draggableOpts","width","height","handle","handleSize","lockAspectRatio","axis","minConstraints","maxConstraints","onResize","onResizeStop","onResizeStart","resizeHandles","transformScale"];function Oo(t,e){if(typeof WeakMap=="function")var n=new WeakMap,r=new WeakMap;return(Oo=function(o,a){if(!a&&o&&o.__esModule)return o;var s,i,l={__proto__:null,default:o};if(o===null||typeof o!="object"&&typeof o!="function")return l;if(s=a?r:n){if(s.has(o))return s.get(o);s.set(o,l)}for(let c in o)c!=="default"&&{}.hasOwnProperty.call(o,c)&&((i=(s=Object.defineProperty)&&Object.getOwnPropertyDescriptor(o,c))&&(i.get||i.set)?s(l,c,i):l[c]=o[c]);return l})(t,e)}function pr(){return pr=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)({}).hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},pr.apply(null,arguments)}function Si(t,e){if(t==null)return{};var n={};for(var r in t)if({}.hasOwnProperty.call(t,r)){if(e.indexOf(r)!==-1)continue;n[r]=t[r]}return n}function zo(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(o){return Object.getOwnPropertyDescriptor(t,o).enumerable})),n.push.apply(n,r)}return n}function fr(t){for(var e=1;e<arguments.length;e++){var n=arguments[e]!=null?arguments[e]:{};e%2?zo(Object(n),!0).forEach(function(r){xi(t,r,n[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):zo(Object(n)).forEach(function(r){Object.defineProperty(t,r,Object.getOwnPropertyDescriptor(n,r))})}return t}function xi(t,e,n){return(e=Di(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function Di(t){var e=Ci(t,"string");return typeof e=="symbol"?e:e+""}function Ci(t,e){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var r=n.call(t,e||"default");if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(t)}var Ge=class extends ke.Component{constructor(){super(...arguments),this.handleRefs={},this.lastHandleRect=null,this.slack=null,this.lastSize=null}componentWillUnmount(){this.resetData()}resetData(){this.lastHandleRect=this.slack=this.lastSize=null}runConstraints(e,n){let r=this.props,o=r.minConstraints,a=r.maxConstraints,s=r.lockAspectRatio;if(!o&&!a&&!s)return[e,n];if(s){let g=this.props.width/this.props.height,z=e-this.props.width,w=n-this.props.height;Math.abs(z)>Math.abs(w*g)?n=e/g:e=n*g}let i=e,l=n,c=this.slack||[0,0],f=c[0],u=c[1];return e+=f,n+=u,o&&(e=Math.max(o[0],e),n=Math.max(o[1],n)),a&&(e=Math.min(a[0],e),n=Math.min(a[1],n)),this.slack=[f+(i-e),u+(l-n)],[e,n]}resizeHandler(e,n){return(r,o)=>{var a,s,i,l;let c=o.node,f=o.deltaX,u=o.deltaY;e==="onResizeStart"&&this.resetData();let g=(this.props.axis==="both"||this.props.axis==="x")&&n!=="n"&&n!=="s",z=(this.props.axis==="both"||this.props.axis==="y")&&n!=="e"&&n!=="w";if(!g&&!z)return;let w=n[0],P=n[n.length-1],S=c.getBoundingClientRect();if(this.lastHandleRect!=null){if(P==="w"){let Rt=S.left-this.lastHandleRect.left;f+=Rt}if(w==="n"){let Rt=S.top-this.lastHandleRect.top;u+=Rt}}this.lastHandleRect=S,P==="w"&&(f=-f),w==="n"&&(u=-u);let b=(a=(s=this.lastSize)==null?void 0:s.width)!=null?a:this.props.width,K=(i=(l=this.lastSize)==null?void 0:l.height)!=null?i:this.props.height,J=b+(g?f/this.props.transformScale:0),at=K+(z?u/this.props.transformScale:0);var ut=this.runConstraints(J,at);if(J=ut[0],at=ut[1],e==="onResizeStop"&&this.lastSize){var it=this.lastSize;J=it.width,at=it.height}let rt=J!==b||at!==K;e!=="onResizeStop"&&(this.lastSize={width:J,height:at});let et=typeof this.props[e]=="function"?this.props[e]:null;et&&!(e==="onResize"&&!rt)&&(r.persist==null||r.persist(),et(r,{node:c,size:{width:J,height:at},handle:n})),e==="onResizeStop"&&this.resetData()}}renderResizeHandle(e,n){let r=this.props.handle;if(!r)return ke.createElement("span",{className:"react-resizable-handle react-resizable-handle-"+e,ref:n});if(typeof r=="function")return r(e,n);let o=typeof r.type=="string",a=fr({ref:n},o?{}:{handleAxis:e});return ke.cloneElement(r,a)}render(){let e=this.props,n=e.children,r=e.className,o=e.draggableOpts,a=e.width,s=e.height,i=e.handle,l=e.handleSize,c=e.lockAspectRatio,f=e.axis,u=e.minConstraints,g=e.maxConstraints,z=e.onResize,w=e.onResizeStop,P=e.onResizeStart,S=e.resizeHandles,b=e.transformScale,K=Si(e,wi);return(0,bi.cloneElement)(n,fr(fr({},K),{},{className:(r?r+" ":"")+"react-resizable",children:[...ke.Children.toArray(n.props.children),...S.map(J=>{var at;let ut=(at=this.handleRefs[J])!=null?at:this.handleRefs[J]=ke.createRef();return ke.createElement(yi.DraggableCore,pr({},o,{nodeRef:ut,key:"resizableHandle-"+J,onStop:this.resizeHandler("onResizeStop",J),onStart:this.resizeHandler("onResizeStart",J),onDrag:this.resizeHandler("onResize",J)}),this.renderResizeHandle(J,ut))})]}))}};mn.default=Ge;Ge.propTypes=vi.resizableProps;Ge.defaultProps={axis:"both",handleSize:[20,20],lockAspectRatio:!1,minConstraints:[20,20],maxConstraints:[1/0,1/0],resizeHandles:["se"],transformScale:1}});var Lo=Mt(vn=>{"use strict";vn.__esModule=!0;vn.default=void 0;var gr=Mo((ct(),ge(ne))),Ri=ko(me()),Ei=ko(hr()),zi=dr(),Oi=["handle","handleSize","onResize","onResizeStart","onResizeStop","draggableOpts","minConstraints","maxConstraints","lockAspectRatio","axis","width","height","resizeHandles","style","transformScale"];function ko(t){return t&&t.__esModule?t:{default:t}}function Mo(t,e){if(typeof WeakMap=="function")var n=new WeakMap,r=new WeakMap;return(Mo=function(o,a){if(!a&&o&&o.__esModule)return o;var s,i,l={__proto__:null,default:o};if(o===null||typeof o!="object"&&typeof o!="function")return l;if(s=a?r:n){if(s.has(o))return s.get(o);s.set(o,l)}for(let c in o)c!=="default"&&{}.hasOwnProperty.call(o,c)&&((i=(s=Object.defineProperty)&&Object.getOwnPropertyDescriptor(o,c))&&(i.get||i.set)?s(l,c,i):l[c]=o[c]);return l})(t,e)}function mr(){return mr=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)({}).hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},mr.apply(null,arguments)}function Po(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter(function(o){return Object.getOwnPropertyDescriptor(t,o).enumerable})),n.push.apply(n,r)}return n}function yn(t){for(var e=1;e<arguments.length;e++){var n=arguments[e]!=null?arguments[e]:{};e%2?Po(Object(n),!0).forEach(function(r){Pi(t,r,n[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):Po(Object(n)).forEach(function(r){Object.defineProperty(t,r,Object.getOwnPropertyDescriptor(n,r))})}return t}function Pi(t,e,n){return(e=ki(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function ki(t){var e=Mi(t,"string");return typeof e=="symbol"?e:e+""}function Mi(t,e){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var r=n.call(t,e||"default");if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(t)}function Li(t,e){if(t==null)return{};var n={};for(var r in t)if({}.hasOwnProperty.call(t,r)){if(e.indexOf(r)!==-1)continue;n[r]=t[r]}return n}var bn=class extends gr.Component{constructor(){super(...arguments),this.state={width:this.props.width,height:this.props.height,propsWidth:this.props.width,propsHeight:this.props.height},this.onResize=(e,n)=>{let r=n.size;this.props.onResize?(e.persist==null||e.persist(),this.setState(r,()=>this.props.onResize&&this.props.onResize(e,n))):this.setState(r)}}static getDerivedStateFromProps(e,n){return n.propsWidth!==e.width||n.propsHeight!==e.height?{width:e.width,height:e.height,propsWidth:e.width,propsHeight:e.height}:null}render(){let e=this.props,n=e.handle,r=e.handleSize,o=e.onResize,a=e.onResizeStart,s=e.onResizeStop,i=e.draggableOpts,l=e.minConstraints,c=e.maxConstraints,f=e.lockAspectRatio,u=e.axis,g=e.width,z=e.height,w=e.resizeHandles,P=e.style,S=e.transformScale,b=Li(e,Oi);return gr.createElement(Ei.default,{axis:u,draggableOpts:i,handle:n,handleSize:r,height:this.state.height,lockAspectRatio:f,maxConstraints:c,minConstraints:l,onResizeStart:a,onResize:this.onResize,onResizeStop:s,resizeHandles:w,transformScale:S,width:this.state.width},gr.createElement("div",mr({},b,{style:yn(yn({},P),{},{width:this.state.width+"px",height:this.state.height+"px"})})))}};vn.default=bn;bn.propTypes=yn(yn({},zi.resizableProps),{},{children:Ri.default.element})});var No=Mt((Ll,wn)=>{"use strict";wn.exports=function(){throw new Error("Don't instantiate Resizable directly! Use require('react-resizable').Resizable")};wn.exports.Resizable=hr().default;wn.exports.ResizableBox=Lo().default});Ce();ct();function oe(t){let{margin:e,containerPadding:n,containerWidth:r,cols:o}=t;return(r-e[0]*(o-1)-n[0]*2)/o}function jt(t,e,n){return Number.isFinite(t)?Math.round(e*t+Math.max(0,t-1)*n):t}function We(t,e,n,r,o,a,s){let{margin:i,containerPadding:l,rowHeight:c}=t,f=oe(t),u,g,z,w;if(s?(u=Math.round(s.width),g=Math.round(s.height)):(u=jt(r,f,i[0]),g=jt(o,c,i[1])),a?(z=Math.round(a.top),w=Math.round(a.left)):s?(z=Math.round(s.top),w=Math.round(s.left)):(z=Math.round((c+i[1])*n+l[1]),w=Math.round((f+i[0])*e+l[0])),!a&&!s){if(Number.isFinite(r)){let S=Math.round((f+i[0])*(e+r)+l[0])-w-u;S!==i[0]&&(u+=S-i[0])}if(Number.isFinite(o)){let S=Math.round((c+i[1])*(n+o)+l[1])-z-g;S!==i[1]&&(g+=S-i[1])}}return{top:z,left:w,width:u,height:g}}function Pr(t,e,n,r,o){let{margin:a,containerPadding:s,cols:i,rowHeight:l,maxRows:c}=t,f=oe(t),u=Math.round((n-s[0])/(f+a[0])),g=Math.round((e-s[1])/(l+a[1]));return u=Be(u,0,i-r),g=Be(g,0,c-o),{x:u,y:g}}function Ae(t,e,n){let{margin:r,containerPadding:o,rowHeight:a}=t,s=oe(t),i=Math.round((n-o[0])/(s+r[0])),l=Math.round((e-o[1])/(a+r[1]));return{x:i,y:l}}function kr(t,e,n){let{margin:r,rowHeight:o}=t,a=oe(t),s=Math.max(1,Math.round((e+r[0])/(a+r[0]))),i=Math.max(1,Math.round((n+r[1])/(o+r[1])));return{w:s,h:i}}function Be(t,e,n){return Math.max(Math.min(t,n),e)}function an(t,e){return!(t.i===e.i||t.x+t.w<=e.x||t.x>=e.x+e.w||t.y+t.h<=e.y||t.y>=e.y+e.h)}function se(t,e){for(let n=0;n<t.length;n++){let r=t[n];if(r!==void 0&&an(r,e))return r}}function kn(t,e){return t.filter(n=>an(n,e))}function Ys(t,e){return e==="horizontal"?Mn(t):e==="vertical"||e==="wrap"?sn(t):[...t]}function sn(t){return[...t].sort((e,n)=>e.y!==n.y?e.y-n.y:e.x-n.x)}function Mn(t){return[...t].sort((e,n)=>e.x!==n.x?e.x-n.x:e.y-n.y)}function qe(t){let e=0;for(let n=0;n<t.length;n++){let r=t[n];if(r!==void 0){let o=r.y+r.h;o>e&&(e=o)}}return e}function ae(t,e){for(let n=0;n<t.length;n++){let r=t[n];if(r!==void 0&&r.i===e)return r}}function Ie(t){return t.filter(e=>e.static===!0)}function Gt(t){return{i:t.i,x:t.x,y:t.y,w:t.w,h:t.h,minW:t.minW,maxW:t.maxW,minH:t.minH,maxH:t.maxH,moved:!!t.moved,static:!!t.static,isDraggable:t.isDraggable,isResizable:t.isResizable,resizeHandles:t.resizeHandles,constraints:t.constraints,isBounded:t.isBounded}}function Re(t){let e=new Array(t.length);for(let n=0;n<t.length;n++){let r=t[n];r!==void 0&&(e[n]=Gt(r))}return e}function Xs(t,e){let n=new Array(t.length);for(let r=0;r<t.length;r++){let o=t[r];o!==void 0&&(e.i===o.i?n[r]=e:n[r]=o)}return n}function Mr(t,e,n){let r=ae(t,e);return r?(r=n(Gt(r)),[Xs(t,r),r]):[[...t],null]}function Ln(t,e){let n=Ie(t);for(let r=0;r<t.length;r++){let o=t[r];if(o!==void 0)if(o.x+o.w>e.cols&&(o.x=e.cols-o.w),o.x<0&&(o.x=0,o.w=e.cols),!o.static)n.push(o);else for(;se(n,o);)o.y++}return t}function re(t,e,n,r,o,a,s,i,l){if(e.static&&e.isDraggable!==!0)return[...t];if(e.y===r&&e.x===n)return[...t];let c=e.x,f=e.y;typeof n=="number"&&(e.x=n),typeof r=="number"&&(e.y=r),e.moved=!0;let u=Ys(t,s);(s==="vertical"&&typeof r=="number"?f>=r:s==="horizontal"&&typeof n=="number"&&c>=n)&&(u=u.reverse());let z=kn(u,e),w=z.length>0;if(w&&l)return Re(t);if(w&&a)return e.x=c,e.y=f,e.moved=!1,t;let P=[...t];for(let S=0;S<z.length;S++){let b=z[S];b!==void 0&&(b.moved||(b.static?P=Or(P,b,e,o,s):P=Or(P,e,b,o,s)))}return P}function Or(t,e,n,r,o,a){let s=o==="horizontal",i=o==="vertical",l=e.static;if(r){r=!1;let u={x:s?Math.max(e.x-n.w,0):n.x,y:i?Math.max(e.y-n.h,0):n.y,w:n.w,h:n.h,i:"-1"},g=se(t,u),z=g!==void 0&&g.y+g.h>e.y,w=g!==void 0&&e.x+e.w>g.x;if(!g)return re(t,n,s?u.x:void 0,i?u.y:void 0,r,l,o);if(z&&i)return re(t,n,void 0,n.y+1,r,l,o);if(z&&o===null)return e.y=n.y,n.y=n.y+n.h,[...t];if(w&&s)return re(t,e,n.x,void 0,r,l,o)}let c=s?n.x+1:void 0,f=i?n.y+1:void 0;return c===void 0&&f===void 0?[...t]:re(t,n,c,f,r,l,o)}function Ee(t,e,n){return Math.max(e,Math.min(n,t))}var $s={name:"gridBounds",constrainPosition(t,e,n,{cols:r,maxRows:o}){return{x:Ee(e,0,Math.max(0,r-t.w)),y:Ee(n,0,Math.max(0,o-t.h))}},constrainSize(t,e,n,r,{cols:o,maxRows:a}){let s=r==="w"||r==="nw"||r==="sw"?t.x+t.w:o-t.x,i=r==="n"||r==="nw"||r==="ne"?t.y+t.h:a-t.y;return{w:Ee(e,1,Math.max(1,s)),h:Ee(n,1,Math.max(1,i))}}},Gs={name:"minMaxSize",constrainSize(t,e,n){return{w:Ee(e,t.minW??1,t.maxW??1/0),h:Ee(n,t.minH??1,t.maxH??1/0)}}};var Nn=[$s,Gs];function Ye(t,e,n,r,o){let a={x:n,y:r};for(let s of t)s.constrainPosition&&(a=s.constrainPosition(e,a.x,a.y,o));if(e.constraints)for(let s of e.constraints)s.constrainPosition&&(a=s.constrainPosition(e,a.x,a.y,o));return a}function Lr(t,e,n,r,o,a){let s={w:n,h:r};for(let i of t)i.constrainSize&&(s=i.constrainSize(e,s.w,s.h,o,a));if(e.constraints)for(let i of e.constraints)i.constrainSize&&(s=i.constrainSize(e,s.w,s.h,o,a));return s}function _n({top:t,left:e,width:n,height:r}){let o=`translate(${e}px,${t}px)`;return{transform:o,WebkitTransform:o,MozTransform:o,msTransform:o,OTransform:o,width:`${n}px`,height:`${r}px`,position:"absolute"}}function Nr({top:t,left:e,width:n,height:r}){return{top:`${t}px`,left:`${e}px`,width:`${n}px`,height:`${r}px`,position:"absolute"}}function Tn(t){return t*100+"%"}function Fs(t,e,n,r){return t+n>r?e:n}function _r(t,e,n){return t<0?e:n}function Us(t){return Math.max(0,t)}function ln(t){return Math.max(0,t)}var jn=(t,e,n)=>{let{left:r,height:o,width:a}=e,s=t.top-(o-t.height);return{left:r,width:a,height:_r(s,t.height,o),top:ln(s)}},Hn=(t,e,n)=>{let{top:r,left:o,height:a,width:s}=e;return{top:r,height:a,width:Fs(t.left,t.width,s,n),left:Us(o)}},Bn=(t,e,n)=>{let{top:r,height:o,width:a}=e,s=t.left+t.width-a;return s<0?{height:o,width:t.left+t.width,top:ln(r),left:0}:{height:o,width:a,top:ln(r),left:s}},Wn=(t,e,n)=>{let{top:r,left:o,height:a,width:s}=e;return{width:s,left:o,height:_r(r,t.height,a),top:ln(r)}},Vs=(t,e,n)=>jn(t,Hn(t,e,n)),Ks=(t,e,n)=>jn(t,Bn(t,e)),Js=(t,e,n)=>Wn(t,Hn(t,e,n)),Zs=(t,e,n)=>Wn(t,Bn(t,e)),Qs={n:jn,ne:Vs,e:Hn,se:Js,s:Wn,sw:Zs,w:Bn,nw:Ks};function Tr(t,e,n,r){let o=Qs[t];return o?o(e,{...e,...n},r):n}var ta={type:"transform",scale:1,calcStyle(t){return _n(t)}};var jr=ta,Hr={cols:12,rowHeight:150,margin:[10,10],containerPadding:null,maxRows:1/0},Br={enabled:!0,bounded:!1,threshold:3},Wr={enabled:!0,handles:["se"]},Ar={enabled:!1,defaultItem:{w:1,h:1}};function An(t,e,n,r,o){let a=r==="x"?"w":"h";e[r]+=1;let s=t.findIndex(l=>l.i===e.i),i=o??Ie(t).length>0;for(let l=s+1;l<t.length;l++){let c=t[l];if(c!==void 0&&!c.static){if(!i&&c.y>e.y+e.h)break;an(e,c)&&An(t,c,n+e[a],r,i)}}e[r]=n}function ea(t,e,n,r){for(e.x=Math.max(e.x,0),e.y=Math.max(e.y,0),e.y=Math.min(r,e.y);e.y>0&&!se(t,e);)e.y--;let o;for(;(o=se(t,e))!==void 0;)An(n,e,o.y+o.h,"y");return e.y=Math.max(e.y,0),e}function na(t,e,n,r){for(e.x=Math.max(e.x,0),e.y=Math.max(e.y,0);e.x>0&&!se(t,e);)e.x--;let o;for(;(o=se(t,e))!==void 0;)if(An(r,e,o.x+o.w,"x"),e.x+e.w>n)for(e.x=n-e.w,e.y++;e.x>0&&!se(t,e);)e.x--;return e.x=Math.max(e.x,0),e}var qr={type:"vertical",allowOverlap:!1,compact(t,e){let n=Ie(t),r=qe(n),o=sn(t),a=new Array(t.length);for(let s=0;s<o.length;s++){let i=o[s];if(i===void 0)continue;let l=Gt(i);l.static||(l=ea(n,l,o,r),r=Math.max(r,l.y+l.h),n.push(l));let c=t.indexOf(i);a[c]=l,l.moved=!1}return a}},Ir={type:"horizontal",allowOverlap:!1,compact(t,e){let n=Ie(t),r=Mn(t),o=new Array(t.length);for(let a=0;a<r.length;a++){let s=r[a];if(s===void 0)continue;let i=Gt(s);i.static||(i=na(n,i,e,r),n.push(i));let l=t.indexOf(s);o[l]=i,i.moved=!1}return o}},Yr={type:null,allowOverlap:!1,compact(t,e){return Re(t)}},ra={...qr,allowOverlap:!0,compact(t,e){return Re(t)}},oa={...Ir,allowOverlap:!0,compact(t,e){return Re(t)}},sa={...Yr,allowOverlap:!0};function Xr(t,e=!1,n=!1){let r;return e?t==="vertical"?r=ra:t==="horizontal"?r=oa:r=sa:t==="vertical"?r=qr:t==="horizontal"?r=Ir:r=Yr,n?{...r,preventCollision:n}:r}ct();function aa(t){let e=typeof globalThis.getComputedStyle=="function"?globalThis.getComputedStyle(t):null;if(!e)return t.clientWidth;let n=o=>{let a=Number.parseFloat(o);return Number.isFinite(a)?a:0},r=Number.parseFloat(e.width);return Number.isFinite(r)?Math.max(0,r):Math.max(0,t.clientWidth-n(e.paddingLeft)-n(e.paddingRight))}function qn(t={}){let{measureBeforeMount:e=!1,initialWidth:n=1280}=t,[r,o]=st(n),[a,s]=st(!e),i=I(null),l=I(null),c=U(()=>{let f=i.current;if(f){let u=Math.round(aa(f));o(g=>g===u?g:u),a||s(!0)}},[a]);return It(()=>{let f=i.current;if(f){if(c(),typeof ResizeObserver<"u"){let u=null;return l.current=new ResizeObserver(g=>{let z=g[0];if(z){let w=Math.round(z.contentRect.width);u!==null&&cancelAnimationFrame(u),u=requestAnimationFrame(()=>{o(P=>P===w?P:w),u=null})}}),l.current.observe(f),()=>{u!==null&&cancelAnimationFrame(u),l.current&&(l.current.disconnect(),l.current=null)}}return()=>{l.current&&(l.current.disconnect(),l.current=null)}}},[c]),{width:r,mounted:a,containerRef:i,measureWidth:c}}ct();ct();var G=on(me(),1);Ce();function to(t){var e,n,r="";if(typeof t=="string"||typeof t=="number")r+=t;else if(typeof t=="object")if(Array.isArray(t)){var o=t.length;for(e=0;e<o;e++)t[e]&&(n=to(t[e]))&&(r&&(r+=" "),r+=n)}else for(n in t)t[n]&&(r&&(r+=" "),r+=n);return r}function In(){for(var t,e,n=0,r="",o=arguments.length;n<o;n++)(t=arguments[n])&&(e=to(t))&&(r&&(r+=" "),r+=e);return r}var Yn=In;ct();var gt=on(me(),1);Ce();function Kn(t,e){for(let n=0,r=t.length;n<r;n++)if(e.apply(e,[t[n],n,t]))return t[n]}function eo(t){return typeof t=="function"||Object.prototype.toString.call(t)==="[object Function]"}function Xe(t){return typeof t=="number"&&!isNaN(t)}function yt(t){return parseInt(t,10)}function ze(t,e,n){if(t[e])return new Error(`Invalid prop ${e} passed to ${n} - do not set this, set it on the child.`)}var Xn=["Moz","Webkit","O","ms"];function ca(t="transform"){var e,n;if(typeof window>"u")return"";let r=(n=(e=window.document)==null?void 0:e.documentElement)==null?void 0:n.style;if(!r||t in r)return"";for(let o=0;o<Xn.length;o++)if(ao(t,Xn[o])in r)return Xn[o];return""}function ao(t,e){return e?`${e}${ua(t)}`:t}function ua(t){let e="",n=!0;for(let r=0;r<t.length;r++)n?(e+=t[r].toUpperCase(),n=!1):t[r]==="-"?n=!0:e+=t[r];return e}var da=ca(),$n="";function fa(t,e){var n;$n||($n=(n=Kn(["matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector"],function(o){return eo(t[o])}))!=null?n:"");let r=t[$n];return eo(r)?!!r.call(t,e):!1}function no(t,e,n){let r=t;do{if(fa(r,e))return!0;if(r===n)return!1;r=r.parentNode}while(r);return!1}function Gn(t,e,n,r){if(!t)return;let o={capture:!0,...r},a=n;t.addEventListener?t.addEventListener(e,a,o):t.attachEvent?t.attachEvent("on"+e,a):t["on"+e]=a}function ye(t,e,n,r){if(!t)return;let o={capture:!0,...r},a=n;t.removeEventListener?t.removeEventListener(e,a,o):t.detachEvent?t.detachEvent("on"+e,a):t["on"+e]=null}function pa(t){let e=t.clientHeight,n=t.ownerDocument.defaultView.getComputedStyle(t);return e+=yt(n.borderTopWidth),e+=yt(n.borderBottomWidth),e}function ha(t){let e=t.clientWidth,n=t.ownerDocument.defaultView.getComputedStyle(t);return e+=yt(n.borderLeftWidth),e+=yt(n.borderRightWidth),e}function ga(t){let e=t.clientHeight,n=t.ownerDocument.defaultView.getComputedStyle(t);return e-=yt(n.paddingTop),e-=yt(n.paddingBottom),e}function ma(t){let e=t.clientWidth,n=t.ownerDocument.defaultView.getComputedStyle(t);return e-=yt(n.paddingLeft),e-=yt(n.paddingRight),e}function ya(t,e,n){let o=e===e.ownerDocument.body?{left:0,top:0}:e.getBoundingClientRect(),a=(t.clientX+e.scrollLeft-o.left)/n,s=(t.clientY+e.scrollTop-o.top)/n;return{x:a,y:s}}function ba(t,e){let n=io(t,e,"px");return{[ao("transform",da)]:n}}function va(t,e){return io(t,e,"")}function io({x:t,y:e},n,r){let o=`translate(${t}${r},${e}${r})`;if(n){let a=`${typeof n.x=="string"?n.x:n.x+r}`,s=`${typeof n.y=="string"?n.y:n.y+r}`;o=`translate(${a}, ${s})`+o}return o}function wa(t,e){return t.targetTouches&&Kn(t.targetTouches,n=>e===n.identifier)||t.changedTouches&&Kn(t.changedTouches,n=>e===n.identifier)}function Sa(t){if(t.targetTouches&&t.targetTouches[0])return t.targetTouches[0].identifier;if(t.changedTouches&&t.changedTouches[0])return t.changedTouches[0].identifier}function xa(){return typeof __webpack_nonce__<"u"?__webpack_nonce__:void 0}function Da(t,e){if(!t)return;let n=t.getElementById("react-draggable-style-el");if(!n){n=t.createElement("style"),n.type="text/css",n.id="react-draggable-style-el";let r=e??xa();r&&n.setAttribute("nonce",r),n.innerHTML=`.react-draggable-transparent-selection *::-moz-selection {all: inherit;}
4
+ `,n.innerHTML+=`.react-draggable-transparent-selection *::selection {all: inherit;}
5
+ `,t.getElementsByTagName("head")[0].appendChild(n)}t.body&&Ca(t.body,"react-draggable-transparent-selection")}function ro(t){window.requestAnimationFrame?window.requestAnimationFrame(()=>{oo(t)}):oo(t)}function oo(t){if(t)try{t.body&&Ra(t.body,"react-draggable-transparent-selection");let e=t.selection;if(e)e.empty();else{let n=(t.defaultView||window).getSelection();n&&n.type!=="Caret"&&n.removeAllRanges()}}catch{}}function Ca(t,e){t.classList?t.classList.add(e):t.className.match(new RegExp(`(?:^|\\s)${e}(?!\\S)`))||(t.className+=` ${e}`)}function Ra(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp(`(?:^|\\s)${e}(?!\\S)`,"g"),"")}function Ea(t,e,n){if(!t.props.bounds)return[e,n];let{bounds:r}=t.props;r=typeof r=="string"?r:Pa(r);let o=Jn(t);if(typeof r=="string"){let{ownerDocument:a}=o,s=a.defaultView;if(!s)throw new Error("Cannot resolve the owner window of the draggable node.");let i;if(r==="parent"?i=o.parentNode:i=o.getRootNode().querySelector(r),!(i instanceof s.HTMLElement))throw new Error('Bounds selector "'+r+'" could not find an element.');let l=i,c=s.getComputedStyle(o),f=s.getComputedStyle(l);r={left:-o.offsetLeft+yt(f.paddingLeft)+yt(c.marginLeft),top:-o.offsetTop+yt(f.paddingTop)+yt(c.marginTop),right:ma(l)-ha(o)-o.offsetLeft+yt(f.paddingRight)-yt(c.marginRight),bottom:ga(l)-pa(o)-o.offsetTop+yt(f.paddingBottom)-yt(c.marginBottom)}}return Xe(r.right)&&(e=Math.min(e,r.right)),Xe(r.bottom)&&(n=Math.min(n,r.bottom)),Xe(r.left)&&(e=Math.max(e,r.left)),Xe(r.top)&&(n=Math.max(n,r.top)),[e,n]}function so(t,e,n){let r=Math.round(e/t[0])*t[0],o=Math.round(n/t[1])*t[1];return[r,o]}function za(t){return t.props.axis==="both"||t.props.axis==="x"}function Oa(t){return t.props.axis==="both"||t.props.axis==="y"}function Fn(t,e,n){let r=typeof e=="number"?wa(t,e):null;if(typeof e=="number"&&!r)return null;let o=Jn(n),a=n.props.offsetParent||o.offsetParent||o.ownerDocument.body;return ya(r||t,a,n.props.scale)}function Un(t,e,n){let r=!Xe(t.lastX),o=Jn(t);return r?{node:o,deltaX:0,deltaY:0,lastX:e,lastY:n,x:e,y:n}:{node:o,deltaX:e-t.lastX,deltaY:n-t.lastY,lastX:t.lastX,lastY:t.lastY,x:e,y:n}}function Vn(t,e){let n=t.props.scale;return{node:e.node,x:t.state.x+e.deltaX/n,y:t.state.y+e.deltaY/n,deltaX:e.deltaX/n,deltaY:e.deltaY/n,lastX:t.state.x,lastY:t.state.y}}function Pa(t){return{left:t.left,top:t.top,right:t.right,bottom:t.bottom}}function Jn(t){let e=t.findDOMNode();if(!e)throw new Error("<DraggableCore>: Unmounted during event!");return e}var ka=typeof process<"u"&&process.env.DRAGGABLE_DEBUG?console.log.bind(console):function(){},Yt=ka,Ht={touch:{start:"touchstart",move:"touchmove",stop:"touchend"},mouse:{start:"mousedown",move:"mousemove",stop:"mouseup"}},ie=Ht.mouse,Ft=class extends je{constructor(){super(...arguments),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,this.touchIdentifier=null,this.mounted=!1,this.handleDragStart=t=>{if(this.props.onMouseDown(t),!this.props.allowAnyClick&&(typeof t.button=="number"&&t.button!==0||t.ctrlKey))return!1;let e=this.findDOMNode();if(!e||!e.ownerDocument||!e.ownerDocument.body)throw new Error("<DraggableCore> not mounted on DragStart!");let{ownerDocument:n}=e;if(this.props.disabled||!(t.target instanceof n.defaultView.Node)||this.props.handle&&!no(t.target,this.props.handle,e)||this.props.cancel&&no(t.target,this.props.cancel,e))return;t.type==="touchstart"&&!this.props.allowMobileScroll&&t.preventDefault();let r=Sa(t);this.touchIdentifier=r;let o=Fn(t,r,this);if(o==null)return;let{x:a,y:s}=o,i=Un(this,a,s);Yt("DraggableCore: handleDragStart: %j",i),Yt("calling",this.props.onStart),!(this.props.onStart(t,i)===!1||this.mounted===!1)&&(this.props.enableUserSelectHack&&Da(n,this.props.nonce),this.dragging=!0,this.lastX=a,this.lastY=s,Gn(n,ie.move,this.handleDrag),Gn(n,ie.stop,this.handleDragStop))},this.handleDrag=t=>{let e=Fn(t,this.touchIdentifier,this);if(e==null)return;let{x:n,y:r}=e;if(Array.isArray(this.props.grid)){let s=n-this.lastX,i=r-this.lastY;if([s,i]=so(this.props.grid,s,i),!s&&!i)return;n=this.lastX+s,r=this.lastY+i}let o=Un(this,n,r);if(Yt("DraggableCore: handleDrag: %j",o),this.props.onDrag(t,o)===!1||this.mounted===!1){try{this.handleDragStop(new MouseEvent("mouseup"))}catch{let s=document.createEvent("MouseEvents");s.initMouseEvent("mouseup",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),this.handleDragStop(s)}return}this.lastX=n,this.lastY=r},this.handleDragStop=t=>{if(!this.dragging)return;let e=Fn(t,this.touchIdentifier,this);if(e==null)return;let{x:n,y:r}=e;if(Array.isArray(this.props.grid)){let i=n-this.lastX||0,l=r-this.lastY||0;[i,l]=so(this.props.grid,i,l),n=this.lastX+i,r=this.lastY+l}let o=Un(this,n,r);if(this.props.onStop(t,o)===!1||this.mounted===!1)return!1;let s=this.findDOMNode();s&&this.props.enableUserSelectHack&&ro(s.ownerDocument),Yt("DraggableCore: handleDragStop: %j",o),this.dragging=!1,this.lastX=NaN,this.lastY=NaN,s&&(Yt("DraggableCore: Removing handlers"),ye(s.ownerDocument,ie.move,this.handleDrag),ye(s.ownerDocument,ie.stop,this.handleDragStop))},this.onMouseDown=t=>(ie=Ht.mouse,this.handleDragStart(t)),this.onMouseUp=t=>(ie=Ht.mouse,this.handleDragStop(t)),this.onTouchStart=t=>(ie=Ht.touch,this.handleDragStart(t)),this.onTouchEnd=t=>(ie=Ht.touch,this.handleDragStop(t))}componentDidMount(){this.mounted=!0;let t=this.findDOMNode();t&&Gn(t,Ht.touch.start,this.onTouchStart,{passive:!1})}componentWillUnmount(){this.mounted=!1;let t=this.findDOMNode();if(t){let{ownerDocument:e}=t;ye(e,Ht.mouse.move,this.handleDrag),ye(e,Ht.touch.move,this.handleDrag),ye(e,Ht.mouse.stop,this.handleDragStop),ye(e,Ht.touch.stop,this.handleDragStop),ye(t,Ht.touch.start,this.onTouchStart,{passive:!1}),this.props.enableUserSelectHack&&ro(e)}}findDOMNode(){var t;if((t=this.props)!=null&&t.nodeRef)return this.props.nodeRef.current;let e=_e;return typeof e.findDOMNode=="function"?e.findDOMNode(this):(Yt("react-draggable: ReactDOM.findDOMNode is not available in React 19+. You must provide a nodeRef prop. See: https://github.com/react-grid-layout/react-draggable#noderef"),null)}render(){return He(Te.only(this.props.children),{onMouseDown:this.onMouseDown,onMouseUp:this.onMouseUp,onTouchEnd:this.onTouchEnd})}};Ft.displayName="DraggableCore";Ft.propTypes={allowAnyClick:gt.default.bool,allowMobileScroll:gt.default.bool,children:gt.default.node.isRequired,disabled:gt.default.bool,enableUserSelectHack:gt.default.bool,offsetParent:function(t,e){if(t[e]&&t[e].nodeType!==1)throw new Error("Draggable's offsetParent must be a DOM Node.")},grid:gt.default.arrayOf(gt.default.number),handle:gt.default.string,cancel:gt.default.string,nodeRef:gt.default.object,nonce:gt.default.string,onStart:gt.default.func,onDrag:gt.default.func,onStop:gt.default.func,onMouseDown:gt.default.func,scale:gt.default.number,className:ze,style:ze,transform:ze};Ft.defaultProps={allowAnyClick:!1,allowMobileScroll:!1,disabled:!1,enableUserSelectHack:!0,onStart:function(){},onDrag:function(){},onStop:function(){},onMouseDown:function(){},scale:1};var un=class extends je{constructor(t){super(t),this.onDragStart=(e,n)=>{if(Yt("Draggable: onDragStart: %j",n),this.props.onStart(e,Vn(this,n))===!1)return!1;this.setState({dragging:!0,dragged:!0})},this.onDrag=(e,n)=>{if(!this.state.dragging)return!1;Yt("Draggable: onDrag: %j",n);let r=Vn(this,n),o={x:r.x,y:r.y,slackX:0,slackY:0};if(this.props.bounds){let{x:s,y:i}=o;o.x+=this.state.slackX,o.y+=this.state.slackY;let[l,c]=Ea(this,o.x,o.y);o.x=l,o.y=c,o.slackX=this.state.slackX+(s-o.x),o.slackY=this.state.slackY+(i-o.y),r.x=o.x,r.y=o.y,r.deltaX=o.x-this.state.x,r.deltaY=o.y-this.state.y}if(this.props.onDrag(e,r)===!1)return!1;this.setState(o)},this.onDragStop=(e,n)=>{if(!this.state.dragging||this.props.onStop(e,Vn(this,n))===!1)return!1;Yt("Draggable: onDragStop: %j",n);let o={dragging:!1,slackX:0,slackY:0};if(!!this.props.position){let{x:s,y:i}=this.props.position;o.x=s,o.y=i}this.setState(o)},this.state={dragging:!1,dragged:!1,x:t.position?t.position.x:t.defaultPosition.x,y:t.position?t.position.y:t.defaultPosition.y,prevPropsPosition:{...t.position},slackX:0,slackY:0,isElementSVG:!1},t.position&&!(t.onDrag||t.onStop)&&console.warn("A `position` was applied to this <Draggable>, without drag handlers. This will make this component effectively undraggable. Please attach `onDrag` or `onStop` handlers so you can adjust the `position` of this element.")}static getDerivedStateFromProps({position:t},{prevPropsPosition:e}){return t&&(!e||t.x!==e.x||t.y!==e.y)?(Yt("Draggable: getDerivedStateFromProps %j",{position:t,prevPropsPosition:e}),{x:t.x,y:t.y,prevPropsPosition:{...t}}):null}componentDidMount(){typeof window.SVGElement<"u"&&this.findDOMNode()instanceof window.SVGElement&&this.setState({isElementSVG:!0})}componentWillUnmount(){this.state.dragging&&this.setState({dragging:!1})}findDOMNode(){var t;if((t=this.props)!=null&&t.nodeRef)return this.props.nodeRef.current;let e=_e;return typeof e.findDOMNode=="function"?e.findDOMNode(this):null}render(){let{axis:t,bounds:e,children:n,defaultPosition:r,defaultClassName:o,defaultClassNameDragging:a,defaultClassNameDragged:s,position:i,positionOffset:l,scale:c,...f}=this.props,u={},g=null,w=!!!i||this.state.dragging,P=i||r,S={x:za(this)&&w?this.state.x:P.x,y:Oa(this)&&w?this.state.y:P.y};this.state.isElementSVG?g=va(S,l):u=ba(S,l);let b=Te.only(n),K=In(b.props.className||"",o,{[a]:this.state.dragging,[s]:this.state.dragged});return Pn(Ft,{...f,onStart:this.onDragStart,onDrag:this.onDrag,onStop:this.onDragStop},He(b,{className:K,style:{...b.props.style,...u},transform:g}))}};un.displayName="Draggable";un.propTypes={...Ft.propTypes,axis:G.default.oneOf(["both","x","y","none"]),bounds:G.default.oneOfType([G.default.shape({left:G.default.number,right:G.default.number,top:G.default.number,bottom:G.default.number}),G.default.string,G.default.oneOf([!1])]),defaultClassName:G.default.string,defaultClassNameDragging:G.default.string,defaultClassNameDragged:G.default.string,defaultPosition:G.default.shape({x:G.default.number,y:G.default.number}),positionOffset:G.default.shape({x:G.default.oneOfType([G.default.number,G.default.string]),y:G.default.oneOfType([G.default.number,G.default.string])}),position:G.default.shape({x:G.default.number,y:G.default.number}),className:ze,style:ze,transform:ze};un.defaultProps={...Ft.defaultProps,axis:"both",bounds:!1,defaultClassName:"react-draggable",defaultClassNameDragging:"react-draggable-dragging",defaultClassNameDragged:"react-draggable-dragged",defaultPosition:{x:0,y:0},scale:1};var Bo=on(No(),1);var _o=globalThis.React,Nl=_o.Fragment,ce=(t,e,n)=>_o.createElement(t,n===void 0?e:{...e,key:n}),To=ce;var we=on(Gr(),1);function yr(t){let{children:e,cols:n,containerWidth:r,margin:o,containerPadding:a,rowHeight:s,maxRows:i,isDraggable:l,isResizable:c,isBounded:f,static:u,useCSSTransforms:g=!0,usePercentages:z=!1,transformScale:w=1,positionStrategy:P,dragThreshold:S=0,droppingPosition:b,className:K="",style:J,handle:at="",cancel:ut="",x:it,y:rt,w:et,h:lt,minW:Rt=1,maxW:Wt=1/0,minH:C=1,maxH:R=1/0,i:Y,resizeHandles:Ot,resizeHandle:xt,constraints:Et=Nn,layoutItem:ue,layout:de=[],onDragStart:Nt,onDrag:Vt,onDragStop:Kt,onResizeStart:fe,onResize:pe,onResizeStop:he}=t,[d,m]=st(!1),[k,y]=st(!1),x=I(null),D=I({left:0,top:0}),j=I({top:0,left:0,width:0,height:0}),F=I(void 0),W=I(de);W.current=de;let ot=I(null),M=I(null),N=I(!1),pt=I({x:0,y:0}),X=I(!1),B=Ct(()=>({cols:n,containerPadding:a,containerWidth:r,margin:o,maxRows:i,rowHeight:s}),[n,a,r,o,i,s]),$=Ct(()=>({cols:n,maxRows:i,containerWidth:r,containerHeight:0,rowHeight:s,margin:o,layout:[]}),[n,i,r,s,o]),ht=U(()=>({...$,layout:W.current}),[$]),_t=Ct(()=>ue??{i:Y,x:it,y:rt,w:et,h:lt,minW:Rt,maxW:Wt,minH:C,maxH:R},[ue,Y,it,rt,et,lt,Rt,Wt,C,R]),Ue=U(_=>{if(P?.calcStyle)return P.calcStyle(_);if(g)return _n(_);let H=Nr(_);return z?{...H,left:Tn(_.left/r),width:Tn(_.width/r)}:H},[P,g,z,r]),At=U((_,{node:H})=>{if(!Nt)return;let{offsetParent:nt}=H;if(!nt)return;let A=nt.getBoundingClientRect(),dt=H.getBoundingClientRect(),wt=dt.left/w,Dt=A.left/w,St=dt.top/w,Pt=A.top/w,kt;if(P?.calcDragPosition){let O=_;kt=P.calcDragPosition(O.clientX,O.clientY,O.clientX-dt.left,O.clientY-dt.top)}else kt={left:wt-Dt+nt.scrollLeft,top:St-Pt+nt.scrollTop};if(D.current=kt,S>0){let O=_;pt.current={x:O.clientX,y:O.clientY},N.current=!0,X.current=!1,m(!0);return}m(!0);let te=Ae(B,kt.top,kt.left),{x:ee,y:h}=Ye(Et,_t,te.x,te.y,ht());Nt(Y,ee,h,{e:_,node:H,newPosition:kt})},[Nt,w,B,P,S,Et,_t,ht,Y]),Se=U((_,{node:H,deltaX:nt,deltaY:A})=>{if(!Vt||!d)return;let dt=_;if(N.current&&!X.current){let ee=dt.clientX-pt.current.x,h=dt.clientY-pt.current.y;if(Math.hypot(ee,h)<S)return;if(X.current=!0,N.current=!1,Nt){let v=Ae(B,D.current.top,D.current.left),{x:L,y:q}=Ye(Et,_t,v.x,v.y,ht());Nt(Y,L,q,{e:_,node:H,newPosition:D.current})}}let wt=D.current.top+A,Dt=D.current.left+nt;if(f){let{offsetParent:ee}=H;if(ee){let h=ee.clientHeight-jt(lt,s,o[1]);wt=Be(wt,0,h);let O=oe(B),v=r-jt(et,O,o[0]);Dt=Be(Dt,0,v)}}let St={top:wt,left:Dt};D.current=St;let Pt=Ae(B,wt,Dt),{x:kt,y:te}=Ye(Et,_t,Pt.x,Pt.y,ht());Vt(Y,kt,te,{e:_,node:H,newPosition:St})},[Vt,Nt,d,S,f,lt,s,o,B,r,et,Y,Et,_t,ht]),Jt=U((_,{node:H})=>{if(!Kt||!d)return;let nt=N.current;if(N.current=!1,X.current=!1,pt.current={x:0,y:0},nt){m(!1),D.current={left:0,top:0};return}let{left:A,top:dt}=D.current,wt={top:dt,left:A};m(!1),D.current={left:0,top:0};let Dt=Ae(B,dt,A),{x:St,y:Pt}=Ye(Et,_t,Dt.x,Dt.y,ht());Kt(Y,St,Pt,{e:_,node:H,newPosition:wt})},[Kt,d,B,Et,_t,ht,Y]);ot.current=At,M.current=Se;let Tt=U((_,{node:H,size:nt,handle:A},dt,wt)=>{let Dt=wt==="onResizeStart"?fe:wt==="onResize"?pe:he;if(!Dt)return;let St;H?St=Tr(A,dt,nt,r):St={...nt,top:dt.top,left:dt.left},j.current=St;let Pt=kr(B,St.width,St.height),{w:kt,h:te}=Lr(Et,_t,Pt.w,Pt.h,A,ht());Dt(Y,kt,te,{e:_.nativeEvent??_,node:H,size:St,handle:A})},[fe,pe,he,r,B,Y,Et,_t,ht]),xe=U((_,H)=>{y(!0);let nt=We(B,it,rt,et,lt),A={...H,handle:H.handle};Tt(_,A,nt,"onResizeStart")},[Tt,B,it,rt,et,lt]),De=U((_,H)=>{let nt=We(B,it,rt,et,lt),A={...H,handle:H.handle};Tt(_,A,nt,"onResize")},[Tt,B,it,rt,et,lt]),Zt=U((_,H)=>{y(!1),j.current={top:0,left:0,width:0,height:0};let nt=We(B,it,rt,et,lt),A={...H,handle:H.handle};Tt(_,A,nt,"onResizeStop")},[Tt,B,it,rt,et,lt]);It(()=>{if(!b)return;let _=x.current;if(!_)return;let H=F.current||{left:0,top:0},nt=d&&(b.left!==H.left||b.top!==H.top);if(d){if(nt){let A=b.left-D.current.left,dt=b.top-D.current.top,wt={node:_,deltaX:A,deltaY:dt,lastX:D.current.left,lastY:D.current.top,x:b.left,y:b.top};M.current?.(b.e,wt)}}else{let A={node:_,deltaX:b.left,deltaY:b.top,lastX:0,lastY:0,x:b.left,y:b.top};ot.current?.(b.e,A)}F.current=b},[b,d,Y]);let qt=We(B,it,rt,et,lt,d?D.current:null,k?j.current:null),Me=p.Children.only(e),Le=oe(B),Ve=[jt(Rt,Le,o[0]),jt(C,s,o[1])],Ke=[jt(Wt,Le,o[0]),jt(R,s,o[1])],zt=Me.props,Cn=zt.className,Je=zt.style,Qt=p.cloneElement(Me,{ref:x,className:Yn("react-grid-item",Cn,K,{static:u,resizing:k,"react-draggable":l,"react-draggable-dragging":d,dropping:!!b,cssTransforms:g}),style:{...J,...Je,...Ue(qt)}}),Ze=xt;return Qt=ce(Bo.Resizable,{draggableOpts:{disabled:!c},className:c?void 0:"react-resizable-hide",width:qt.width,height:qt.height,minConstraints:Ve,maxConstraints:Ke,onResizeStart:xe,onResize:De,onResizeStop:Zt,transformScale:w,resizeHandles:Ot,handle:Ze,children:Qt}),Qt=ce(Ft,{disabled:!l,onStart:At,onDrag:Se,onStop:Jt,handle:at,cancel:".react-resizable-handle"+(ut?","+ut:""),scale:w,nodeRef:x,children:Qt}),Qt}var Ut=()=>{},jo="react-grid-layout",Wo=!1;try{Wo=/firefox/i.test(navigator.userAgent)}catch{}function Ni(t,e){let n=p.Children.toArray(t),r=p.Children.toArray(e);if(n.length!==r.length)return!1;for(let o=0;o<n.length;o++){let a=n[o],s=r[o];if(a?.key!==s?.key)return!1}return!0}function Ho(t,e,n,r){let o=[],a=new Set;p.Children.forEach(e,i=>{if(!p.isValidElement(i)||i.key===null)return;let l=String(i.key);a.add(l);let c=t.find(f=>f.i===l);if(c)o.push(Gt(c));else{let u=i.props["data-grid"];u?o.push({i:l,x:u.x??0,y:u.y??0,w:u.w??1,h:u.h??1,minW:u.minW,maxW:u.maxW,minH:u.minH,maxH:u.maxH,static:u.static,isDraggable:u.isDraggable,isResizable:u.isResizable,resizeHandles:u.resizeHandles,isBounded:u.isBounded}):o.push({i:l,x:0,y:qe(o),w:1,h:1})}});let s=Ln(o,{cols:n});return r.compact(s,n)}function Fe(t){let{children:e,width:n,gridConfig:r,dragConfig:o,resizeConfig:a,dropConfig:s,positionStrategy:i=jr,compactor:l,constraints:c=Nn,layout:f=[],droppingItem:u,autoSize:g=!0,className:z="",style:w={},innerRef:P,onLayoutChange:S=Ut,onDragStart:b=Ut,onDrag:K=Ut,onDragStop:J=Ut,onResizeStart:at=Ut,onResize:ut=Ut,onResizeStop:it=Ut,onDrop:rt=Ut,onDropDragOver:et=Ut}=t,lt=Ct(()=>({...Hr,...r}),[r]),Rt=Ct(()=>({...Br,...o}),[o]),Wt=Ct(()=>({...Wr,...a}),[a]),C=Ct(()=>({...Ar,...s}),[s]),{cols:R,rowHeight:Y,maxRows:Ot,margin:xt,containerPadding:Et}=lt,{enabled:ue,bounded:de,handle:Nt,cancel:Vt,threshold:Kt}=Rt,{enabled:fe,handles:pe,handleComponent:he}=Wt,{enabled:d,defaultItem:m,onDragOver:k}=C,y=l??Xr("vertical"),x=y.type,D=y.allowOverlap,j=y.preventCollision??!1,F=Ct(()=>u??{i:"__dropping-elem__",...m},[u,m]),W=i.type==="transform",ot=i.scale,M=Et??xt,[N,pt]=st(!1),[X,B]=st(()=>Ho(f,e,R,y)),[$,ht]=st(null),[_t,Ue]=st(!1),[At,Se]=st(null),[Jt,Tt]=st(),xe=I(null),De=I(null),Zt=I(null),qt=I(0),Me=I(X),Le=I(f),Ve=I(e),Ke=I(x),zt=I(X);zt.current=X,It(()=>{pt(!0),(0,we.deepEqual)(X,f)||S(X)},[]),It(()=>{if($||At)return;let h=!(0,we.deepEqual)(f,Le.current),O=!Ni(e,Ve.current),v=x!==Ke.current;if(h||O||v){let q=Ho(h?f:X,e,R,y);(0,we.deepEqual)(q,X)||B(q)}Le.current=f,Ve.current=e,Ke.current=x},[f,e,R,x,y,$,At,X]),It(()=>{if(!$&&!(0,we.deepEqual)(X,Me.current)){Me.current=X;let h=X.filter(O=>O.i!==F.i);S(h)}},[X,$,S,F.i]);let Cn=Ct(()=>{if(!g)return;let h=qe(X),O=M[1];return h*Y+(h-1)*xt[1]+O*2+"px"},[g,X,Y,xt,M]),Je=U((h,O,v,L)=>{let q=zt.current,T=ae(q,h);if(!T)return;let Z={w:T.w,h:T.h,x:T.x,y:T.y,i:h};xe.current=Gt(T),Zt.current=q,ht(Z),b(q,T,T,null,L.e,L.node)},[b]),Qt=U((h,O,v,L)=>{let q=zt.current,T=xe.current,Z=ae(q,h);if(!Z)return;let ft={w:Z.w,h:Z.h,x:Z.x,y:Z.y,i:h},Q=re(q,Z,O,v,!0,j,x,R,D);K(Q,T,Z,ft,L.e,L.node),B(y.compact(Q,R)),ht(ft)},[j,x,R,D,y,K]),Ze=U((h,O,v,L)=>{if(!$)return;let q=zt.current,T=xe.current,Z=ae(q,h);if(!Z)return;let ft=re(q,Z,O,v,!0,j,x,R,D),Q=y.compact(ft,R);J(Q,T,Z,null,L.e,L.node);let mt=Zt.current;xe.current=null,Zt.current=null,ht(null),B(Q),mt&&!(0,we.deepEqual)(mt,Q)&&S(Q)},[$,j,x,R,D,y,J,S]),_=U((h,O,v,L)=>{let q=zt.current,T=ae(q,h);T&&(De.current=Gt(T),Zt.current=q,Ue(!0),at(q,T,T,null,L.e,L.node))},[at]),H=U((h,O,v,L)=>{let q=zt.current,T=De.current,{handle:Z}=L,ft=!1,Q,mt,[Qe,$t]=Mr(q,h,tt=>(Q=tt.x,mt=tt.y,["sw","w","nw","n","ne"].includes(Z)&&(["sw","nw","w"].includes(Z)&&(Q=tt.x+(tt.w-O),O=tt.x!==Q&&Q<0?tt.w:O,Q=Q<0?0:Q),["ne","n","nw"].includes(Z)&&(mt=tt.y+(tt.h-v),v=tt.y!==mt&&mt<0?tt.h:v,mt=mt<0?0:mt),ft=!0),j&&!D&&kn(q,{...tt,w:O,h:v,x:Q??tt.x,y:mt??tt.y}).filter(en=>en.i!==tt.i).length>0&&(mt=tt.y,v=tt.h,Q=tt.x,O=tt.w,ft=!1),tt.w=O,tt.h=v,tt));if(!$t)return;let Ne=Qe;ft&&Q!==void 0&&mt!==void 0&&(Ne=re(Qe,$t,Q,mt,!0,j,x,R,D));let tn={w:$t.w,h:$t.h,x:$t.x,y:$t.y,i:h,static:!0};ut(Ne,T,$t,tn,L.e,L.node),B(y.compact(Ne,R)),ht(tn)},[j,x,R,D,y,ut]),nt=U((h,O,v,L)=>{let q=zt.current,T=De.current,Z=ae(q,h),ft=y.compact(q,R);it(ft,T,Z??null,null,L.e,L.node);let Q=Zt.current;De.current=null,Zt.current=null,ht(null),Ue(!1),B(ft),Q&&!(0,we.deepEqual)(Q,ft)&&S(ft)},[R,y,it,S]),A=U(()=>{let h=zt.current;if(!h.some(L=>L.i===F.i)){Se(null),ht(null),Tt(void 0);return}let v=y.compact(h.filter(L=>L.i!==F.i),R);B(v),Se(null),ht(null),Tt(void 0)},[F.i,R,y]),dt=U(h=>{if(h.preventDefault(),h.stopPropagation(),Wo&&!h.nativeEvent.target?.classList.contains(jo))return!1;let O=k?k(h.nativeEvent):et(h);if(O===!1)return At&&A(),!1;let{dragOffsetX:v=0,dragOffsetY:L=0,...q}=O??{},T={...F,...q},Z=h.currentTarget.getBoundingClientRect(),ft={cols:R,margin:xt,maxRows:Ot,rowHeight:Y,containerWidth:n,containerPadding:M},Q=oe(ft),mt=jt(T.w,Q,xt[0]),Qe=jt(T.h,Y,xt[1]),$t=mt/2,Ne=Qe/2,tn=h.clientX-Z.left+v-$t,tt=h.clientY-Z.top+L-Ne,Rn=Math.max(0,tn),en=Math.max(0,tt),nn={left:Rn/ot,top:en/ot,e:h.nativeEvent};if(At)Jt&&(Jt.left!==nn.left||Jt.top!==nn.top)&&Tt(nn);else{let En=Pr(ft,en,Rn,T.w,T.h);Se(ce("div",{},T.i)),Tt(nn);let ns=zt.current.filter(rs=>rs.i!==T.i);B([...ns,{...T,x:En.x,y:En.y,static:!1,isDraggable:!0}])}},[At,Jt,F,k,et,A,ot,R,xt,Ot,Y,n,M]),wt=U(h=>{h.preventDefault(),h.stopPropagation(),qt.current--,qt.current<0&&(qt.current=0),qt.current===0&&A()},[A]),Dt=U(h=>{h.preventDefault(),h.stopPropagation(),qt.current++},[]),St=U(h=>{h.preventDefault(),h.stopPropagation();let O=zt.current,v=O.find(L=>L.i===F.i);qt.current=0,A(),rt(O,v,h.nativeEvent)},[F.i,A,rt]),Pt=U((h,O)=>{if(!h||!h.key)return null;let v=ae(X,String(h.key));if(!v)return null;let L=typeof v.isDraggable=="boolean"?v.isDraggable:!v.static&&ue,q=typeof v.isResizable=="boolean"?v.isResizable:!v.static&&fe,T=v.resizeHandles||[...pe],Z=L&&de&&v.isBounded!==!1,ft=he;return ce(yr,{containerWidth:n,cols:R,margin:xt,containerPadding:M,maxRows:Ot,rowHeight:Y,cancel:Vt,handle:Nt,onDragStart:Je,onDrag:Qt,onDragStop:Ze,onResizeStart:_,onResize:H,onResizeStop:nt,isDraggable:L,isResizable:q,isBounded:Z,useCSSTransforms:W&&N,usePercentages:!N,transformScale:ot,positionStrategy:i,dragThreshold:Kt,w:v.w,h:v.h,x:v.x,y:v.y,i:v.i,minH:v.minH,minW:v.minW,maxH:v.maxH,maxW:v.maxW,static:v.static,droppingPosition:O?Jt:void 0,resizeHandles:T,resizeHandle:ft,constraints:c,layoutItem:v,layout:X,children:h},v.i)},[X,n,R,xt,M,Ot,Y,Vt,Nt,Je,Qt,Ze,_,H,nt,ue,fe,de,W,N,ot,i,Kt,Jt,pe,he,c]),kt=()=>$?ce(yr,{w:$.w,h:$.h,x:$.x,y:$.y,i:$.i,className:`react-grid-placeholder ${_t?"placeholder-resizing":""}`,containerWidth:n,cols:R,margin:xt,containerPadding:M,maxRows:Ot,rowHeight:Y,isDraggable:!1,isResizable:!1,isBounded:!1,useCSSTransforms:W,transformScale:ot,constraints:c,layout:X,children:ce("div",{})}):null,te=Yn(jo,z),ee={height:Cn,...w};return To("div",{ref:P,className:te,style:ee,onDrop:d?St:void 0,onDragLeave:d?wt:void 0,onDragEnter:d?Dt:void 0,onDragOver:d?dt:void 0,children:[p.Children.map(e,h=>p.isValidElement(h)?Pt(h):null),d&&At&&Pt(At,!0),kt()]})}ct();var Lt=(...t)=>t.filter(Boolean).join(" ");var Ti=({type:t="info",title:e,message:n,onDismiss:r,className:o})=>p.createElement("div",{className:Lt("ks-alert",`ks-alert-${t}`,o),role:"alert"},p.createElement("div",{className:"ks-alert-body"},p.createElement("div",{className:"ks-alert-content"},e&&p.createElement("p",{className:"ks-alert-title"},e),p.createElement("p",{className:e?"ks-alert-message-titled":"ks-alert-message"},n)),r&&p.createElement("button",{type:"button",className:"ks-alert-dismiss","aria-label":"Dismiss",onClick:r},"\xD7"))),Ao=Ti;ct();var ji={primary:"ks-button-primary",secondary:"ks-button-secondary",danger:"ks-button-danger"},Hi={sm:"ks-button-sm",md:"ks-button-md",lg:"ks-button-lg"},Bi=({variant:t="primary",size:e="md",className:n,children:r,...o})=>{let a=o.href?"a":"button";return p.createElement(a,{...o,className:Lt("ks-button",ji[t],Hi[e],n)},r)},br=Bi;ct();var Wi=({as:t="input",disabled:e,className:n,...r})=>p.createElement(t,{...r,disabled:e,className:Lt("ks-input",e&&"ks-input-disabled",n)}),vr=Wi;ct();var Sn=(t,e)=>({className:n,children:r,...o})=>p.createElement(t,{...o,className:Lt(e,n)},r),wr=Sn("label","ks-label"),dc=Sn("p","ks-hint"),fc=Sn("p","ks-error"),pc=Sn("span","ks-required");ct();var Ai=({as:t="div",className:e,children:n,...r})=>p.createElement(t,{...r,className:Lt("ks-panel",e)},n),qo=Ai;ct();var qi=({title:t,subtitle:e,action:n,spacing:r="md",className:o,children:a})=>p.createElement("div",{className:Lt(`ks-section-${r}`,o)},t&&p.createElement("div",{className:"ks-section-header"},p.createElement("div",null,p.createElement("h2",{className:"ks-section-title"},t),e&&p.createElement("p",{className:"ks-section-subtitle"},e)),n&&p.createElement("a",{href:n.href,className:"ks-section-action"},n.label)),a),Io=qi;ct();var Ii="Your change was not saved because the server could not be reached.",Yo=({base:t,token:e,fetch:n,version:r,layout:o,onLayout:a,onError:s})=>{let i=r??o?.version,l=o,c=Promise.resolve(),f=async(u,g,z)=>{let w=await n(t+u,{method:g,headers:{"Content-Type":"application/json","X-CSRF-Token":e},body:z&&JSON.stringify({...z,version:i})}).catch(()=>null);if(!w)return s(Ii),l&&a({...l});let P=await w.json().catch(()=>({}));s(w.ok?null:P.error);let S=await(await n(t+"/layout",{headers:{Accept:"application/json"}})).json();i=S.version,l=S,a(S)};return(u,g,z)=>c=c.then(()=>f(u,g,z))};var Yi=(t,e,n)=>{let[r,o]=st(n),[a,s]=st(null),i=Ct(()=>Yo({base:t,token:e,fetch:(...l)=>window.fetch(...l),layout:n,onLayout:o,onError:s}),[t,e]);return{layout:r,error:a,send:i}},Xo=Yi;var $o=(t,e)=>t("/blocks","POST",{type:e}),Go=(t,e,{x:n,y:r})=>t("/blocks","POST",{type:e,x:n,y:r}),Sr=(t,e)=>t("/blocks","PATCH",{layout:e.map(({i:n,x:r,y:o,w:a,h:s})=>({id:n,x:r,y:o,w:a,h:s}))}),Fo=(t,e,n)=>t(`/blocks/${e}`,"PATCH",{content:n}),Uo=(t,e)=>t(`/blocks/${e}`,"DELETE"),Vo=(t,e)=>t.map(({id:n,x:r,y:o,w:a,h:s,type:i})=>{let l=e.find(u=>u.key===i)??{},c={minW:l.min_width,maxW:l.max_width,minH:l.min_height,maxH:l.max_height},f=Object.fromEntries(Object.entries(c).filter(([,u])=>u!=null));return{i:n,x:r,y:o,w:a,h:s,...f,...l.resizable===!1&&{isResizable:!1},...l.fixed&&{isDraggable:!1}}});var Xi={columns:12,row_height:60,gap:10},$i=["e","s","se"],xn=(t,e)=>t.find(n=>n.key===e),Gi=(t,e)=>xn(t,e)?.name??`Unknown block type (${e})`,Fi=(t,e)=>t.filter(n=>n.name.toLowerCase().includes(e.trim().toLowerCase())),Ui=t=>t.reduce((e,n)=>{let r=n.group??"";return(e.find(a=>a.name===r)??e[e.push({name:r,types:[]})-1]).types.push(n),e},[]),Vi=(t,e)=>{let n=document.createElement("div");return n.dataset.blockContent=t,n.innerHTML=e,n},Ki=({id:t,name:e,html:n})=>{let r=I(null),[o,a]=st(!1);return It(()=>{let s=document.querySelector(`[data-block-content="${t}"]`)??(n?Vi(t,n):null);s&&s.parentElement!==r.current&&r.current.appendChild(s),a(!!s)},[t,n]),p.createElement(p.Fragment,null,o?null:e,p.createElement("div",{ref:r,className:"grow"}))},Ko=(t,e)=>t.once&&e.some(n=>n.type===t.key);function xr({base:t,token:e,emptyMessage:n,...r}){let{layout:o,error:a,send:s}=Xo(t,e,r),{block_types:i=[],blocks:l=[],grid:c={},contents:f={}}=o,{columns:u,row_height:g,gap:z}={...Xi,...c},{width:w,containerRef:P,mounted:S}=qn({measureBeforeMount:!0}),b=Vo(l,i),K=I(null),[J,at]=st(""),[ut,it]=st(null),rt=l.find(C=>C.id===ut),et=xn(i,rt?.type)?.fields??[],lt=C=>R=>{K.current=C,R.dataTransfer.setData("text/plain",C.key)},Rt={enabled:!0,onDragOver:()=>K.current?{w:K.current.width,h:K.current.height}:!1},Wt=(C,R)=>{K.current&&Go(s,K.current.key,R),K.current=null};return p.createElement("div",{className:"lg:grid lg:grid-cols-[16rem_minmax(0,1fr)] lg:gap-6"},p.createElement(Io,{title:"Blocks",spacing:"sm"},p.createElement(wr,{htmlFor:"ks-blocks-search"},"Search blocks"),p.createElement(vr,{id:"ks-blocks-search",type:"search",value:J,onChange:C=>at(C.target.value),className:"mb-2"}),i.length===0?p.createElement("p",null,"There are no blocks to add."):Ui(Fi(i,J)).map(C=>p.createElement(p.Fragment,{key:C.name},C.name&&p.createElement("h3",{className:"ks-section-title"},C.name),p.createElement("ul",null,C.types.map(R=>p.createElement("li",{key:R.key,"data-block-type":R.key,className:"flex items-center justify-between gap-2 py-1",draggable:"true",onDragStart:lt(R)},p.createElement("span",null,R.name,R.description&&p.createElement("span",{className:"ks-section-subtitle block"},R.description)),p.createElement(br,{variant:"secondary",size:"sm",type:"button",disabled:Ko(R,l),onClick:()=>$o(s,R.key)},Ko(R,l)?"Added":"Add"))))))),p.createElement(qo,{"data-block-grid-panel":!0},a&&p.createElement(Ao,{type:"error",message:a,className:"mb-3"}),l.length===0&&p.createElement("p",null,n),et.length>0&&p.createElement("div",{"data-block-fields":!0,className:"mb-3"},et.map(C=>p.createElement("div",{key:C.key,className:"mb-2"},p.createElement(wr,{htmlFor:`ks-block-field-${C.key}`},C.label),p.createElement(vr,{key:`${ut}-${C.key}`,id:`ks-block-field-${C.key}`,type:"text",defaultValue:rt.content?.[C.key]??"",onBlur:R=>Fo(s,ut,{...rt.content,[C.key]:R.target.value})})))),p.createElement("div",{ref:P,"data-block-grid":!0,style:{overflow:"hidden",visibility:S?"visible":"hidden"}},p.createElement(Fe,{width:w,layout:b,gridConfig:{cols:u,rowHeight:g,margin:[z,z]},resizeConfig:{enabled:!0,handles:$i},dragConfig:{handle:"[data-block-handle]",cancel:"[data-remove-block]"},dropConfig:Rt,onDrop:Wt,onDragStop:C=>Sr(s,C),onResizeStop:C=>Sr(s,C)},l.map(C=>p.createElement("div",{key:C.id,"data-block":C.id,onClick:()=>it(C.id),className:"ks-panel p-3 flex items-start justify-between gap-2"},!xn(i,C.type)?.fixed&&p.createElement("span",{"data-block-handle":!0,className:"ks-block-handle","aria-hidden":"true"},"\u283F"),p.createElement(Ki,{id:C.id,name:Gi(i,C.type),html:f[C.id]}),!xn(i,C.type)?.fixed&&p.createElement(br,{variant:"secondary",size:"sm",type:"button","data-remove-block":!0,onClick:()=>Uo(s,C.id)},"Remove")))))))}ct();var Jo=new Map,Dn=new Map,Zo=(t,e)=>Jo.set(t,e),Qo=()=>{Dn.forEach(t=>t.unmount()),Dn.clear()},ts=(t,e)=>t.querySelectorAll("[data-react-ui]").forEach(n=>{if(Dn.has(n))return;let r=Jo.get(n.dataset.reactUi),o=e(n);Dn.set(n,o),o.render(p.createElement(r,JSON.parse(n.dataset.props)))});var es=(t,e)=>{let n=()=>ts(t,e);t.addEventListener("turbo:load",n),t.addEventListener("turbo:frame-load",n),t.addEventListener("turbo:before-cache",Qo),t.readyState==="loading"?t.addEventListener("DOMContentLoaded",n):n()};Zo("dash_kit/dashboard-grid",xr);es(document,zn);})();
@@ -0,0 +1,2 @@
1
+ export function registerControllers(_application) {
2
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,6 @@
1
+ module DashKit
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :null_session
4
+ helper KeystoneUi::Engine.helpers
5
+ end
6
+ end
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DashKit
4
+ class DashboardsController < DashKit.parent_controller.constantize
5
+ before_action :require_editable!, only: %i[toggle_widget move_widget reorder save_filters create_definition update_definition destroy_definition]
6
+
7
+ def index
8
+ @dashboards = dashboard_scope.all
9
+ end
10
+
11
+ def new
12
+ @dashboard = dashboard_scope.new
13
+ end
14
+
15
+ def create
16
+ @dashboard = dashboard_scope.new(dashboard_params)
17
+
18
+ if @dashboard.save
19
+ redirect_to dashboards_path, notice: "Dashboard created."
20
+ else
21
+ render :new, status: :unprocessable_entity
22
+ end
23
+ end
24
+
25
+ def select
26
+ dashboard_scope.find(params[:id]).activate!
27
+ redirect_to dashboards_path
28
+ end
29
+
30
+ def duplicate
31
+ dashboard_scope.find(params[:id]).duplicate!
32
+ redirect_to dashboards_path
33
+ end
34
+
35
+ def edit
36
+ @dashboard = dashboard_scope.find(params[:id])
37
+ end
38
+
39
+ def destroy
40
+ dashboard_scope.find(params[:id]).destroy
41
+ redirect_to dashboards_path
42
+ end
43
+
44
+ def update
45
+ @dashboard = dashboard_scope.find(params[:id])
46
+
47
+ if @dashboard.update(dashboard_params)
48
+ redirect_to dashboards_path, notice: "Dashboard updated."
49
+ else
50
+ render :edit, status: :unprocessable_entity
51
+ end
52
+ end
53
+
54
+ def place_blocks
55
+ widget_dashboard.place_blocks(params.require(:layout).map { |position| position.permit(:id, :x, :y, :w, :h).to_h }, version: params[:version])
56
+ head :no_content
57
+ rescue KsBlocks::InvalidLayout => refusal
58
+ render json: { error: refusal.message }, status: :unprocessable_entity
59
+ end
60
+
61
+ def save_filters
62
+ widget_dashboard.update_filter(params[:filter_key], params[:filter_value])
63
+ respond_to do |format|
64
+ format.turbo_stream { render_widgets }
65
+ format.html { redirect_back fallback_location: main_app.root_path }
66
+ end
67
+ end
68
+
69
+ def create_definition
70
+ definition = widget_dashboard.widget_definitions.create(definition_params)
71
+ widget_dashboard.add_built_widget(definition) if definition.persisted?
72
+ respond_to do |format|
73
+ format.turbo_stream { render_widgets }
74
+ format.html { redirect_back fallback_location: main_app.root_path }
75
+ end
76
+ end
77
+
78
+ def update_definition
79
+ widget_dashboard.widget_definitions.find(params[:definition_id]).update(definition_params)
80
+ respond_to do |format|
81
+ format.turbo_stream { render_widgets }
82
+ format.html { redirect_back fallback_location: main_app.root_path }
83
+ end
84
+ end
85
+
86
+ def destroy_definition
87
+ widget_dashboard.widget_definitions.find(params[:definition_id]).destroy
88
+ respond_to do |format|
89
+ format.turbo_stream { render_widgets }
90
+ format.html { redirect_back fallback_location: main_app.root_path }
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def definition_params
97
+ params.require(:widget_definition).permit(:source, :visualization, options: {})
98
+ end
99
+
100
+ def widget_dashboard
101
+ @widget_dashboard ||= dashboard_scope.find(params[:id])
102
+ end
103
+
104
+ def render_widgets
105
+ render turbo_stream: turbo_stream.replace(
106
+ helpers.dash_kit_widgets_id(widget_dashboard),
107
+ partial: "dash_kit/dashboards/widgets",
108
+ locals: { config: widget_dashboard }
109
+ )
110
+ end
111
+
112
+ def dashboard_params
113
+ params.require(:dashboard).permit(:name, :dashboard_type)
114
+ end
115
+
116
+ def dashboard_scope
117
+ if DashKit.current_owner_method
118
+ DashKit::Dashboard.for_owner(send(DashKit.current_owner_method))
119
+ else
120
+ DashKit::Dashboard
121
+ end
122
+ end
123
+
124
+ def require_editable!
125
+ viewer = current_viewer
126
+ return if viewer.nil?
127
+
128
+ head :forbidden unless DashKit.editable?(widget_dashboard, viewer)
129
+ end
130
+
131
+ def current_viewer
132
+ if DashKit.current_viewer_method
133
+ send(DashKit.current_viewer_method)
134
+ elsif DashKit.current_owner_method
135
+ send(DashKit.current_owner_method)
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DashKit
4
+ class WidgetDefinitionsController < DashKit.parent_controller.constantize
5
+ def show
6
+ definition = definition_scope.find_by(id: params[:id])
7
+ return head :not_found if definition.nil?
8
+
9
+ renderer = DashKit.renderer_for(definition.visualization)
10
+ return render partial: "dash_kit/widget_definitions/missing_renderer", layout: false if renderer.nil?
11
+
12
+ render partial: renderer, layout: false, locals: {
13
+ source: definition.source,
14
+ options: definition.options,
15
+ filter_state: definition.dashboard.filter_state
16
+ }
17
+ end
18
+
19
+ private
20
+
21
+ def definition_scope
22
+ DashKit::WidgetDefinition.where(dashboard: dashboard_scope)
23
+ end
24
+
25
+ def dashboard_scope
26
+ if DashKit.current_owner_method
27
+ DashKit::Dashboard.for_owner(send(DashKit.current_owner_method))
28
+ else
29
+ DashKit::Dashboard.all
30
+ end
31
+ end
32
+ end
33
+ end