diff --git a/repository/BaselineOfSeaside3.package/BaselineOfSeaside3.class/instance/baselinecommon..st b/repository/BaselineOfSeaside3.package/BaselineOfSeaside3.class/instance/baselinecommon..st
index 713eda5d5..53ca8ec65 100644
--- a/repository/BaselineOfSeaside3.package/BaselineOfSeaside3.class/instance/baselinecommon..st
+++ b/repository/BaselineOfSeaside3.package/BaselineOfSeaside3.class/instance/baselinecommon..st
@@ -60,9 +60,13 @@ baselinecommon: spec
package: 'Seaside-Tools-Core' with: [
spec requires: #('Seaside-Core' 'Seaside-Component' 'Seaside-RenderLoop' 'Seaside-Session' ). ];
package: 'Seaside-Tools-Web' with: [
- spec requires: #('Seaside-Tools-Core' 'Seaside-RenderLoop' 'Seaside-Widgets' ). ];
+ spec requires: #('Seaside-Tools-Core' 'Seaside-RenderLoop' 'Seaside-Widgets' ) ];
package: 'Seaside-Widgets' with: [
- spec requires: #('Seaside-Component' 'Seaside-Canvas' ). ];
+ spec requires: #('Seaside-Component' 'Seaside-Canvas' ) ];
+ package: 'Seaside-HotwireTurbo' with: [
+ spec requires: #('Seaside-Core' 'Seaside-Component' 'Seaside-Canvas') ];
+ package: 'Seaside-HotwireTurbo-Examples' with: [
+ spec requires: #('Seaside-HotwireTurbo') ];
package: 'Seaside-Tests-Canvas' with: [
spec requires: #('Seaside-Tests-Core' 'Seaside-Canvas' ). ];
package: 'Seaside-Tests-Component' with: [
@@ -96,11 +100,12 @@ baselinecommon: spec
spec
group: 'default' with: #('Core' 'JSON' 'Email' 'Javascript' 'JQuery' 'JQueryUI' 'Seaside-Examples' 'Seaside-Welcome');
group: 'OneClick' with: #('Tests' 'Development' 'Zinc');
- group: 'CI' with: #('Tests' 'Development Tests');
+ group: 'CI' with: #('Tests' 'Development Tests' 'Seaside-HotwireTurbo');
group: 'Core' with: #('Seaside-Core' 'Seaside-Continuation' 'Seaside-Canvas' 'Seaside-Session' 'Seaside-Component' 'Seaside-RenderLoop' 'Seaside-Tools-Core' 'Seaside-Flow' 'Seaside-Environment' 'Seaside-Widgets' );
group: 'Tests' with: #('Core' 'Seaside-Tests-Core' 'Seaside-Tests-Canvas' 'Seaside-Tests-Session' 'Seaside-Tests-Component' 'Seaside-Tests-RenderLoop' 'Seaside-Tests-Environment' 'Seaside-Tests-Flow' 'Seaside-Tests-UTF8' 'Seaside-Tests-InternetExplorer' 'Seaside-Tests-Email' 'Seaside-Tests-Examples' 'RSS Tests' 'Welcome Tests' 'REST Tests' 'Swagger Tests' 'Seaside-Tests-Parasol');
- group: 'Development' with: #('Core' 'Seaside-Development' );
- group: 'Development Tests' with: #('Development' 'Core' 'Seaside-Tests-Development' );
+ group: 'Hotwired' with: #('Seaside-HotwireTurbo');
+ group: 'Development' with: #('Core' 'Seaside-Development');
+ group: 'Development Tests' with: #('Development' 'Core' 'Seaside-Tests-Development');
group: 'Email' with: #('Seaside-Email');
- group: 'Examples' with: #('Core' 'Seaside-Examples' 'Seaside-REST-Examples');
+ group: 'Examples' with: #('Core' 'Seaside-Examples' 'Seaside-REST-Examples' 'Seaside-HotwireTurbo-Examples');
group: 'Base' with: #('Core') ].
\ No newline at end of file
diff --git a/repository/BaselineOfSeaside3.package/BaselineOfSeaside3.class/instance/baselinejquery..st b/repository/BaselineOfSeaside3.package/BaselineOfSeaside3.class/instance/baselinejquery..st
index ddc8c3b40..f18fcc544 100644
--- a/repository/BaselineOfSeaside3.package/BaselineOfSeaside3.class/instance/baselinejquery..st
+++ b/repository/BaselineOfSeaside3.package/BaselineOfSeaside3.class/instance/baselinejquery..st
@@ -8,6 +8,8 @@ baselinejquery: spec
spec requires: #('Javascript-Core' ) ];
package: 'JQuery-Tests-Core' with: [
spec requires: #('JQuery-Core' 'Javascript-Tests-Core' 'Seaside-Development' 'Seaside-Tests-Functional' 'Seaside-Ajaxifier-Core') ];
+ package: 'JQuery-Examples' with: [
+ spec requires: #('JQuery-Core') ];
package: 'JQuery-JSON' with: [
spec requires: #('JQuery-Core' 'Seaside-JSON-Core') ];
package: 'JQuery-Tests-JSON' with: [
@@ -16,4 +18,5 @@ baselinejquery: spec
spec
group: 'JQuery' with: #('JQuery-Core' 'JQuery-JSON');
group: 'JQuery Tests' with: #('JQuery-Tests-Core' 'JQuery-Tests-JSON');
+ group: 'Examples' with: #('JQuery-Examples');
group: 'Tests' with: #( 'JQuery Tests' ) ]
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/.filetree b/repository/JQuery-Examples.package/.filetree
new file mode 100644
index 000000000..57a679737
--- /dev/null
+++ b/repository/JQuery-Examples.package/.filetree
@@ -0,0 +1,5 @@
+{
+ "separateMethodMetaAndSource" : false,
+ "noMethodMetaData" : true,
+ "useCypressPropertiesFile" : true
+}
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WAJQueryExampleComponent.class/README.md b/repository/JQuery-Examples.package/WATodoWithJQuery.class/README.md
similarity index 100%
rename from repository/Seaside-Examples.package/WAJQueryExampleComponent.class/README.md
rename to repository/JQuery-Examples.package/WATodoWithJQuery.class/README.md
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/class/initialize.st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/class/initialize.st
new file mode 100644
index 000000000..0df2c807c
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/class/initialize.st
@@ -0,0 +1,5 @@
+initialization
+initialize
+ (WAAdmin register: self asApplicationAt: '/examples/todo-jquery')
+ exceptionHandler: WADebugErrorHandler;
+ addLibrary: WAExamplesLibrary
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/addTodo..st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/addTodo..st
new file mode 100644
index 000000000..f5b5b0641
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/addTodo..st
@@ -0,0 +1,6 @@
+actions
+addTodo: aString
+ | newTodo |
+ newTodo := WATodoWithJQueryItem newWithDescription: aString in: todos.
+ todos add: newTodo.
+ ^ newTodo
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/children.st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/children.st
new file mode 100644
index 000000000..23e0247f0
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/children.st
@@ -0,0 +1,3 @@
+accessing
+children
+ ^ self todos
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/initialize.st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/initialize.st
new file mode 100644
index 000000000..8641fa518
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/initialize.st
@@ -0,0 +1,6 @@
+initialization
+initialize
+ super initialize.
+ todos := OrderedCollection new.
+ 1 to: 5000 do: [ :index |
+ self addTodo: 'Task ', index greaseString ]
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/renderAddNewTodoOn..st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/renderAddNewTodoOn..st
new file mode 100644
index 000000000..94ceeabfe
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/renderAddNewTodoOn..st
@@ -0,0 +1,19 @@
+rendering
+renderAddNewTodoOn: html
+ | newTodo |
+ html header
+ id: #header;
+ with: [
+ html heading
+ level: 1;
+ with: 'todos'.
+ html textInput
+ id: #'new-todo';
+ autofocus;
+ attributeAt: 'autocomplete' put: 'off';
+ callback: [ :value | newTodo := self addTodo: value ];
+ onChange: (html jQuery ajax
+ serializeThis;
+ script: [ :s | s << ((s jQuery id: 'todo-list') append: newTodo) ];
+ onComplete: ((html jQuery id: #'new-todo') value: ''));
+ placeholder: 'What needs to be done?' ]
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/renderContentOn..st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/renderContentOn..st
new file mode 100644
index 000000000..5e6cdb13f
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/renderContentOn..st
@@ -0,0 +1,7 @@
+rendering
+renderContentOn: html
+ html section
+ id: #todoapp;
+ with: [
+ self renderAddNewTodoOn: html.
+ self renderTodosOn: html ]
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/renderTodosOn..st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/renderTodosOn..st
new file mode 100644
index 000000000..6d82c7805
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/renderTodosOn..st
@@ -0,0 +1,19 @@
+rendering
+renderTodosOn: html
+
+ html section
+ id: 'main';
+ with: [
+ html checkbox
+ id: 'toggle-all'.
+ html label
+ for: 'toggle-all';
+ with: 'Mark all as complete'.
+ html unorderedList
+ id: 'todo-list';
+ script: (self scriptToTriggerCheckboxToggleOn: html);
+ script: (self scriptToTriggerRenameOn: html);
+ script: (self scriptToTriggerEditOn: html);
+ script: (self scriptToSerializeEditOn: html);
+ with: [
+ self todos do: [ :todoItem | todoItem renderOn: html ] ] ]
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToSerializeEditOn..st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToSerializeEditOn..st
new file mode 100644
index 000000000..f534d486f
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToSerializeEditOn..st
@@ -0,0 +1,17 @@
+rendering
+scriptToSerializeEditOn: html
+
+ | currentItem itemId |
+ ^ html jQuery this
+ on: 'change'
+ selector:'.edit'
+ do: ((
+ html jQuery ajax
+ serialize: (html jQuery expression: (JSStream on:'event.target'));
+ callback: [ :passengers | currentItem := passengers first ]
+ passengers: ((html jQuery expression: (JSStream on:'event.target')) closest:'li');
+ callback: [ :id | itemId := id ]
+ value: (JSStream on:'$(event.target).closest("li").get(0).id');
+ script: [ :s | s << (((s jQuery id: itemId) find: 'label') html: currentItem description) ];
+ onComplete: ((((html jQuery expression: (JSStream on: 'event.target')) closest:'li') find: '.edit') hide, (((html jQuery expression: (JSStream on: 'event.target')) closest:'li') find: 'label') show))
+ asFunction: #(event))
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToTriggerCheckboxToggleOn..st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToTriggerCheckboxToggleOn..st
new file mode 100644
index 000000000..1e354673e
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToTriggerCheckboxToggleOn..st
@@ -0,0 +1,7 @@
+rendering
+scriptToTriggerCheckboxToggleOn: html
+
+ ^ html jQuery this
+ on: 'click'
+ selector: '.toggle'
+ do: ((html jQuery ajax serializeWithHidden: (html jQuery expression: (JSStream on: 'event.target'))) asFunction: #(event))
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToTriggerEditOn..st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToTriggerEditOn..st
new file mode 100644
index 000000000..2da62afb6
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToTriggerEditOn..st
@@ -0,0 +1,7 @@
+rendering
+scriptToTriggerEditOn: html
+
+ ^ html jQuery this
+ on: 'click'
+ selector: '.view>label'
+ do: (((((html jQuery expression: (JSStream on: 'event.target')) hide closest:'li') find: '.edit') show) asFunction:#(event))
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToTriggerRenameOn..st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToTriggerRenameOn..st
new file mode 100644
index 000000000..987069d13
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/scriptToTriggerRenameOn..st
@@ -0,0 +1,10 @@
+rendering
+scriptToTriggerRenameOn: html
+
+ ^ html jQuery this
+ on: 'click'
+ selector: '.destroy'
+ do: ((html jQuery ajax
+ callback: [ :passengers | passengers first remove ]
+ passengers: (((html jQuery expression: (JSStream on:'event.target')) closest: 'li'));
+ onComplete: (((html jQuery expression: (JSStream on:'event.target')) closest: 'li') remove)) asFunction: #(event))
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/todos.st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/todos.st
new file mode 100644
index 000000000..26eccb224
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/todos.st
@@ -0,0 +1,3 @@
+accessing
+todos
+ ^ todos
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/updateRoot..st b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/updateRoot..st
new file mode 100644
index 000000000..d2af8944f
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/instance/updateRoot..st
@@ -0,0 +1,7 @@
+rendering
+updateRoot: aRoot
+
+ super updateRoot: aRoot.
+ aRoot title: 'Seaside-JQuery Todo Demo'.
+ aRoot stylesheet url: WAExamplesLibrary / #todoCss.
+ aRoot javascript url: JQDeploymentLibrary / #jQueryJs
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQuery.class/properties.json b/repository/JQuery-Examples.package/WATodoWithJQuery.class/properties.json
new file mode 100644
index 000000000..d63168884
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQuery.class/properties.json
@@ -0,0 +1,13 @@
+{
+ "commentStamp" : "",
+ "super" : "WAExampleComponent",
+ "category" : "JQuery-Examples",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [
+ "todos"
+ ],
+ "name" : "WATodoWithJQuery",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/README.md b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/class/newWithDescription.in..st b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/class/newWithDescription.in..st
new file mode 100644
index 000000000..544869ab4
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/class/newWithDescription.in..st
@@ -0,0 +1,3 @@
+instance creation
+newWithDescription: aString in: aCollection
+ ^ self new initializeWithDescription: aString in: aCollection
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/description..st b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/description..st
new file mode 100644
index 000000000..24c97bebc
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/description..st
@@ -0,0 +1,3 @@
+accessing
+description: anObject
+ description := anObject
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/description.st b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/description.st
new file mode 100644
index 000000000..c5ddedef1
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/description.st
@@ -0,0 +1,3 @@
+accessing
+description
+ ^ description
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/done..st b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/done..st
new file mode 100644
index 000000000..d0c44d461
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/done..st
@@ -0,0 +1,3 @@
+accessing
+done: anObject
+ done := anObject
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/done.st b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/done.st
new file mode 100644
index 000000000..a14b18f11
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/done.st
@@ -0,0 +1,3 @@
+accessing
+done
+ ^ done
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/initializeWithDescription.in..st b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/initializeWithDescription.in..st
new file mode 100644
index 000000000..0000b0c6e
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/initializeWithDescription.in..st
@@ -0,0 +1,6 @@
+initialization
+initializeWithDescription: aString in: aCollection
+ self initialize.
+ self done: false.
+ self description: aString.
+ todos := aCollection
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/remove.st b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/remove.st
new file mode 100644
index 000000000..468ca6ad5
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/remove.st
@@ -0,0 +1,3 @@
+private
+remove
+ todos remove: self
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/renderContentOn..st b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/renderContentOn..st
new file mode 100644
index 000000000..7c21fe50b
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/instance/renderContentOn..st
@@ -0,0 +1,20 @@
+rendering
+renderContentOn: html
+ html listItem
+ passenger: self;
+ with: [
+ html div
+ class: 'view';
+ with:[
+ html checkbox
+ class: 'toggle';
+ callback: [ :value | self done: value ];
+ value: done.
+ html label: description.
+ html button
+ class: 'destroy' ].
+ html textInput
+ class: 'edit';
+ style: 'display:none';
+ callback: [ :value | self description: value ];
+ value: description ]
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/properties.json b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/properties.json
new file mode 100644
index 000000000..6b9108f35
--- /dev/null
+++ b/repository/JQuery-Examples.package/WATodoWithJQueryItem.class/properties.json
@@ -0,0 +1,15 @@
+{
+ "commentStamp" : "",
+ "super" : "WAComponent",
+ "category" : "JQuery-Examples",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [
+ "todos",
+ "description",
+ "done"
+ ],
+ "name" : "WATodoWithJQueryItem",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/monticello.meta/categories.st b/repository/JQuery-Examples.package/monticello.meta/categories.st
new file mode 100644
index 000000000..eec46cbc0
--- /dev/null
+++ b/repository/JQuery-Examples.package/monticello.meta/categories.st
@@ -0,0 +1 @@
+SystemOrganization addCategory: #'JQuery-Examples'!
diff --git a/repository/JQuery-Examples.package/monticello.meta/initializers.st b/repository/JQuery-Examples.package/monticello.meta/initializers.st
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/JQuery-Examples.package/monticello.meta/package b/repository/JQuery-Examples.package/monticello.meta/package
new file mode 100644
index 000000000..14340f2f2
--- /dev/null
+++ b/repository/JQuery-Examples.package/monticello.meta/package
@@ -0,0 +1 @@
+(name 'JQuery-Examples')
\ No newline at end of file
diff --git a/repository/JQuery-Examples.package/properties.json b/repository/JQuery-Examples.package/properties.json
new file mode 100644
index 000000000..6f31cf5a2
--- /dev/null
+++ b/repository/JQuery-Examples.package/properties.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/repository/Javascript-Core.package/WARenderer.extension/instance/javascript..st b/repository/Javascript-Core.package/WARenderer.extension/instance/javascript..st
new file mode 100644
index 000000000..911063f1d
--- /dev/null
+++ b/repository/Javascript-Core.package/WARenderer.extension/instance/javascript..st
@@ -0,0 +1,4 @@
+*javascript-core
+javascript: aString
+
+ ^ JSStream on: aString
\ No newline at end of file
diff --git a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/defer.st b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/defer.st
index 7492cdff6..c5602f1bd 100644
--- a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/defer.st
+++ b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/defer.st
@@ -1,4 +1,5 @@
attributes
defer
"When set, this boolean attribute provides a hint to the user agent that the script is not going to generate any document content (e.g., no 'document.write' in javascript) and thus, the user agent can continue parsing and rendering."
+
self attributes at: 'defer' put: true
\ No newline at end of file
diff --git a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/resourceUrl..st b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/resourceUrl..st
index af4506b47..319567401 100644
--- a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/resourceUrl..st
+++ b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/resourceUrl..st
@@ -1,3 +1,4 @@
attributes
resourceUrl: aString
+
self url: (canvas absoluteUrlForResource: aString)
\ No newline at end of file
diff --git a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/tag.st b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/tag.st
index 2573da80b..2c650c5cd 100644
--- a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/tag.st
+++ b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/tag.st
@@ -1,3 +1,4 @@
accessing
tag
+
^ 'script'
\ No newline at end of file
diff --git a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/type..st b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/type..st
new file mode 100644
index 000000000..125f72993
--- /dev/null
+++ b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/type..st
@@ -0,0 +1,4 @@
+attributes
+type: aString
+
+ self attributeAt: 'type' put: aString
\ No newline at end of file
diff --git a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/url..st b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/url..st
index 638aa3fe5..91851377d 100644
--- a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/url..st
+++ b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/url..st
@@ -1,3 +1,4 @@
attributes
url: aString
+
self attributes at: 'src' put: aString
\ No newline at end of file
diff --git a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/with..st b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/with..st
index 7528cbc09..9c99f9652 100644
--- a/repository/Seaside-Canvas.package/WAScriptTag.class/instance/with..st
+++ b/repository/Seaside-Canvas.package/WAScriptTag.class/instance/with..st
@@ -1,8 +1,9 @@
public
-with: aString
- self attributes
+with: aString
+
+ self attributes
at: 'type'
ifAbsentPut: [ 'text/javascript' ].
super with: [
- aString isNil ifFalse: [
+ aString ifNotNil: [
self document nextPutAll: aString greaseString ] ]
\ No newline at end of file
diff --git a/repository/Seaside-Canvas.package/WATagBrush.class/instance/dataAttributeAt.put..st b/repository/Seaside-Canvas.package/WATagBrush.class/instance/dataAttributeAt.put..st
new file mode 100644
index 000000000..9fc7777b1
--- /dev/null
+++ b/repository/Seaside-Canvas.package/WATagBrush.class/instance/dataAttributeAt.put..st
@@ -0,0 +1,4 @@
+attributes
+dataAttributeAt: aString put: aValue
+
+ self attributeAt: 'data-',aString put: aValue
\ No newline at end of file
diff --git a/repository/Seaside-Canvas.package/WATagBrush.class/instance/dataAttributeAt.put.if..st b/repository/Seaside-Canvas.package/WATagBrush.class/instance/dataAttributeAt.put.if..st
new file mode 100644
index 000000000..032548613
--- /dev/null
+++ b/repository/Seaside-Canvas.package/WATagBrush.class/instance/dataAttributeAt.put.if..st
@@ -0,0 +1,4 @@
+attributes
+dataAttributeAt: aString put: aValue if: aBoolean
+
+ aBoolean ifTrue:[ self dataAttributeAt: aString put: aValue ]
\ No newline at end of file
diff --git a/repository/Seaside-Component.package/WAPluggablePresenter.class/README.md b/repository/Seaside-Component.package/WAPluggablePresenter.class/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-Component.package/WAPluggablePresenter.class/instance/block..st b/repository/Seaside-Component.package/WAPluggablePresenter.class/instance/block..st
new file mode 100644
index 000000000..9f1997723
--- /dev/null
+++ b/repository/Seaside-Component.package/WAPluggablePresenter.class/instance/block..st
@@ -0,0 +1,3 @@
+accessing
+block: aBlock
+ block := aBlock
\ No newline at end of file
diff --git a/repository/Seaside-Component.package/WAPluggablePresenter.class/instance/renderContentOn..st b/repository/Seaside-Component.package/WAPluggablePresenter.class/instance/renderContentOn..st
new file mode 100644
index 000000000..bc744a06c
--- /dev/null
+++ b/repository/Seaside-Component.package/WAPluggablePresenter.class/instance/renderContentOn..st
@@ -0,0 +1,3 @@
+rendering
+renderContentOn: html
+ block value: html
\ No newline at end of file
diff --git a/repository/Seaside-Component.package/WAPluggablePresenter.class/properties.json b/repository/Seaside-Component.package/WAPluggablePresenter.class/properties.json
new file mode 100644
index 000000000..1347fe04d
--- /dev/null
+++ b/repository/Seaside-Component.package/WAPluggablePresenter.class/properties.json
@@ -0,0 +1,13 @@
+{
+ "commentStamp" : "",
+ "super" : "WAComponent",
+ "category" : "Seaside-Component-Base",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [
+ "block"
+ ],
+ "name" : "WAPluggablePresenter",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-Core.package/WACallbackRegistry.class/instance/handle..st b/repository/Seaside-Core.package/WACallbackRegistry.class/instance/handle..st
index d0c4e7045..94b8ac10b 100644
--- a/repository/Seaside-Core.package/WACallbackRegistry.class/instance/handle..st
+++ b/repository/Seaside-Core.package/WACallbackRegistry.class/instance/handle..st
@@ -7,6 +7,7 @@ handle: aRequestContext
callbacks at: key ifPresent: [ :callback |
(callback isEnabledFor: aRequestContext)
ifTrue: [ set add: callback ] ] ].
+ "Process the callbacks in order of priority"
set sorted do: [ :callback |
callback evaluateWithFieldValues:
(fields allAt: callback key) ]
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WAExamplesLibrary.class/instance/todoCss.st b/repository/Seaside-Examples.package/WAExamplesLibrary.class/instance/todoCss.st
index 7b29da03a..df7d10730 100644
--- a/repository/Seaside-Examples.package/WAExamplesLibrary.class/instance/todoCss.st
+++ b/repository/Seaside-Examples.package/WAExamplesLibrary.class/instance/todoCss.st
@@ -293,6 +293,31 @@ label[for=''toggle-all''] {
display: block;
}
+#todo-list li .edit-link {
+ position: absolute;
+ top: 20px;
+ right: 60px;
+ bottom: 0;
+ margin: auto 0;
+ font-size: small;
+ color: #a88a8a;
+ display: none;
+}
+
+#todo-list li:hover .edit-link {
+ display: block;
+}
+
+#todo-list li .edit-link:hover {
+ text-shadow: 0 0 1px #000,
+ 0 0 10px rgba(199, 107, 107, 0.8);
+ -webkit-transform: scale(1.3);
+ -moz-transform: scale(1.3);
+ -ms-transform: scale(1.3);
+ -o-transform: scale(1.3);
+ transform: scale(1.3);
+}
+
#todo-list li .edit {
display: none;
}
diff --git a/repository/Seaside-Examples.package/WATodo.class/README.md b/repository/Seaside-Examples.package/WATodo.class/README.md
index e69de29bb..ffed987e8 100644
--- a/repository/Seaside-Examples.package/WATodo.class/README.md
+++ b/repository/Seaside-Examples.package/WATodo.class/README.md
@@ -0,0 +1 @@
+I am the TODO application example's root component
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodo.class/instance/addTodo..st b/repository/Seaside-Examples.package/WATodo.class/instance/addTodo..st
index 7696c31ea..0fafe3088 100644
--- a/repository/Seaside-Examples.package/WATodo.class/instance/addTodo..st
+++ b/repository/Seaside-Examples.package/WATodo.class/instance/addTodo..st
@@ -1,4 +1,4 @@
-actions
+adding
addTodo: aString
| newTodo |
newTodo := WATodoItem newWithDescription: aString in: todos.
diff --git a/repository/Seaside-Examples.package/WATodo.class/instance/children.st b/repository/Seaside-Examples.package/WATodo.class/instance/children.st
index 23e0247f0..ffd841508 100644
--- a/repository/Seaside-Examples.package/WATodo.class/instance/children.st
+++ b/repository/Seaside-Examples.package/WATodo.class/instance/children.st
@@ -1,3 +1,3 @@
-accessing
+hooks
children
^ self todos
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodo.class/instance/initialize.st b/repository/Seaside-Examples.package/WATodo.class/instance/initialize.st
index 8641fa518..4220d9262 100644
--- a/repository/Seaside-Examples.package/WATodo.class/instance/initialize.st
+++ b/repository/Seaside-Examples.package/WATodo.class/instance/initialize.st
@@ -2,5 +2,5 @@ initialization
initialize
super initialize.
todos := OrderedCollection new.
- 1 to: 5000 do: [ :index |
- self addTodo: 'Task ', index greaseString ]
\ No newline at end of file
+ 1 to: 10 do: [ :index |
+ self addTodo: ('Task {1}' format: { index greaseString }) ]
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodo.class/instance/renderAddNewTodoOn..st b/repository/Seaside-Examples.package/WATodo.class/instance/renderAddNewTodoOn..st
index 075907262..e159b8647 100644
--- a/repository/Seaside-Examples.package/WATodo.class/instance/renderAddNewTodoOn..st
+++ b/repository/Seaside-Examples.package/WATodo.class/instance/renderAddNewTodoOn..st
@@ -4,20 +4,13 @@ renderAddNewTodoOn: html
html header
id: #header;
with: [
- html heading
- level: 1;
- with: 'todos'.
- html textInput
- id: #'new-todo';
- autofocus;
- attributeAt: 'autocomplete' put: 'off';
- callback: [ :value | newTodo := self addTodo: value ];
- "onChange: (html jQuery ajax
- serializeThis;
- onComplete: ((html jQuery ajax script: [:s | s << ((s jQuery id: 'todo-list') append: newTodo)]),
- ((html jQuery id: #'new-todo') value: '')));"
- onChange: (html jQuery ajax
- serializeThis;
- script: [ :s | s << ((s jQuery id: 'todo-list') append: newTodo) ];
- onComplete: ((html jQuery id: #'new-todo') value: ''));
- placeholder: 'What needs to be done?' ]
\ No newline at end of file
+ html form: [
+ html heading
+ level: 1;
+ with: 'todos'.
+ html textInput
+ id: #'new-todo';
+ autofocus;
+ attributeAt: 'autocomplete' put: 'off';
+ callback: [ :value | newTodo := self addTodo: value ];
+ placeholder: 'What needs to be done?' ] ]
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodo.class/instance/renderContentOn..st b/repository/Seaside-Examples.package/WATodo.class/instance/renderContentOn..st
index fb378c06f..5e6cdb13f 100644
--- a/repository/Seaside-Examples.package/WATodo.class/instance/renderContentOn..st
+++ b/repository/Seaside-Examples.package/WATodo.class/instance/renderContentOn..st
@@ -4,5 +4,4 @@ renderContentOn: html
id: #todoapp;
with: [
self renderAddNewTodoOn: html.
- self renderTodosOn: html.
- self renderFooterOn: html ]
\ No newline at end of file
+ self renderTodosOn: html ]
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodo.class/instance/renderFooterOn..st b/repository/Seaside-Examples.package/WATodo.class/instance/renderFooterOn..st
deleted file mode 100644
index d950db5f3..000000000
--- a/repository/Seaside-Examples.package/WATodo.class/instance/renderFooterOn..st
+++ /dev/null
@@ -1,2 +0,0 @@
-rendering
-renderFooterOn: html
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodo.class/instance/renderTodosOn..st b/repository/Seaside-Examples.package/WATodo.class/instance/renderTodosOn..st
index 27b035439..fd6f11c5e 100644
--- a/repository/Seaside-Examples.package/WATodo.class/instance/renderTodosOn..st
+++ b/repository/Seaside-Examples.package/WATodo.class/instance/renderTodosOn..st
@@ -1,6 +1,6 @@
rendering
renderTodosOn: html
- | currentItem itemId |
+
html section
id: 'main';
with: [
@@ -11,32 +11,4 @@ renderTodosOn: html
with: 'Mark all as complete'.
html unorderedList
id: 'todo-list';
- script: (html jQuery this
- on: 'click'
- selector: '.toggle'
- do: ((html jQuery ajax serializeWithHidden: (html jQuery expression: (JSStream on: 'event.target'))) asFunction: #(event)));
- script: (html jQuery this
- on: 'click'
- selector: '.destroy'
- do: ((html jQuery ajax
- callback: [ :passengers | passengers first remove ]
- passengers: (((html jQuery expression: (JSStream on:'event.target')) closest: 'li'));
- onComplete: (((html jQuery expression: (JSStream on:'event.target')) closest: 'li') remove)) asFunction: #(event)));
- script: (html jQuery this
- on: 'click'
- selector: '.view>label'
- do: (((((html jQuery expression: (JSStream on: 'event.target')) hide closest:'li') find: '.edit') show) asFunction:#(event)));
- script: (html jQuery this
- on: 'change'
- selector:'.edit'
- do: ((
- html jQuery ajax
- serialize: (html jQuery expression: (JSStream on:'event.target'));
- callback: [ :passengers | currentItem := passengers first ]
- passengers: ((html jQuery expression: (JSStream on:'event.target')) closest:'li');
- callback: [ :id | itemId := id ]
- value: (JSStream on:'$(event.target).closest("li").get(0).id');
- script: [ :s | s << (((s jQuery id: itemId) find: 'label') html: currentItem description) ];
- onComplete: ((((html jQuery expression: (JSStream on: 'event.target')) closest:'li') find: '.edit') hide, (((html jQuery expression: (JSStream on: 'event.target')) closest:'li') find: 'label') show))
- asFunction: #(event)));
with: [ self todos do: [ :todoItem | todoItem renderOn: html ] ] ]
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodo.class/instance/updateRoot..st b/repository/Seaside-Examples.package/WATodo.class/instance/updateRoot..st
index 39c3cca66..66816dd88 100644
--- a/repository/Seaside-Examples.package/WATodo.class/instance/updateRoot..st
+++ b/repository/Seaside-Examples.package/WATodo.class/instance/updateRoot..st
@@ -1,6 +1,6 @@
-rendering
+updating
updateRoot: aRoot
super updateRoot: aRoot.
- aRoot stylesheet url: WAExamplesLibrary / #todoCss.
- aRoot javascript url: JQDeploymentLibrary / #jQueryJs
\ No newline at end of file
+ aRoot title: 'Seaside Todo Demo'.
+ aRoot stylesheet url: WAExamplesLibrary / #todoCss
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodo.class/properties.json b/repository/Seaside-Examples.package/WATodo.class/properties.json
index d6f543c57..7a6098770 100644
--- a/repository/Seaside-Examples.package/WATodo.class/properties.json
+++ b/repository/Seaside-Examples.package/WATodo.class/properties.json
@@ -1,5 +1,5 @@
{
- "commentStamp" : "",
+ "commentStamp" : "JohanBrichau 8/23/2023 11:50",
"super" : "WAExampleComponent",
"category" : "Seaside-Examples-Misc",
"classinstvars" : [ ],
diff --git a/repository/Seaside-Examples.package/WATodoItem.class/README.md b/repository/Seaside-Examples.package/WATodoItem.class/README.md
index e69de29bb..bea333349 100644
--- a/repository/Seaside-Examples.package/WATodoItem.class/README.md
+++ b/repository/Seaside-Examples.package/WATodoItem.class/README.md
@@ -0,0 +1 @@
+I am the component that represents a single TODO line in the TODO application example
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodoItem.class/class/newWithDescription.in..st b/repository/Seaside-Examples.package/WATodoItem.class/class/newWithDescription.in..st
index 544869ab4..27357d54c 100644
--- a/repository/Seaside-Examples.package/WATodoItem.class/class/newWithDescription.in..st
+++ b/repository/Seaside-Examples.package/WATodoItem.class/class/newWithDescription.in..st
@@ -1,3 +1,3 @@
instance creation
newWithDescription: aString in: aCollection
- ^ self new initializeWithDescription: aString in: aCollection
\ No newline at end of file
+ ^ self basicNew initializeWithDescription: aString in: aCollection
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodoItem.class/instance/initializeWithDescription.in..st b/repository/Seaside-Examples.package/WATodoItem.class/instance/initializeWithDescription.in..st
index 0000b0c6e..127949d70 100644
--- a/repository/Seaside-Examples.package/WATodoItem.class/instance/initializeWithDescription.in..st
+++ b/repository/Seaside-Examples.package/WATodoItem.class/instance/initializeWithDescription.in..st
@@ -1,5 +1,6 @@
initialization
initializeWithDescription: aString in: aCollection
+
self initialize.
self done: false.
self description: aString.
diff --git a/repository/Seaside-Examples.package/WATodoItem.class/instance/renderContentOn..st b/repository/Seaside-Examples.package/WATodoItem.class/instance/renderContentOn..st
index 7c21fe50b..9b24805cf 100644
--- a/repository/Seaside-Examples.package/WATodoItem.class/instance/renderContentOn..st
+++ b/repository/Seaside-Examples.package/WATodoItem.class/instance/renderContentOn..st
@@ -1,20 +1,18 @@
rendering
renderContentOn: html
+
html listItem
- passenger: self;
- with: [
- html div
+ onDoubleClick: (html javascript callback: [ self call: (WATodoItemEditor on: self) ]);
+ with:[
+ html form
class: 'view';
with:[
html checkbox
class: 'toggle';
+ onChange: (JSStream on: 'this.form.requestSubmit()');
callback: [ :value | self done: value ];
value: done.
html label: description.
html button
- class: 'destroy' ].
- html textInput
- class: 'edit';
- style: 'display:none';
- callback: [ :value | self description: value ];
- value: description ]
\ No newline at end of file
+ callback: [ self remove ];
+ class: 'destroy' ] ]
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodoItem.class/properties.json b/repository/Seaside-Examples.package/WATodoItem.class/properties.json
index 089665b76..cc41c80b5 100644
--- a/repository/Seaside-Examples.package/WATodoItem.class/properties.json
+++ b/repository/Seaside-Examples.package/WATodoItem.class/properties.json
@@ -1,5 +1,5 @@
{
- "commentStamp" : "",
+ "commentStamp" : "JohanBrichau 8/23/2023 11:51",
"super" : "WAComponent",
"category" : "Seaside-Examples-Misc",
"classinstvars" : [ ],
diff --git a/repository/Seaside-Examples.package/WATodoItemEditor.class/README.md b/repository/Seaside-Examples.package/WATodoItemEditor.class/README.md
new file mode 100644
index 000000000..2b8f68755
--- /dev/null
+++ b/repository/Seaside-Examples.package/WATodoItemEditor.class/README.md
@@ -0,0 +1 @@
+I am the component that represents an editable TODO line in the TODO application example
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodoItemEditor.class/class/on..st b/repository/Seaside-Examples.package/WATodoItemEditor.class/class/on..st
new file mode 100644
index 000000000..4d174a81a
--- /dev/null
+++ b/repository/Seaside-Examples.package/WATodoItemEditor.class/class/on..st
@@ -0,0 +1,4 @@
+instance creation
+on: aWATodoItem
+
+ ^ self basicNew initializeOn: aWATodoItem
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodoItemEditor.class/instance/initializeOn..st b/repository/Seaside-Examples.package/WATodoItemEditor.class/instance/initializeOn..st
new file mode 100644
index 000000000..391b7dc5c
--- /dev/null
+++ b/repository/Seaside-Examples.package/WATodoItemEditor.class/instance/initializeOn..st
@@ -0,0 +1,5 @@
+initialization
+initializeOn: aWATodoItem
+
+ self initialize.
+ todoItem := aWATodoItem
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WATodoItemEditor.class/instance/renderContentOn..st b/repository/Seaside-Examples.package/WATodoItemEditor.class/instance/renderContentOn..st
new file mode 100644
index 000000000..82c0663cd
--- /dev/null
+++ b/repository/Seaside-Examples.package/WATodoItemEditor.class/instance/renderContentOn..st
@@ -0,0 +1,11 @@
+rendering
+renderContentOn: html
+
+ html form: [
+ html textInput
+ class: 'edit';
+ callback: [ :value | todoItem description: value ];
+ value: todoItem description.
+ html submitButton
+ style: 'display:none';
+ callback: [ self answer ] ]
\ No newline at end of file
diff --git a/repository/Seaside-Examples.package/WAJQueryExampleComponent.class/properties.json b/repository/Seaside-Examples.package/WATodoItemEditor.class/properties.json
similarity index 56%
rename from repository/Seaside-Examples.package/WAJQueryExampleComponent.class/properties.json
rename to repository/Seaside-Examples.package/WATodoItemEditor.class/properties.json
index c07f3a52e..ddbfa22bc 100644
--- a/repository/Seaside-Examples.package/WAJQueryExampleComponent.class/properties.json
+++ b/repository/Seaside-Examples.package/WATodoItemEditor.class/properties.json
@@ -1,11 +1,13 @@
{
- "commentStamp" : "",
+ "commentStamp" : "JohanBrichau 8/23/2023 11:51",
"super" : "WAComponent",
"category" : "Seaside-Examples-Misc",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
- "instvars" : [ ],
- "name" : "WAJQueryExampleComponent",
+ "instvars" : [
+ "todoItem"
+ ],
+ "name" : "WATodoItemEditor",
"type" : "normal"
}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/.filetree b/repository/Seaside-GemStone-Core.package/.filetree
index 8998102c2..57a679737 100644
--- a/repository/Seaside-GemStone-Core.package/.filetree
+++ b/repository/Seaside-GemStone-Core.package/.filetree
@@ -1,4 +1,5 @@
{
- "noMethodMetaData" : true,
"separateMethodMetaAndSource" : false,
- "useCypressPropertiesFile" : true }
+ "noMethodMetaData" : true,
+ "useCypressPropertiesFile" : true
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/AbstractDictionary.extension/properties.json b/repository/Seaside-GemStone-Core.package/AbstractDictionary.extension/properties.json
index 763edb842..1dbd70c66 100644
--- a/repository/Seaside-GemStone-Core.package/AbstractDictionary.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/AbstractDictionary.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "AbstractDictionary" }
+ "name" : "AbstractDictionary"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/Bag.extension/properties.json b/repository/Seaside-GemStone-Core.package/Bag.extension/properties.json
index facfa7af3..7085387d9 100644
--- a/repository/Seaside-GemStone-Core.package/Bag.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/Bag.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "Bag" }
+ "name" : "Bag"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/CharacterCollection.extension/properties.json b/repository/Seaside-GemStone-Core.package/CharacterCollection.extension/properties.json
index c85a513c3..e95044552 100644
--- a/repository/Seaside-GemStone-Core.package/CharacterCollection.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/CharacterCollection.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "CharacterCollection" }
+ "name" : "CharacterCollection"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/GRGemStonePlatform.extension/properties.json b/repository/Seaside-GemStone-Core.package/GRGemStonePlatform.extension/properties.json
index eab5d9b55..eb3c2499a 100644
--- a/repository/Seaside-GemStone-Core.package/GRGemStonePlatform.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/GRGemStonePlatform.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "GRGemStonePlatform" }
+ "name" : "GRGemStonePlatform"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/GRObject.extension/properties.json b/repository/Seaside-GemStone-Core.package/GRObject.extension/properties.json
index 58a89918f..bcef24c66 100644
--- a/repository/Seaside-GemStone-Core.package/GRObject.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/GRObject.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "GRObject" }
+ "name" : "GRObject"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/GRPackage.extension/properties.json b/repository/Seaside-GemStone-Core.package/GRPackage.extension/properties.json
index dd2faaf08..ae522a7e0 100644
--- a/repository/Seaside-GemStone-Core.package/GRPackage.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/GRPackage.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "GRPackage" }
+ "name" : "GRPackage"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/MIMEDocument.extension/properties.json b/repository/Seaside-GemStone-Core.package/MIMEDocument.extension/properties.json
index 6624012e3..e3d70ed7f 100644
--- a/repository/Seaside-GemStone-Core.package/MIMEDocument.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/MIMEDocument.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "MIMEDocument" }
+ "name" : "MIMEDocument"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/MessageSend.extension/properties.json b/repository/Seaside-GemStone-Core.package/MessageSend.extension/properties.json
index 66fcc3c1b..00669b90c 100644
--- a/repository/Seaside-GemStone-Core.package/MessageSend.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/MessageSend.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "MessageSend" }
+ "name" : "MessageSend"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/Object.extension/properties.json b/repository/Seaside-GemStone-Core.package/Object.extension/properties.json
index 3d3b9ec45..f30a86e11 100644
--- a/repository/Seaside-GemStone-Core.package/Object.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/Object.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "Object" }
+ "name" : "Object"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/ObjectLogEntry.extension/properties.json b/repository/Seaside-GemStone-Core.package/ObjectLogEntry.extension/properties.json
index ecf42342c..d7f72a38e 100644
--- a/repository/Seaside-GemStone-Core.package/ObjectLogEntry.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/ObjectLogEntry.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "ObjectLogEntry" }
+ "name" : "ObjectLogEntry"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/OrderedCollection.extension/properties.json b/repository/Seaside-GemStone-Core.package/OrderedCollection.extension/properties.json
index c40806091..ed81cf535 100644
--- a/repository/Seaside-GemStone-Core.package/OrderedCollection.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/OrderedCollection.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "OrderedCollection" }
+ "name" : "OrderedCollection"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/PositionableStream.extension/properties.json b/repository/Seaside-GemStone-Core.package/PositionableStream.extension/properties.json
index 9e1697a61..8e090ee3c 100644
--- a/repository/Seaside-GemStone-Core.package/PositionableStream.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/PositionableStream.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "PositionableStream" }
+ "name" : "PositionableStream"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/SentButNotImplementedTest.extension/properties.json b/repository/Seaside-GemStone-Core.package/SentButNotImplementedTest.extension/properties.json
index 4b0d17e45..03e0b087d 100644
--- a/repository/Seaside-GemStone-Core.package/SentButNotImplementedTest.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/SentButNotImplementedTest.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "SentButNotImplementedTest" }
+ "name" : "SentButNotImplementedTest"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/Set.extension/properties.json b/repository/Seaside-GemStone-Core.package/Set.extension/properties.json
index f9de8dae6..9f6f45568 100644
--- a/repository/Seaside-GemStone-Core.package/Set.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/Set.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "Set" }
+ "name" : "Set"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/String.extension/properties.json b/repository/Seaside-GemStone-Core.package/String.extension/properties.json
index c21385076..b20f2de3b 100644
--- a/repository/Seaside-GemStone-Core.package/String.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/String.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "String" }
+ "name" : "String"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/TransientRecursionLock.extension/properties.json b/repository/Seaside-GemStone-Core.package/TransientRecursionLock.extension/properties.json
index 7f850be87..991764727 100644
--- a/repository/Seaside-GemStone-Core.package/TransientRecursionLock.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/TransientRecursionLock.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "TransientRecursionLock" }
+ "name" : "TransientRecursionLock"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/TransientValue.extension/properties.json b/repository/Seaside-GemStone-Core.package/TransientValue.extension/properties.json
index 7ffa29380..89753b9d2 100644
--- a/repository/Seaside-GemStone-Core.package/TransientValue.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/TransientValue.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "TransientValue" }
+ "name" : "TransientValue"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/WAExceptionHandler.extension/properties.json b/repository/Seaside-GemStone-Core.package/WAExceptionHandler.extension/properties.json
index 93ab897a3..64c2e6911 100644
--- a/repository/Seaside-GemStone-Core.package/WAExceptionHandler.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/WAExceptionHandler.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "WAExceptionHandler" }
+ "name" : "WAExceptionHandler"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/WAGemStoneMutex.class/properties.json b/repository/Seaside-GemStone-Core.package/WAGemStoneMutex.class/properties.json
index c35d8bde7..f73f5abd7 100644
--- a/repository/Seaside-GemStone-Core.package/WAGemStoneMutex.class/properties.json
+++ b/repository/Seaside-GemStone-Core.package/WAGemStoneMutex.class/properties.json
@@ -1,15 +1,14 @@
{
- "category" : "Seaside-GemStone-Core-Utilities",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WAObject",
+ "category" : "Seaside-GemStone-Core-Utilities",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
"semaphore",
- "owner" ],
+ "owner"
+ ],
"name" : "WAGemStoneMutex",
- "pools" : [
- ],
- "super" : "WAObject",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/WAGemStoneRequestContext.class/properties.json b/repository/Seaside-GemStone-Core.package/WAGemStoneRequestContext.class/properties.json
index 79f5f19c7..dad20d679 100644
--- a/repository/Seaside-GemStone-Core.package/WAGemStoneRequestContext.class/properties.json
+++ b/repository/Seaside-GemStone-Core.package/WAGemStoneRequestContext.class/properties.json
@@ -1,14 +1,13 @@
{
- "category" : "Seaside-GemStone-Core-RequestHandling",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WARequestContext",
+ "category" : "Seaside-GemStone-Core-RequestHandling",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
- "forDebugging" ],
+ "forDebugging"
+ ],
"name" : "WAGemStoneRequestContext",
- "pools" : [
- ],
- "super" : "WARequestContext",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/WAGsUrlEncoder.class/properties.json b/repository/Seaside-GemStone-Core.package/WAGsUrlEncoder.class/properties.json
index 9c5cd1863..0c8cb59aa 100644
--- a/repository/Seaside-GemStone-Core.package/WAGsUrlEncoder.class/properties.json
+++ b/repository/Seaside-GemStone-Core.package/WAGsUrlEncoder.class/properties.json
@@ -1,14 +1,11 @@
{
- "category" : "Seaside-GemStone-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
- "instvars" : [
- ],
- "name" : "WAGsUrlEncoder",
- "pools" : [
- ],
"super" : "WAUrlEncoder",
- "type" : "normal" }
+ "category" : "Seaside-GemStone-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [ ],
+ "name" : "WAGsUrlEncoder",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/WAObjectLogEntry.class/properties.json b/repository/Seaside-GemStone-Core.package/WAObjectLogEntry.class/properties.json
index 78af6d9fd..f83ec344d 100644
--- a/repository/Seaside-GemStone-Core.package/WAObjectLogEntry.class/properties.json
+++ b/repository/Seaside-GemStone-Core.package/WAObjectLogEntry.class/properties.json
@@ -1,14 +1,13 @@
{
- "category" : "Seaside-GemStone-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "RemoteDebuggerLogEntry",
+ "category" : "Seaside-GemStone-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
- "request" ],
+ "request"
+ ],
"name" : "WAObjectLogEntry",
- "pools" : [
- ],
- "super" : "RemoteDebuggerLogEntry",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/WARetryHttpRequest.extension/properties.json b/repository/Seaside-GemStone-Core.package/WARetryHttpRequest.extension/properties.json
index cadc920f8..f750ae14a 100644
--- a/repository/Seaside-GemStone-Core.package/WARetryHttpRequest.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/WARetryHttpRequest.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "WARetryHttpRequest" }
+ "name" : "WARetryHttpRequest"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/WAServerAdaptor.extension/properties.json b/repository/Seaside-GemStone-Core.package/WAServerAdaptor.extension/properties.json
index 3e6a1f464..fc14321b0 100644
--- a/repository/Seaside-GemStone-Core.package/WAServerAdaptor.extension/properties.json
+++ b/repository/Seaside-GemStone-Core.package/WAServerAdaptor.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "WAServerAdaptor" }
+ "name" : "WAServerAdaptor"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/WASessionLockNotAcquiredException.class/properties.json b/repository/Seaside-GemStone-Core.package/WASessionLockNotAcquiredException.class/properties.json
index 83f41c54a..acebe4c8a 100644
--- a/repository/Seaside-GemStone-Core.package/WASessionLockNotAcquiredException.class/properties.json
+++ b/repository/Seaside-GemStone-Core.package/WASessionLockNotAcquiredException.class/properties.json
@@ -1,14 +1,11 @@
{
- "category" : "Seaside-GemStone-Core-Notifications",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
- "instvars" : [
- ],
- "name" : "WASessionLockNotAcquiredException",
- "pools" : [
- ],
"super" : "WARetryHttpRequest",
- "type" : "normal" }
+ "category" : "Seaside-GemStone-Core-Notifications",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [ ],
+ "name" : "WASessionLockNotAcquiredException",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/monticello.meta/version b/repository/Seaside-GemStone-Core.package/monticello.meta/version
deleted file mode 100644
index ecdc96603..000000000
--- a/repository/Seaside-GemStone-Core.package/monticello.meta/version
+++ /dev/null
@@ -1 +0,0 @@
-(name 'Seaside-GemStone-Core-JohanBrichau.83' message 'Removed the GsContext class because it is in Grease since 2 years now' id '60a8ba9d-34b3-4e9a-9398-aa4f569b80f6' date '10/02/2020' time '13:16:13' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.82' message 'address https://github.com/SeasideSt/Seaside/commit/622616aee2896a8e61ebb0edfa4f622807d6f5af#commitcomment-12213675' id '6911ec2b-09d1-4ca2-b8ee-76c7abf476a4' date '07/24/2015' time '01:47:27' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.81' message 'removed WARcLastAccessPolicy' id 'f1992299-0907-4951-a0ed-4a4eb0ed1536' date '07/16/2015' time '06:09:07' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.80' message 'WAGsUrlEncoder needs a class initialize method' id '65ee6899-3e65-48e3-b8cc-6285916daa58' date '07/16/2015' time '03:11:45' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.79' message 'Remove gemstoneReap method (now works with WABulkReapingCache>>reap)' id 'd00c023a-30f4-48d5-a371-76fd22266757' date '07/16/2015' time '02:50:38' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.78' message 'Introduce WAGsUrlEncoder as an optimization of WAUrlEncoder to remove the gemstone-specific change to WATableBasedEncoder (issue 845)' id 'de234f0e-a13c-452b-8d89-d32116cffdfb' date '07/16/2015' time '01:00:19' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.77' message 'added necessary methods on GRGemStonePlatform' id '110e5090-a763-4be3-aaed-efd5320f1044' date '07/15/2015' time '04:04:57' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.76' message 'Part of the changes required to sync with Seaside-Core-pmm.848' id '5fe7def5-5074-4478-a7eb-286dc28624c4' date '07/14/2015' time '09:05:47' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.75' message 'Gs issue 71: Bugfix for situation where the active process'' reified object is changed due to Seaside call/answer continuation logic, eventually causing a deadlock in the transientrecursionlock (See https://github.com/GsDevKit/Seaside31/issues/71)' id '5c899003-dbe1-4fdf-a619-62d22168ada8' date '06/06/2015' time '02:53:40' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-dkh.74' message 'Missed some sent but not implemented for GemStone 3.3 changes' id '03352f02-041d-4bb9-80f4-25d319b48321' date '05/27/2015' time '10:11:07' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.73' message 'port GsContext>>continuation:level: to GemStone 3.3' id 'e78c9fa7-333a-4672-9231-28de7962f422' date '05/26/2015' time '15:44:20' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.72' message 'merged by GitFileTree-MergeDriver' id '6d109e15-3e45-4040-9228-566acb331179' date '04/08/2015' time '03:25:05' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.71' message 'set explicit array of retry delays + remove shadowed var' id '829672b8-18de-461b-ab95-2cf375ddf30c' date '04/04/2015' time '03:14:15' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.70' message 'explicitly state the retry delays to be used' id '3400d140-358e-4ae4-a000-53772d33e0e5' date '04/04/2015' time '02:53:19' author 'JohanBrichau' ancestors () stepChildren ())) stepChildren ())(name 'Seaside-GemStone-Core-dkh.70' message 'Issue #64: in an attempt to avoid saving a GsSocket instance when logging a commit conflict to the object log, we''ll just pass the url of the native request ... unless the GsSocket is sneaking into a persistent root some other (less obvious way) ... logging commit conflicts should now be safe and hopefully the FastCGI-related GsSocket "lost state" errors nuked' id '59b5f0d8-77f2-4893-8f70-4223af182b39' date '04/03/2015' time '15:49:51' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.69' message 'GRGemStonePlatform>>seasideProcessRequest:adaptor:resultBlock: in Seaside-GemStone-Core sends #internalServerErrorMessage: a messge that is implemented by the adaptor classes ...' id '5808ac48-a4cd-420e-a143-feee3fac8bd2' date '12/14/2014' time '13:49:13' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.68' message 'WAScriptGenerator>>writeLoadScriptsOn: in Seaside-Core sends the message javascript: that is implemented in Javascript-Core...' id '46893b1f-569c-4ce2-9564-0e35c738af41' date '12/14/2014' time '13:44:28' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.67' message 'get all tests passing for Seaside3.1.1 in GemStone 3.2
- remove ExecutableBlock methods from Seaside-GemStone-Core package
- move UnorderedCollection>>restoreFromSnapshot: and
UnorderedCollection>>snapshotCopy into Seaside-GemStone320-Core (new package for
3.2) and Seaside-GemStone300-Core (3.0 and 3.1)' id '8dee7f71-7db2-4ab2-a21b-16bd761bbe38' date '06/04/2014' time '20:34:05' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.66' message 'Merged-in the implementation of WANoReapingStrategy from Seaside3.0' id '005ec643-0557-4549-a374-f1b14be232e1' date '12/15/2013' time '07:46:25' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.65' message 'added WARcLastAccessExpiryPolicy (copied from Seaside30)' id '78f92895-5d98-4c4c-b7df-2abbc212b97b' date '09/29/2013' time '04:58:10' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-JohanBrichau.64' message 'added WARcLastAccessExpiryPolicy (copied from Seaside30)' id 'c4c7f536-4b16-4654-8d6e-d2b97cd7fa95' date '09/29/2013' time '04:49:28' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Core-dkh.63' message '3.0.6.1 (dkh.334):
- remove the GemStone method seasideNextLine and add a test for Issue 289' id '81e7cc84-552b-4806-bf52-2d93f25be69c' date '09/27/2011' time '14:59:38' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.62' message '- stop logging lock not acquired events' id 'ea61cee0-b218-4380-b66c-9213a7150077' date '05/31/2011' time '15:19:02' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.61' message '- fix Issue 217: MultibyteString JavascriptOn infinite recursion [GemStone]
http://code.google.com/p/glassdb/issues/detail?id=217
- add JSJsonStreamTest>>testStringMultiByte to common test suite' id '18c522ae-04fb-44fe-acfc-1281702a335c' date '02/16/2011' time '17:09:21' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.60' message 'better retry algorithm ... I think' id 'db8dc2a3-6668-4a49-bf15-e28195eef5c1' date '08/12/2010' time '21:42:47' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.59' message '- increasing delays on retry' id 'b3b0093c-230e-45e4-99d4-8125d6f266ab' date '08/04/2010' time '13:24:49' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.57' message '- moved WARetryHttpRequest' id '7401878d-4f8f-456a-8a0d-a968544b1db6' date '07/23/1910' time '11:45:26' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.56' message '- pushing methods around' id '6984eaea-fc2c-48ae-b412-2c412e567df8' date '07/23/1910' time '11:26:13' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.55' message '- moved to Grease and Seaside-GemStone240-Core' id '429a06a4-f20f-48c9-9bae-85eeab6e10bc' date '07/23/1910' time '10:53:22' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.54' message '- changes to support Seaside-Core-pmm.648 merge' id 'e10f69df-da45-4aed-a6ef-bbb02a776024' date '06/21/1910' time '15:10:51' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.53' message '- remove ObjectLogErrorHandlers...the remote debugging error handlers are preferred
- WAGemStoneRequestContext allows for conditionally destroying the context contents ... don''t destroy context if we are debugging with a continuation.
' id 'b09badd3-230a-47d6-9249-c762b1897542' date '06/21/1910' time '14:00:34' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.52' message '-transcript object log support
- disable ''Proceed'' for remote debugging until Issue 128 is fixed (http://code.google.com/p/glassdb/issues/detail?id=128)
' id 'c5aa744d-fede-4391-9304-aeda998f1cad' date '06/20/1910' time '16:06:09' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.51' message '- clean up handling of internal server errors' id '734e24dc-c704-4621-891a-f5adab15e770' date '06/18/1910' time '16:56:30' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.50' message '- performance enhancements' id 'c5bf4ff5-3680-443c-b5d9-1a4fa9d81bf7' date '06/18/1910' time '09:07:38' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.49' message '- need a GsContext>>greaseString' id '5f00a802-f522-44b0-a794-075663d03f49' date '06/04/1910' time '17:50:55' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.48' message '- install a missing #renderOn: message' id 'a0a45c36-73d9-4029-aefe-3e1638dca0bd' date '06/04/1910' time '15:40:09' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.47' message '- clean up sent but not implemented for 3.0.0-alpha5.15' id '22cf5d52-1d31-48f6-b2dd-3a340affa326' date '06/04/1910' time '10:10:05' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.46' message '- support for Grease 1.0-alpha9.3' id 'ac00dbb9-18b8-4709-9ef7-dd76562d08bd' date '06/03/1910' time '14:44:53' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-DaleHenrichs.45' message '- move some methods from Seaside-GemStone-Core to Grease-GemStone-Core' id 'aecf8cf0-8463-4569-9f2e-dcdeca5be069' date '06/02/1910' time '15:32:52' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Core-dkh.44' message '- support for maintenance vm cache reaping' id '22ab5138-c62f-4bc8-9e87-1c87243b6433' date '12/29/2009' time '09:42:16' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.43' message '- WACache>>gemstoneReap to be used for expiring sessions from a separate vm' id 'a90db662-3445-4b12-9a4b-c4d825da504f' date '12/28/2009' time '09:30:33' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.42' message '- bullet proof the bullet proofing' id '70b0baac-5b5c-4b12-9efd-7e3e18095f8b' date '12/28/2009' time '07:02:06' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.41' message '- bullet proof WAGemStoneMutex from concurrency issues' id '50722445-5914-4475-ba20-80e09be07102' date '12/24/2009' time '16:57:56' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.40' message '- add GemStone WAObjectLogErrorHandler ... minimum multi-vm support' id '13049094-a2cc-4758-90a7-72de856ab90c' date '12/24/2009' time '13:16:24' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.39' message '- concurrent server gem support for FastCGI and Swazoo2
- common adaptor code for transactions and request processing
- server logging and error handlers
' id '04a6752e-77bd-4d9a-8ae6-685fa2bcfc92' date '12/23/2009' time '16:47:39' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.38' message '- add WAGemStoneMutex
- fix error handling bugs' id '037d31f0-8cbb-4019-ad41-046c93901a6c' date '11/23/2009' time '15:36:28' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.37' message '- update dependencies based on loading experiences using ConfigurationOfSeaside30
' id '21953dc1-1c9b-401a-8964-690cca5f3f87' date '11/13/2009' time '15:16:51' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.36' message '- moved methods that belong in Seaside-GemStone-Development' id '9bd2f06a-1c18-43c1-a88e-54af230b9ced' date '11/10/2009' time '15:41:11' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.35' message '- remove deprecatedAPI' id 'ddf0a3ef-da17-4eb8-b093-8e4f7386c580' date '11/09/2009' time '13:04:25' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.34' message '- skidding on grease' id '923ddf8c-f06a-4a69-98de-303f34d7d5a9' date '11/06/2009' time '10:24:51' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.33' message '- skidding on grease' id 'f30d7b86-677a-4236-ac21-944421602a49' date '11/06/2009' time '10:02:54' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.32' message '- method moved to Sport' id '5ccead2c-2ca8-483e-bf30-b5349ac4a336' date '11/06/2009' time '08:00:44' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.31' message '- remove all of the class-side methods (completely obsolete)
- replace toString with seasideString' id '004163ab-d043-4361-94bf-6145947bb383' date '09/16/2009' time '12:03:01' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-jgf.30' message 'Save current state to see if we can get clean loads...' id '9f7bf19a-bb0d-4304-a281-ba185fa5784c' date '09/04/2009' time '17:21:40' author 'jgf' ancestors ((name 'Seaside-GemStone-Core-jgf.29' message 'Add a method to PositionableStream. There are a number of other changes, including removal of WAContinuation (is it in another package?) and addition of a number of additional methods for WAGemStonePlatform.' id 'cee6b385-7fda-4e30-b7a1-a87ff11bcc96' date '05/05/2009' time '13:19:08' author 'jgf' ancestors ((name 'Seaside-GemStone-Core-dkh.28' message '- utf8 fixes' id '06384203-6ece-46e4-a444-1a5921035041' date '09/03/2008' time '10:37:50' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.27' message '- (formerly) seaside support code moved to bootstrap' id '3e1521b7-417e-4f11-bc6e-1ae6c6430c5b' date '08/25/2008' time '15:12:51' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.26' message '- minor method shuffling
' id 'be238520-beee-4ce5-8648-e898a234727c' date '05/30/2008' time '11:42:05' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.25' message '- atRandom moved to Squeak
- error handlers moved to development' id 'f5d53bda-c6df-4d06-9d26-afc05050e49e' date '05/30/2008' time '11:27:08' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.24' message '- BlockCllosure>>equivalentTo: so that lightweight stuff can run on GemStone and Squeak
' id 'ec267527-a366-4453-814d-b86fe9aa3737' date '05/23/2008' time '16:34:11' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.23' message '- get GemStone error handlers working' id '774dbfe3-672a-49bf-ac5d-16ae3dafb358' date '05/20/2008' time '16:51:11' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.22' message '- add some extension methods that slipped between the cracks' id 'b4e3c84f-6459-48ab-b952-4de09c8614e0' date '05/20/2008' time '12:44:25' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.21' message '- some reorganizing
- some stuff from Seaside2.8' id 'f6f113ad-9036-4930-9788-34426565dc5c' date '05/20/2008' time '12:16:25' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.20' message '- continued fastcgi ' id '4fd579c4-cc69-4f4d-90ef-ca25e2ff256a' date '05/20/2008' time '09:28:36' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.19' message '- more fastcgi support' id '73ab4d46-1039-445f-962e-a73e31237054' date '05/20/2008' time '08:32:12' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.18' message '- fastcgi support' id '1c4f2d84-fa38-4ac4-9495-797d6cd37890' date '05/20/2008' time '08:26:45' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.17' message '- added some classes needed for GastCGI
' id 'e2f32308-fd30-4b0c-836d-66ae45b706d5' date '05/19/2008' time '20:35:26' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.16' message '- catch up with latest API' id '66d48746-ccf5-4e54-ac4c-9d5b6e189018' date '05/19/2008' time '16:49:23' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.15' message '- add WAProcessVariable' id '30e54db0-a6d5-4616-a6b0-96c041b0499a' date '05/19/2008' time '15:10:19' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.14' message '- rename Contuation to WAContinuation' id '15c123d6-e4a8-4fcd-a994-b5aa0012e4d7' date '03/24/2008' time '14:46:27' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.12' message '- Object>>snapshotCopy moved to platform-specific package' id '5fbc0db9-8818-459c-8862-5cd1715002b9' date '03/19/2008' time '15:24:31' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.11' message '- toString for DoubleByteString' id '11550012-8024-4fa1-9e53-e7504c40cd1f' date '03/19/2008' time '11:56:37' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.10' message '- add Date class >> daysInMonthNumber:forYear: ' id '15c43214-911a-4a1e-bc5b-b49300ff9b66' date '03/17/2008' time '16:21:50' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.9' message '- restgore FileLibraryCache ...' id 'e6c57fc7-8d70-4112-80c3-c365ca9dea4d' date '03/17/2008' time '16:16:55' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.8' message '- passing more tests' id 'dd8a5310-560d-4414-b04c-a4ca2ccad5b4' date '03/07/2008' time '17:09:12' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.7' message '- another round for toString (I think I''ve got it this time - at least the tests are all passing)
- add sourceCodeLineSeparatorCharacter method' id 'e95b18ce-8c9e-4ec4-813f-048571c8b13f' date '03/07/2008' time '16:16:34' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.6' message '- add WAGemStonePlatform class>>stackDepth. GemStone doesn''t have thisContext used in WAFlowTest, so provide a platform specific method
' id '3fd9fb48-13ce-4860-b0d1-c9d1cf7cb4b0' date '03/03/2008' time '20:16:56' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.5' message '- begin straightening out #toString changes' id 'a4e9aa59-eb0f-4b41-bd51-2a844c75051a' date '03/03/2008' time '17:15:17' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.4' message '- make pass through Seaside-Squeak-Core and pick up a couple new extension methods' id '22c4a766-adfb-491d-b433-9c10018ce629' date '03/03/2008' time '16:25:54' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.3' message '- made pass through Seaside2.8 extension methods and pulled all of the true Seaside extensions into this package
' id '661a3a4e-7c07-47f7-98e7-c307def9e4d3' date '03/03/2008' time '15:59:34' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.2' message '- bring over Continuation class' id 'c6547486-65d4-4b30-9af6-e9aa60730737' date '02/29/2008' time '10:24:41' author 'dkh' ancestors ((name 'Seaside-GemStone-Core-dkh.1' message '- initial version' id 'f5e514b3-8445-4cbc-ac1a-87cb2eb29cf3' date '02/28/2008' time '16:22:55' author 'dkh' ancestors () stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())(name 'Seaside-GemStone-Core-DaleHenrichs.58' message '- session stats for Seaside 3.0
0 - request count (oncoming)
1 - response count (outgoing)
2 - request retries' id 'ed2f4013-8172-45f0-a4a2-c93881edb524' date '07/30/2010' time '17:12:09' author 'DaleHenrichs' ancestors () stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Core.package/properties.json b/repository/Seaside-GemStone-Core.package/properties.json
index f037444a7..6f31cf5a2 100644
--- a/repository/Seaside-GemStone-Core.package/properties.json
+++ b/repository/Seaside-GemStone-Core.package/properties.json
@@ -1,2 +1 @@
-{
- }
+{ }
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/.filetree b/repository/Seaside-GemStone-Development.package/.filetree
index 8998102c2..57a679737 100644
--- a/repository/Seaside-GemStone-Development.package/.filetree
+++ b/repository/Seaside-GemStone-Development.package/.filetree
@@ -1,4 +1,5 @@
{
- "noMethodMetaData" : true,
"separateMethodMetaAndSource" : false,
- "useCypressPropertiesFile" : true }
+ "noMethodMetaData" : true,
+ "useCypressPropertiesFile" : true
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/BlockClosure.extension/properties.json b/repository/Seaside-GemStone-Development.package/BlockClosure.extension/properties.json
index 1d6f4884e..2190e5e29 100644
--- a/repository/Seaside-GemStone-Development.package/BlockClosure.extension/properties.json
+++ b/repository/Seaside-GemStone-Development.package/BlockClosure.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "BlockClosure" }
+ "name" : "BlockClosure"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/GRPackage.extension/properties.json b/repository/Seaside-GemStone-Development.package/GRPackage.extension/properties.json
index dd2faaf08..ae522a7e0 100644
--- a/repository/Seaside-GemStone-Development.package/GRPackage.extension/properties.json
+++ b/repository/Seaside-GemStone-Development.package/GRPackage.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "GRPackage" }
+ "name" : "GRPackage"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WADevelopment.class/properties.json b/repository/Seaside-GemStone-Development.package/WADevelopment.class/properties.json
index a99eeb595..f29cdad9b 100644
--- a/repository/Seaside-GemStone-Development.package/WADevelopment.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WADevelopment.class/properties.json
@@ -1,14 +1,11 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
- "instvars" : [
- ],
- "name" : "WADevelopment",
- "pools" : [
- ],
"super" : "WABasicDevelopment",
- "type" : "normal" }
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [ ],
+ "name" : "WADevelopment",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAGemStoneContinuationDebugger.class/properties.json b/repository/Seaside-GemStone-Development.package/WAGemStoneContinuationDebugger.class/properties.json
index de54ae143..8013cf1ce 100644
--- a/repository/Seaside-GemStone-Development.package/WAGemStoneContinuationDebugger.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAGemStoneContinuationDebugger.class/properties.json
@@ -1,14 +1,13 @@
{
- "category" : "Seaside-GemStone-Development",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "dkh 06/05/2015 15:44",
+ "super" : "WAGemStoneWalkback",
+ "category" : "Seaside-GemStone-Development",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
- "errorDescription" ],
+ "errorDescription"
+ ],
"name" : "WAGemStoneContinuationDebugger",
- "pools" : [
- ],
- "super" : "WAGemStoneWalkback",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAGemStoneInspector.class/properties.json b/repository/Seaside-GemStone-Development.package/WAGemStoneInspector.class/properties.json
index 3c2278c2b..66efcd62f 100644
--- a/repository/Seaside-GemStone-Development.package/WAGemStoneInspector.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAGemStoneInspector.class/properties.json
@@ -1,14 +1,11 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
- "instvars" : [
- ],
- "name" : "WAGemStoneInspector",
- "pools" : [
- ],
"super" : "WAInspector",
- "type" : "normal" }
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [ ],
+ "name" : "WAGemStoneInspector",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAGemStoneWalkback.class/properties.json b/repository/Seaside-GemStone-Development.package/WAGemStoneWalkback.class/properties.json
index fef689ac4..66d5191bb 100644
--- a/repository/Seaside-GemStone-Development.package/WAGemStoneWalkback.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAGemStoneWalkback.class/properties.json
@@ -1,14 +1,13 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WAWalkback",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
- "frames" ],
+ "frames"
+ ],
"name" : "WAGemStoneWalkback",
- "pools" : [
- ],
- "super" : "WAWalkback",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAGemStoneWalkbackErrorHandler.class/properties.json b/repository/Seaside-GemStone-Development.package/WAGemStoneWalkbackErrorHandler.class/properties.json
index 7c3c04123..ed31b7419 100644
--- a/repository/Seaside-GemStone-Development.package/WAGemStoneWalkbackErrorHandler.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAGemStoneWalkbackErrorHandler.class/properties.json
@@ -1,14 +1,11 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "dkh 10/14/2011 13:55",
- "instvars" : [
- ],
- "name" : "WAGemStoneWalkbackErrorHandler",
- "pools" : [
- ],
"super" : "WAWalkbackErrorHandler",
- "type" : "normal" }
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [ ],
+ "name" : "WAGemStoneWalkbackErrorHandler",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAHandleAbortWouldLoseDataToolFilter.class/properties.json b/repository/Seaside-GemStone-Development.package/WAHandleAbortWouldLoseDataToolFilter.class/properties.json
index 79e6c0ce1..cf388eb42 100644
--- a/repository/Seaside-GemStone-Development.package/WAHandleAbortWouldLoseDataToolFilter.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAHandleAbortWouldLoseDataToolFilter.class/properties.json
@@ -1,14 +1,11 @@
{
- "category" : "Seaside-GemStone-Development-Filter",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
- "instvars" : [
- ],
- "name" : "WAHandleAbortWouldLoseDataToolFilter",
- "pools" : [
- ],
"super" : "WARequestFilter",
- "type" : "normal" }
+ "category" : "Seaside-GemStone-Development-Filter",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [ ],
+ "name" : "WAHandleAbortWouldLoseDataToolFilter",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAObjectsReadFilter.class/properties.json b/repository/Seaside-GemStone-Development.package/WAObjectsReadFilter.class/properties.json
index 49f7ec815..cf5254a37 100644
--- a/repository/Seaside-GemStone-Development.package/WAObjectsReadFilter.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAObjectsReadFilter.class/properties.json
@@ -1,14 +1,13 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "JohanBrichau 06/07/2023 20:05",
+ "super" : "WARequestFilter",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
- "items" ],
+ "items"
+ ],
"name" : "WAObjectsReadFilter",
- "pools" : [
- ],
- "super" : "WARequestFilter",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAObjectsReadItem.class/properties.json b/repository/Seaside-GemStone-Development.package/WAObjectsReadItem.class/properties.json
index 7e8046049..88e91909d 100644
--- a/repository/Seaside-GemStone-Development.package/WAObjectsReadItem.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAObjectsReadItem.class/properties.json
@@ -1,18 +1,17 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WAObject",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
"request",
"objectsRead",
"size",
"start",
- "end" ],
+ "end"
+ ],
"name" : "WAObjectsReadItem",
- "pools" : [
- ],
- "super" : "WAObject",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAObjectsReadTool.class/properties.json b/repository/Seaside-GemStone-Development.package/WAObjectsReadTool.class/properties.json
index 7d5f3ec67..431bd5382 100644
--- a/repository/Seaside-GemStone-Development.package/WAObjectsReadTool.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAObjectsReadTool.class/properties.json
@@ -1,16 +1,15 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WATool",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
"report",
"items",
- "message" ],
+ "message"
+ ],
"name" : "WAObjectsReadTool",
- "pools" : [
- ],
- "super" : "WATool",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAObjectsReadToolPlugin.class/properties.json b/repository/Seaside-GemStone-Development.package/WAObjectsReadToolPlugin.class/properties.json
index 3616d3d69..75e049a3c 100644
--- a/repository/Seaside-GemStone-Development.package/WAObjectsReadToolPlugin.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAObjectsReadToolPlugin.class/properties.json
@@ -1,14 +1,13 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WAToolPlugin",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
- "filter" ],
+ "filter"
+ ],
"name" : "WAObjectsReadToolPlugin",
- "pools" : [
- ],
- "super" : "WAToolPlugin",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAProfilerFilter.class/properties.json b/repository/Seaside-GemStone-Development.package/WAProfilerFilter.class/properties.json
index a9e7d30e1..e0e1e3755 100644
--- a/repository/Seaside-GemStone-Development.package/WAProfilerFilter.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAProfilerFilter.class/properties.json
@@ -1,14 +1,13 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WARequestFilter",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
- "items" ],
+ "items"
+ ],
"name" : "WAProfilerFilter",
- "pools" : [
- ],
- "super" : "WARequestFilter",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAProfilerItem.class/properties.json b/repository/Seaside-GemStone-Development.package/WAProfilerItem.class/properties.json
index 8521628e1..35db472bf 100644
--- a/repository/Seaside-GemStone-Development.package/WAProfilerItem.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAProfilerItem.class/properties.json
@@ -1,15 +1,14 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WAObject",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
"request",
- "profmonitor" ],
+ "profmonitor"
+ ],
"name" : "WAProfilerItem",
- "pools" : [
- ],
- "super" : "WAObject",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAProfilerTool.class/properties.json b/repository/Seaside-GemStone-Development.package/WAProfilerTool.class/properties.json
index 5e76c7441..a01acacae 100644
--- a/repository/Seaside-GemStone-Development.package/WAProfilerTool.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAProfilerTool.class/properties.json
@@ -1,16 +1,15 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WATool",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
"report",
"items",
- "message" ],
+ "message"
+ ],
"name" : "WAProfilerTool",
- "pools" : [
- ],
- "super" : "WATool",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WAProfilerToolPlugin.class/properties.json b/repository/Seaside-GemStone-Development.package/WAProfilerToolPlugin.class/properties.json
index 4e9661ef1..463e0fac5 100644
--- a/repository/Seaside-GemStone-Development.package/WAProfilerToolPlugin.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WAProfilerToolPlugin.class/properties.json
@@ -1,14 +1,13 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WAToolPlugin",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
- "filter" ],
+ "filter"
+ ],
"name" : "WAProfilerToolPlugin",
- "pools" : [
- ],
- "super" : "WAToolPlugin",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WARemoteDebuggingWalkback.class/properties.json b/repository/Seaside-GemStone-Development.package/WARemoteDebuggingWalkback.class/properties.json
index aa120c5da..c4fd6bc63 100644
--- a/repository/Seaside-GemStone-Development.package/WARemoteDebuggingWalkback.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WARemoteDebuggingWalkback.class/properties.json
@@ -1,15 +1,14 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "",
+ "super" : "WAGemStoneWalkback",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
"continuation",
- "logEntry" ],
+ "logEntry"
+ ],
"name" : "WARemoteDebuggingWalkback",
- "pools" : [
- ],
- "super" : "WAGemStoneWalkback",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/WARemoteDebuggingWalkbackErrorHandler.class/properties.json b/repository/Seaside-GemStone-Development.package/WARemoteDebuggingWalkbackErrorHandler.class/properties.json
index 814e6650f..cb8afc443 100644
--- a/repository/Seaside-GemStone-Development.package/WARemoteDebuggingWalkbackErrorHandler.class/properties.json
+++ b/repository/Seaside-GemStone-Development.package/WARemoteDebuggingWalkbackErrorHandler.class/properties.json
@@ -1,14 +1,13 @@
{
- "category" : "Seaside-GemStone-Development-Core",
- "classinstvars" : [
- ],
- "classvars" : [
- ],
"commentStamp" : "dkh 10/14/2011 13:56",
+ "super" : "WAGemStoneWalkbackErrorHandler",
+ "category" : "Seaside-GemStone-Development-Core",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
"instvars" : [
- "walkback" ],
+ "walkback"
+ ],
"name" : "WARemoteDebuggingWalkbackErrorHandler",
- "pools" : [
- ],
- "super" : "WAGemStoneWalkbackErrorHandler",
- "type" : "normal" }
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/monticello.meta/version b/repository/Seaside-GemStone-Development.package/monticello.meta/version
deleted file mode 100644
index 88f09544e..000000000
--- a/repository/Seaside-GemStone-Development.package/monticello.meta/version
+++ /dev/null
@@ -1 +0,0 @@
-(name 'Seaside-GemStone-Development-JohanBrichau.34' message 'Include change from https://github.com/GsDevKit/Seaside31/commit/ed70a052141d50b621c478e2e8db03398a627763' id '39a4a371-ee13-44d3-b200-efe28b1a7a0a' date '03/28/2016' time '08:02:00' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Development-dkh.33' message 'Issue #75: rename WAObjectLogDebuggerWalkback to WAGemStoneContinuationDebugger and move from package WAGemStoneContinuationDebugger to Seaside-GemStone-Development' id '75240d1f-c329-4ae5-aa39-e98dbabe485e' date '06/05/2015' time '15:50:49' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.32' message 'merged by GitFileTree-MergeDriver' id '1fc0f02a-64ef-4014-b6b3-63b25e3029f0' date '06/03/2015' time '09:52:19' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.31' message 'missing method for ajax error gem log logging' id '59e8a418-0f1e-4c48-978d-a499eddcd30e' date '06/02/2015' time '16:00:15' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.30' message 'log error stack to gem log when ajax error encountered' id '3c1ef174-98c2-40d8-877e-b29782b22c11' date '06/01/2015' time '09:43:47' author 'dkh' ancestors () stepChildren ())) stepChildren ())(name 'Seaside-GemStone-Development-MarianoMartinezPeck.31' message '* WAGemStoneStoneWalkback #initializeWithException: now delegates to a new method #initializeWithContext:
* WAGemStoneStoneWalkback #currentContextForWalkback now delegates to new #currentContextForContinuation:
* Added #stackReportLimit and #logContinuation to WARemoteDebuggingContinuation
* Make WARemoteDebuggingWalkbackErrorHandler #open to send logContinuation for ajax requests (ajax requests errors were not being written into the gem log until now).
' id 'ee4cc1d4-2e14-448d-b514-68ea11bde6e6' date '06/03/2015' time '10:29:53' author 'MarianoMartinezPeck' ancestors ((name 'Seaside-GemStone-Development-MarianoMartinezPeck.30' message '* WAGemStoneStoneWalkback #initializeWithException: now delegates to a new method #initializeWithContext:
* WAGemStoneStoneWalkback #currentContextForWalkback now delegates to new #currentContextForContinuation:
* Added #stackReportLimit and #logContinuation to WARemoteDebuggingContinuation
* Make WARemoteDebuggingWalkbackErrorHandler #open to send logContinuation for ajax requests (ajax requests errors were not being written into the gem log until now).
' id 'a8e3a43c-bdba-4640-ae81-79e6194feabe' date '06/03/2015' time '10:03:21' author 'MarianoMartinezPeck' ancestors ((name 'Seaside-GemStone-Development-dkh.29' message 'replace deprecated `currentRequest` with `requestContext request`' id '6f5ee0f4-e7f6-41f4-b523-09a1829df299' date '07/14/2014' time '17:03:19' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-JohanBrichau.28' message 'fixed reference to undefined symbol WARenderCanvas' id '69d50695-693b-4dd3-9582-e3cf4a3b4e2f' date '02/16/2014' time '01:28:48' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-Development-dkh.27' message '3.0.6.2 (dkh.346):
- WAHandleAbortWouldLoseDataToolFilter>>handleFiltered: transaction logic fixed' id 'f8635f5e-7aae-4d46-8ac0-ca01d266c126' date '10/19/2011' time '11:48:05' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.26' message '3.0.6.1 (dkh.339):
- back off a bit on the fix for Issue 130 ... make cross platform error handlers a little easier to manage' id 'd01f6719-4b82-4796-b6a4-78de26b1e6e0' date '10/14/2011' time '18:45:18' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.25' message '3.0.6.1 (dkh.338):
- GemStone 3.0.1 fix for Issue 130: remote breakpoints don''''t work
http://code.google.com/p/glassdb/issues/detail?id=130
' id '8d92fee3-15a5-4eec-ac0d-536d2ac882d4' date '10/14/2011' time '17:41:28' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.24' message '3.0.6.1 (dkh.337):
- fix Issue 130: remote breakpoints don''t work
http://code.google.com/p/glassdb/issues/detail?id=130' id '8d90f4df-5a59-4dcb-9838-aaf8a4cec76f' date '10/07/2011' time '16:55:17' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.23' message '- get Seaside3.0 running on GemStone3.0beta3
- ExceptionSet handling fixed in GemStone3.0, no longer need special version of Seaside-Core
- WAFlowPlatformTest>>testSuspendCallbackDo passes in GemStone3.0' id '236c3830-3b01-40e3-80ff-3488caae1a03' date '01/20/2011' time '11:03:12' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.22' message '- fix Issue 191: http://code.google.com/p/glassdb/issues/detail?id=191 "getting object log continuation for rest api calls"' id '187deabe-c263-4b38-961c-8d0471316f3f' date '12/13/2010' time '13:48:37' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.21' message '- fix Issue 170: http://code.google.com/p/glassdb/issues/detail?id=170 "Errors during Ajax requests can crash vm"
' id '5a5771bf-1460-4804-a952-428b6097545c' date '09/02/2010' time '15:08:53' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.20' message '- development Seaside3.0 workspace' id '51d244ad-2536-475b-b184-56331d813a9f' date '07/08/1910' time '16:06:30' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.19' message '- move #inspectorFields to Seaside-GemStone-Tools-Production' id 'f680454b-e4ba-417d-9d3a-90fc640253d1' date '07/06/1910' time '12:05:32' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.18' message '- move WaStringInspector to Seaside-GemStone-Tools-Production' id '7f2c708f-248e-4f41-8aff-9838836d41ad' date '07/06/1910' time '11:35:07' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.17' message '- move #canDebugInteractively to Environment (where it''s used)' id '36c30d07-705c-475a-ab74-13b678be42b8' date '06/25/1910' time '08:57:18' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.16' message '- remove WARemoteDebuggingProductionWalkback and WARemoteDebuggingProductionWalkbackErrorHandler in favor of WAGemStoneProductionErrorHandler in Seaside-GemStone-Environment' id 'b7e185ff-16d3-409c-841d-fe1d495a0757' date '06/24/1910' time '02:10:53' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.15' message '- add WARemoteDebuggingProductionWalkbackErrorHandler and WARemoteDebuggingProductionWalkback for production error handling
- clean up logging
- use #call: for opening Walkback component so that Proceed link works...
' id '44ccad39-109c-448f-85c9-45c4ee6e9d9c' date '06/21/1910' time '14:01:00' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.14' message '- support for handling Halt with remote debugger' id '382d224e-72c5-414a-be17-cf5c78c74c12' date '06/21/1910' time '13:22:56' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.13' message '- better string inspect support
- remote debugging support. Disable ''Proceed'' for remote debugging until Issue 128 is fixed (http://code.google.com/p/glassdb/issues/detail?id=128)
' id 'cdef77ec-7d47-4dfb-81d4-798b54bd548e' date '06/20/1910' time '16:06:56' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.12' message '- tool bar css needs to be defined for walkback error handling' id 'cb11119a-b9a1-4f45-8f4f-44c3a572af2d' date '06/19/1910' time '11:02:47' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.11' message '- don''t bother with a tool puglin for handling abort required in functional tests...' id '715c93c5-c6e7-4867-81fe-ef209d9ad3b8' date '06/18/1910' time '09:08:22' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-DaleHenrichs.10' message '- support for Grease 1.0-alpha9.3' id '14f8b3df-96b2-43ba-ad81-5e98a766911f' date '06/03/1910' time '14:45:08' author 'DaleHenrichs' ancestors ((name 'Seaside-GemStone-Development-dkh.9' message '- update GRPackage info' id '154e02b8-ba59-47a5-9407-64bbc1adf364' date '11/30/2009' time '16:44:26' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.8' message '- tool (WAHandleAbortWouldLoseDataToolFilter) to allow relatively safe use of #allInstances for GemStone (in functional tests at least)' id '5b6a14ca-e85a-4103-a92f-2b0bed5abdc7' date '11/25/2009' time '14:10:19' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.7' message '- move the workspace creation to WABasicDevelopment' id 'd601a1ae-7a64-41c4-b526-947b48767e33' date '11/17/2009' time '10:11:04' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.6' message '- update the workspace string' id '7c485b35-0ea1-4cc4-9b38-c2a7badffeb7' date '11/11/2009' time '11:16:34' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.5' message '- add a Seaside 3.0 workspace ' id '92f68997-b9a2-471d-b96f-5a3f470885c0' date '11/11/2009' time '10:39:48' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.4' message '- implement inspector and debugger' id 'd42ebfe9-680a-4cac-b91f-f988dd396d01' date '11/10/2009' time '15:41:53' author 'dkh' ancestors ((name 'Seaside-GemStone-Development-dkh.3' message '- get the package name spelling right - GemStone' id '0c4b50aa-1aeb-4668-96ed-350d0bf17df0' date '11/09/2009' time '13:00:08' author 'dkh' ancestors () stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())) stepChildren ())
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-Development.package/properties.json b/repository/Seaside-GemStone-Development.package/properties.json
index f037444a7..6f31cf5a2 100644
--- a/repository/Seaside-GemStone-Development.package/properties.json
+++ b/repository/Seaside-GemStone-Development.package/properties.json
@@ -1,2 +1 @@
-{
- }
+{ }
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-JSON-Core.package/.filetree b/repository/Seaside-GemStone-JSON-Core.package/.filetree
index 8998102c2..57a679737 100644
--- a/repository/Seaside-GemStone-JSON-Core.package/.filetree
+++ b/repository/Seaside-GemStone-JSON-Core.package/.filetree
@@ -1,4 +1,5 @@
{
- "noMethodMetaData" : true,
"separateMethodMetaAndSource" : false,
- "useCypressPropertiesFile" : true }
+ "noMethodMetaData" : true,
+ "useCypressPropertiesFile" : true
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-JSON-Core.package/BlockClosure.extension/properties.json b/repository/Seaside-GemStone-JSON-Core.package/BlockClosure.extension/properties.json
index 1d6f4884e..2190e5e29 100644
--- a/repository/Seaside-GemStone-JSON-Core.package/BlockClosure.extension/properties.json
+++ b/repository/Seaside-GemStone-JSON-Core.package/BlockClosure.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "BlockClosure" }
+ "name" : "BlockClosure"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-JSON-Core.package/CharacterCollection.extension/properties.json b/repository/Seaside-GemStone-JSON-Core.package/CharacterCollection.extension/properties.json
index c85a513c3..e95044552 100644
--- a/repository/Seaside-GemStone-JSON-Core.package/CharacterCollection.extension/properties.json
+++ b/repository/Seaside-GemStone-JSON-Core.package/CharacterCollection.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "CharacterCollection" }
+ "name" : "CharacterCollection"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-JSON-Core.package/ExecBlock.extension/properties.json b/repository/Seaside-GemStone-JSON-Core.package/ExecBlock.extension/properties.json
index d8195e286..6629ff4e0 100644
--- a/repository/Seaside-GemStone-JSON-Core.package/ExecBlock.extension/properties.json
+++ b/repository/Seaside-GemStone-JSON-Core.package/ExecBlock.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "ExecBlock" }
+ "name" : "ExecBlock"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-JSON-Core.package/SmallDouble.extension/properties.json b/repository/Seaside-GemStone-JSON-Core.package/SmallDouble.extension/properties.json
index f1677848d..275d24706 100644
--- a/repository/Seaside-GemStone-JSON-Core.package/SmallDouble.extension/properties.json
+++ b/repository/Seaside-GemStone-JSON-Core.package/SmallDouble.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "SmallDouble" }
+ "name" : "SmallDouble"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-JSON-Core.package/WAJsonCanvas.extension/properties.json b/repository/Seaside-GemStone-JSON-Core.package/WAJsonCanvas.extension/properties.json
index b8768a583..0bae6a260 100644
--- a/repository/Seaside-GemStone-JSON-Core.package/WAJsonCanvas.extension/properties.json
+++ b/repository/Seaside-GemStone-JSON-Core.package/WAJsonCanvas.extension/properties.json
@@ -1,2 +1,3 @@
{
- "name" : "WAJsonCanvas" }
+ "name" : "WAJsonCanvas"
+}
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-JSON-Core.package/monticello.meta/categories.st b/repository/Seaside-GemStone-JSON-Core.package/monticello.meta/categories.st
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-GemStone-JSON-Core.package/monticello.meta/version b/repository/Seaside-GemStone-JSON-Core.package/monticello.meta/version
deleted file mode 100644
index a4350716a..000000000
--- a/repository/Seaside-GemStone-JSON-Core.package/monticello.meta/version
+++ /dev/null
@@ -1 +0,0 @@
-(name 'Seaside-GemStone-JSON-Core-JohanBrichau.2' message 'added BlockClosure>>jsonOn:' id 'c25ac207-4617-4594-b561-4b274fda16e8' date '06/21/2014' time '02:29:22' author 'JohanBrichau' ancestors ((name 'Seaside-GemStone-JSON-Core-dkh.1' message 'merged Seaside-Core-pmm.806 to pick up Philippe''s latest ...
created Seaside-GemStone-JSON-Core
moved JSON methods from Javascript-GemStone-Core to Seaside-GemStone-JSON-Core
1199 run, 1195 passes, 0 expected defects, 1 failures, 3 errors, 0 unexpected passes' id 'c3511469-4d4f-472c-9df1-475164aef3b2' date '09/17/2013' time '05:20:56' author 'dkh' ancestors () stepChildren ())) stepChildren ())
\ No newline at end of file
diff --git a/repository/Seaside-GemStone-JSON-Core.package/properties.json b/repository/Seaside-GemStone-JSON-Core.package/properties.json
index f037444a7..6f31cf5a2 100644
--- a/repository/Seaside-GemStone-JSON-Core.package/properties.json
+++ b/repository/Seaside-GemStone-JSON-Core.package/properties.json
@@ -1,2 +1 @@
-{
- }
+{ }
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/.filetree b/repository/Seaside-HotwireTurbo-Examples.package/.filetree
new file mode 100644
index 000000000..57a679737
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/.filetree
@@ -0,0 +1,5 @@
+{
+ "separateMethodMetaAndSource" : false,
+ "noMethodMetaData" : true,
+ "useCypressPropertiesFile" : true
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/README.md b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/counter..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/counter..st
new file mode 100644
index 000000000..09d7d1113
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/counter..st
@@ -0,0 +1,4 @@
+accessing
+counter: aValue
+
+ counter := aValue
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/counter.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/counter.st
new file mode 100644
index 000000000..93f7267cd
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/counter.st
@@ -0,0 +1,4 @@
+accessing
+counter
+
+ ^ counter
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/decrease.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/decrease.st
new file mode 100644
index 000000000..175c972b4
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/decrease.st
@@ -0,0 +1,4 @@
+actions
+decrease
+
+ counter := counter - 1
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/increase.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/increase.st
new file mode 100644
index 000000000..41651014a
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/increase.st
@@ -0,0 +1,4 @@
+actions
+increase
+
+ counter := counter + 1
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/initialize.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/initialize.st
new file mode 100644
index 000000000..08a22894e
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/initialize.st
@@ -0,0 +1,5 @@
+initialization
+initialize
+
+ super initialize.
+ counter := 0
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/renderContentOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/renderContentOn..st
new file mode 100644
index 000000000..287aecf83
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/instance/renderContentOn..st
@@ -0,0 +1,11 @@
+rendering
+renderContentOn: html
+
+ html heading: counter.
+ html anchor
+ callback: [ self increase ];
+ with: '++'.
+ html space.
+ html anchor
+ callback: [ self decrease ];
+ with: '--'
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/properties.json b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/properties.json
new file mode 100644
index 000000000..fc644ef8c
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboCounter.class/properties.json
@@ -0,0 +1,13 @@
+{
+ "commentStamp" : "",
+ "super" : "WAComponent",
+ "category" : "Seaside-HotwireTurbo-Examples",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [
+ "counter"
+ ],
+ "name" : "WATurboCounter",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/README.md b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/class/canBeRoot.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/class/canBeRoot.st
new file mode 100644
index 000000000..2f51eea6e
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/class/canBeRoot.st
@@ -0,0 +1,3 @@
+testing
+canBeRoot
+ ^ true
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/class/register.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/class/register.st
new file mode 100644
index 000000000..f6d439852
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/class/register.st
@@ -0,0 +1,6 @@
+initialization
+register
+
+ (WAAdmin register: self asApplicationAt: '/examples/turbo/multicounter')
+ addLibrary: JQDevelopmentLibrary;
+ preferenceAt: #actionPhaseContinuationClass put: WATurboCallbackProcessingActionContinuation
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/children.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/children.st
new file mode 100644
index 000000000..d7403f0eb
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/children.st
@@ -0,0 +1,4 @@
+hooks
+children
+
+ ^ counters, { totals }
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/createTotalsPresenter.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/createTotalsPresenter.st
new file mode 100644
index 000000000..492046d9a
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/createTotalsPresenter.st
@@ -0,0 +1,7 @@
+private
+createTotalsPresenter
+
+ ^ (WAPluggablePresenter new block: [ :html |
+ html heading
+ level: 1;
+ with: (counters inject: 0 into:[ :total :c | c counter + total ]) ]) addDecoration: (WATurboFrame newWithId: 'id-total'); yourself
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/initialize.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/initialize.st
new file mode 100644
index 000000000..fa011ba54
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/initialize.st
@@ -0,0 +1,6 @@
+initialization
+initialize
+
+ super initialize.
+ counters := (1 to: 5) collect: [ :each | WATurboCounter new addDecoration: WATurboFrame new; yourself ].
+ totals := self createTotalsPresenter
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/renderContentOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/renderContentOn..st
new file mode 100644
index 000000000..7f3aa76a0
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/renderContentOn..st
@@ -0,0 +1,15 @@
+rendering
+renderContentOn: html
+
+ self renderTurboScriptOn: html.
+ counters
+ do: [ :each | html render: each ]
+ separatedBy: [ html horizontalRule ].
+ html
+ horizontalRule;
+ horizontalRule.
+ html heading
+ level: 3;
+ with: 'Total:'.
+ html render: totals.
+ self renderTotalAssignmentFormOn: html
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/renderTotalAssignmentFormOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/renderTotalAssignmentFormOn..st
new file mode 100644
index 000000000..113d90a73
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/renderTotalAssignmentFormOn..st
@@ -0,0 +1,11 @@
+rendering
+renderTotalAssignmentFormOn: html
+
+ | theValue |
+ html form
+ turboStreamCallback: [ :ts | ts replace: 'id-total' with: totals ];
+ with: [
+ html textInput
+ callback: [ :value | theValue := value ].
+ html submitButton
+ callback: [ self setCountersTo: theValue ] ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/renderTurboScriptOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/renderTurboScriptOn..st
new file mode 100644
index 000000000..444dd5f7b
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/renderTurboScriptOn..st
@@ -0,0 +1,7 @@
+rendering
+renderTurboScriptOn: html
+
+ html script
+ type: 'module';
+ "with:'import hotwiredTurbo from ''https://cdn.skypack.dev/@hotwired/turbo'';'"
+ with: 'import * as Turbo from ''',(WATurboFileLibrary / #turboes2017esmJs) greaseString,''';'
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/setCountersTo..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/setCountersTo..st
new file mode 100644
index 000000000..98c7f28ae
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/setCountersTo..st
@@ -0,0 +1,6 @@
+actions
+setCountersTo: aValue
+
+ | theValue |
+ theValue := Integer readFrom: aValue ifFail: [ 0 ].
+ counters do: [ :each | each counter: theValue ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/states.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/states.st
new file mode 100644
index 000000000..f1009cd1c
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/instance/states.st
@@ -0,0 +1,4 @@
+hooks
+states
+
+ ^ #()
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/properties.json b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/properties.json
new file mode 100644
index 000000000..db8c5c76d
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboMultiCounter.class/properties.json
@@ -0,0 +1,14 @@
+{
+ "commentStamp" : "",
+ "super" : "WAComponent",
+ "category" : "Seaside-HotwireTurbo-Examples",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [
+ "counters",
+ "totals"
+ ],
+ "name" : "WATurboMultiCounter",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/README.md b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/class/canBeRoot.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/class/canBeRoot.st
new file mode 100644
index 000000000..2f51eea6e
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/class/canBeRoot.st
@@ -0,0 +1,3 @@
+testing
+canBeRoot
+ ^ true
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/class/register.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/class/register.st
new file mode 100644
index 000000000..3218caaa0
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/class/register.st
@@ -0,0 +1,7 @@
+initialization
+register
+
+ (WAAdmin register: self asApplicationAt: '/examples/turbo/todo')
+ exceptionHandler: WADebugErrorHandler;
+ addLibrary: WAExamplesLibrary;
+ preferenceAt: #actionPhaseContinuationClass put: WATurboCallbackProcessingActionContinuation
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/addTodo..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/addTodo..st
new file mode 100644
index 000000000..f7f610aaf
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/addTodo..st
@@ -0,0 +1,8 @@
+actions
+addTodo: aString
+
+ | newTodo |
+ newTodo := WATurboTodoItem newWithDescription: aString in: todos.
+ newTodo addDecoration: WATurboFrame new.
+ todos add: newTodo.
+ ^ newTodo
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/children.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/children.st
new file mode 100644
index 000000000..0532f19d9
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/children.st
@@ -0,0 +1,4 @@
+accessing
+children
+
+ ^ self todos
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/initialize.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/initialize.st
new file mode 100644
index 000000000..c07170a74
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/initialize.st
@@ -0,0 +1,7 @@
+initialization
+initialize
+
+ super initialize.
+ todos := OrderedCollection new.
+ 1 to: 10 do: [ :index |
+ self addTodo: ('Task {1}' format: { index greaseString }) ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderAddNewTodoOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderAddNewTodoOn..st
new file mode 100644
index 000000000..c3a3290d1
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderAddNewTodoOn..st
@@ -0,0 +1,17 @@
+rendering
+renderAddNewTodoOn: html
+
+ | newTodo |
+ html form
+ id: 'new-todo-form';
+ turboStreamCallback: [ :ts |
+ ts
+ append: 'todo-list' with: newTodo;
+ replace: 'new-todo-form' with: [ :r | self renderAddNewTodoOn: r ] ];
+ with: [
+ html textInput
+ id: 'new-todo';
+ autofocus;
+ noAutocomplete;
+ callback: [ :value | newTodo := self addTodo: value ];
+ placeholder: 'What needs to be done?' ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderContentOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderContentOn..st
new file mode 100644
index 000000000..d58e020c4
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderContentOn..st
@@ -0,0 +1,10 @@
+rendering
+renderContentOn: html
+
+ self renderTurboScriptOn: html.
+ html section
+ id: #todoapp;
+ with: [
+ self renderHeaderWithAddTodoOn: html.
+ self renderTodosOn: html.
+ self renderFooterOn: html ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderFooterOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderFooterOn..st
new file mode 100644
index 000000000..3112dda1f
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderFooterOn..st
@@ -0,0 +1,9 @@
+rendering
+renderFooterOn: html
+
+ html footer
+ id: #footer;
+ with: [
+ html span
+ id: #'todo-count';
+ with: todos size ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderHeaderWithAddTodoOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderHeaderWithAddTodoOn..st
new file mode 100644
index 000000000..bf1e56649
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderHeaderWithAddTodoOn..st
@@ -0,0 +1,10 @@
+rendering
+renderHeaderWithAddTodoOn: html
+
+ html header
+ id: #header;
+ with: [
+ html heading
+ level: 1;
+ with: 'todos'.
+ self renderAddNewTodoOn: html ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderTodosOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderTodosOn..st
new file mode 100644
index 000000000..fd6f11c5e
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderTodosOn..st
@@ -0,0 +1,14 @@
+rendering
+renderTodosOn: html
+
+ html section
+ id: 'main';
+ with: [
+ html checkbox
+ id: 'toggle-all'.
+ html label
+ for: 'toggle-all';
+ with: 'Mark all as complete'.
+ html unorderedList
+ id: 'todo-list';
+ with: [ self todos do: [ :todoItem | todoItem renderOn: html ] ] ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderTurboScriptOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderTurboScriptOn..st
new file mode 100644
index 000000000..0b899f23d
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/renderTurboScriptOn..st
@@ -0,0 +1,7 @@
+rendering
+renderTurboScriptOn: html
+
+ html script
+ type: 'module';
+ "with:'import hotwiredTurbo from ''https://cdn.skypack.dev/@hotwired/turbo'';'"
+ with: 'import * as Turbo from ''',(WATurboFileLibrary / #turboes2017esmJs) greaseString,''';'
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/todos.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/todos.st
new file mode 100644
index 000000000..787cbff0b
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/todos.st
@@ -0,0 +1,4 @@
+accessing
+todos
+
+ ^ todos
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/updateRoot..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/updateRoot..st
new file mode 100644
index 000000000..80a9df22a
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/instance/updateRoot..st
@@ -0,0 +1,6 @@
+rendering
+updateRoot: aRoot
+
+ super updateRoot: aRoot.
+ aRoot title: 'Seaside-Turbo Todo Demo'.
+ aRoot stylesheet url: WAExamplesLibrary / #todoCss
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/properties.json b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/properties.json
new file mode 100644
index 000000000..9074d1652
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodo.class/properties.json
@@ -0,0 +1,13 @@
+{
+ "commentStamp" : "",
+ "super" : "WAExampleComponent",
+ "category" : "Seaside-HotwireTurbo-Examples",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [
+ "todos"
+ ],
+ "name" : "WATurboTodo",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/README.md b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/class/newWithDescription.in..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/class/newWithDescription.in..st
new file mode 100644
index 000000000..544869ab4
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/class/newWithDescription.in..st
@@ -0,0 +1,3 @@
+instance creation
+newWithDescription: aString in: aCollection
+ ^ self new initializeWithDescription: aString in: aCollection
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/description..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/description..st
new file mode 100644
index 000000000..24c97bebc
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/description..st
@@ -0,0 +1,3 @@
+accessing
+description: anObject
+ description := anObject
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/description.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/description.st
new file mode 100644
index 000000000..c5ddedef1
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/description.st
@@ -0,0 +1,3 @@
+accessing
+description
+ ^ description
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/done..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/done..st
new file mode 100644
index 000000000..d0c44d461
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/done..st
@@ -0,0 +1,3 @@
+accessing
+done: anObject
+ done := anObject
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/done.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/done.st
new file mode 100644
index 000000000..a14b18f11
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/done.st
@@ -0,0 +1,3 @@
+accessing
+done
+ ^ done
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/initializeWithDescription.in..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/initializeWithDescription.in..st
new file mode 100644
index 000000000..84ff2e7bf
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/initializeWithDescription.in..st
@@ -0,0 +1,7 @@
+initialization
+initializeWithDescription: aString in: aCollection
+ self initialize.
+ self done: false.
+ self description: aString.
+ editmode := false.
+ todos := aCollection
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/remove.st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/remove.st
new file mode 100644
index 000000000..0d5ce0b36
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/remove.st
@@ -0,0 +1,4 @@
+private
+remove
+
+ todos remove: self
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderCheckBoxIn.on..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderCheckBoxIn.on..st
new file mode 100644
index 000000000..f50ed10c9
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderCheckBoxIn.on..st
@@ -0,0 +1,11 @@
+rendering
+renderCheckBoxIn: id on: html
+
+ html form
+ turboStreamCallback: [ :ts | ts update: id with: self ];
+ with: [
+ html checkbox
+ class: 'toggle';
+ callback: [ :value | self done: value ];
+ onChange: (html javascript: 'this.form.requestSubmit()');
+ value: done ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderContentOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderContentOn..st
new file mode 100644
index 000000000..85b67ed4b
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderContentOn..st
@@ -0,0 +1,14 @@
+rendering
+renderContentOn: html
+
+ | id |
+ html listItem
+ id: (id := html nextId);
+ onDoubleClick: (html javascript turboCallback: [ self turboCall: (WATurboTodoItemEditor on: self) ]);
+ with: [
+ html div
+ class: 'view';
+ with:[
+ self renderCheckBoxIn: id on: html.
+ self renderDescriptionOn: html.
+ self renderDestroyerOn: html ] ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderDescriptionOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderDescriptionOn..st
new file mode 100644
index 000000000..16ed768ee
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderDescriptionOn..st
@@ -0,0 +1,8 @@
+rendering
+renderDescriptionOn: html
+
+ html label: description.
+ html anchor
+ class: 'edit-link';
+ callback: [ self turboCall: (WATurboTodoItemEditor on: self) ];
+ with: 'edit'
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderDestroyerOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderDestroyerOn..st
new file mode 100644
index 000000000..50cdfed4d
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/instance/renderDestroyerOn..st
@@ -0,0 +1,7 @@
+rendering
+renderDestroyerOn: html
+
+ html form: [
+ html button
+ class: 'destroy';
+ turboStreamCallback: [ :ts | self remove. ts removeComponent: self ] ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/properties.json b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/properties.json
new file mode 100644
index 000000000..d99d1685b
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItem.class/properties.json
@@ -0,0 +1,16 @@
+{
+ "commentStamp" : "",
+ "super" : "WAComponent",
+ "category" : "Seaside-HotwireTurbo-Examples",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [
+ "todos",
+ "description",
+ "done",
+ "editmode"
+ ],
+ "name" : "WATurboTodoItem",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/README.md b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/class/on..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/class/on..st
new file mode 100644
index 000000000..4d174a81a
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/class/on..st
@@ -0,0 +1,4 @@
+instance creation
+on: aWATodoItem
+
+ ^ self basicNew initializeOn: aWATodoItem
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/instance/initializeOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/instance/initializeOn..st
new file mode 100644
index 000000000..391b7dc5c
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/instance/initializeOn..st
@@ -0,0 +1,5 @@
+initialization
+initializeOn: aWATodoItem
+
+ self initialize.
+ todoItem := aWATodoItem
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/instance/renderContentOn..st b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/instance/renderContentOn..st
new file mode 100644
index 000000000..82c0663cd
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/instance/renderContentOn..st
@@ -0,0 +1,11 @@
+rendering
+renderContentOn: html
+
+ html form: [
+ html textInput
+ class: 'edit';
+ callback: [ :value | todoItem description: value ];
+ value: todoItem description.
+ html submitButton
+ style: 'display:none';
+ callback: [ self answer ] ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/properties.json b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/properties.json
new file mode 100644
index 000000000..b48f737db
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/WATurboTodoItemEditor.class/properties.json
@@ -0,0 +1,13 @@
+{
+ "commentStamp" : "",
+ "super" : "WAComponent",
+ "category" : "Seaside-HotwireTurbo-Examples",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [
+ "todoItem"
+ ],
+ "name" : "WATurboTodoItemEditor",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/monticello.meta/categories.st b/repository/Seaside-HotwireTurbo-Examples.package/monticello.meta/categories.st
new file mode 100644
index 000000000..2f4aea817
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/monticello.meta/categories.st
@@ -0,0 +1 @@
+SystemOrganization addCategory: #'Seaside-HotwireTurbo-Examples'!
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/monticello.meta/initializers.st b/repository/Seaside-HotwireTurbo-Examples.package/monticello.meta/initializers.st
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/monticello.meta/package b/repository/Seaside-HotwireTurbo-Examples.package/monticello.meta/package
new file mode 100644
index 000000000..fc70e5ab2
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/monticello.meta/package
@@ -0,0 +1 @@
+(name 'Seaside-HotwireTurbo-Examples')
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo-Examples.package/properties.json b/repository/Seaside-HotwireTurbo-Examples.package/properties.json
new file mode 100644
index 000000000..6f31cf5a2
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo-Examples.package/properties.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/.filetree b/repository/Seaside-HotwireTurbo.package/.filetree
new file mode 100644
index 000000000..57a679737
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/.filetree
@@ -0,0 +1,5 @@
+{
+ "separateMethodMetaAndSource" : false,
+ "noMethodMetaData" : true,
+ "useCypressPropertiesFile" : true
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/JSScript.extension/instance/turbo.st b/repository/Seaside-HotwireTurbo.package/JSScript.extension/instance/turbo.st
new file mode 100644
index 000000000..94b9c4739
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/JSScript.extension/instance/turbo.st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+turbo
+
+ ^ (JSStream on: 'Turbo')
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/JSScript.extension/instance/turboCallback..st b/repository/Seaside-HotwireTurbo.package/JSScript.extension/instance/turboCallback..st
new file mode 100644
index 000000000..92f90a32a
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/JSScript.extension/instance/turboCallback..st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+turboCallback: aNiladicValuable
+
+ self turboCallback: aNiladicValuable target: (JSStream on: 'this.closest(''turbo-frame'').id')
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/JSScript.extension/instance/turboCallback.target..st b/repository/Seaside-HotwireTurbo.package/JSScript.extension/instance/turboCallback.target..st
new file mode 100644
index 000000000..7f4566eb6
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/JSScript.extension/instance/turboCallback.target..st
@@ -0,0 +1,11 @@
+*Seaside-HotwireTurbo
+turboCallback: aNiladicValuable target: frameId
+
+ self add:
+ (self turbo call: 'visit' withArguments: {
+ (self renderContext actionUrl withField:
+ (self renderContext callbacks store: (WAActionCallback on: aNiladicValuable))).
+ (Dictionary new
+ add: 'action' -> 'replace';
+ add: 'frame' -> frameId;
+ yourself) })
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/JSScript.extension/properties.json b/repository/Seaside-HotwireTurbo.package/JSScript.extension/properties.json
new file mode 100644
index 000000000..753ae426e
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/JSScript.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "JSScript"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/instance/turbo..st b/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/instance/turbo..st
new file mode 100644
index 000000000..c9b4d1cdf
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/instance/turbo..st
@@ -0,0 +1,6 @@
+*Seaside-HotwireTurbo
+turbo: aBoolean
+
+ "data-turbo=""false"" disables Turbo Drive on links and forms including descendants. To reenable when an ancestor has opted out, use data-turbo=""true"". Be careful: when Turbo Drive is disabled, browsers treat link clicks as normal, but native adapters may exit the app."
+
+ self dataAttributeAt: 'turbo' put: aBoolean
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/instance/turboAction..st b/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/instance/turboAction..st
new file mode 100644
index 000000000..90c8fd65b
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/instance/turboAction..st
@@ -0,0 +1,6 @@
+*Seaside-HotwireTurbo
+turboAction: aString
+
+ (#('replace' 'advance') includes: aString) ifFalse: [
+ self error: 'Argument for turboAction must be either ''replace'' or ''advance''.' ].
+ self dataAttributeAt: 'turbo-action' put: aString
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/instance/turboTarget..st b/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/instance/turboTarget..st
new file mode 100644
index 000000000..0575ff01f
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/instance/turboTarget..st
@@ -0,0 +1,6 @@
+*Seaside-HotwireTurbo
+turboTarget: aString
+
+ "data-turbo-frame identifies the Turbo Frame to navigate. Refer to the Frames documentation for further details."
+
+ self dataAttributeAt: 'turbo-frame' put: aString
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/properties.json
new file mode 100644
index 000000000..ee770b478
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAAnchorTag.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WAAnchorTag"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WABasicFormTag.extension/instance/turboStreamCallback..st b/repository/Seaside-HotwireTurbo.package/WABasicFormTag.extension/instance/turboStreamCallback..st
new file mode 100644
index 000000000..41d5a5025
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WABasicFormTag.extension/instance/turboStreamCallback..st
@@ -0,0 +1,6 @@
+*Seaside-HotwireTurbo
+turboStreamCallback: aValuable
+
+ self action:
+ ((self attributeAt: 'action') copy addField: (self storeCallback:
+ ((WATurboStreamCallback on: aValuable) context: canvas context)))
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WABasicFormTag.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WABasicFormTag.extension/properties.json
new file mode 100644
index 000000000..62f612fb2
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WABasicFormTag.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WABasicFormTag"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAButtonTag.extension/instance/turboStreamCallback..st b/repository/Seaside-HotwireTurbo.package/WAButtonTag.extension/instance/turboStreamCallback..st
new file mode 100644
index 000000000..903a58041
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAButtonTag.extension/instance/turboStreamCallback..st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+turboStreamCallback: aValuable
+
+ self name: (self storeCallback: ((WATurboStreamCallback on: aValuable) context: canvas context))
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAButtonTag.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WAButtonTag.extension/properties.json
new file mode 100644
index 000000000..ce95d022e
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAButtonTag.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WAButtonTag"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WACallback.extension/instance/isTurboStreamCallback.st b/repository/Seaside-HotwireTurbo.package/WACallback.extension/instance/isTurboStreamCallback.st
new file mode 100644
index 000000000..d7aaca6ba
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WACallback.extension/instance/isTurboStreamCallback.st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+isTurboStreamCallback
+
+ ^ false
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WACallback.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WACallback.extension/properties.json
new file mode 100644
index 000000000..a916301d5
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WACallback.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WACallback"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WACallbackRegistry.extension/instance/findTurboStreamCallbackIn..st b/repository/Seaside-HotwireTurbo.package/WACallbackRegistry.extension/instance/findTurboStreamCallbackIn..st
new file mode 100644
index 000000000..49ce9123a
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WACallbackRegistry.extension/instance/findTurboStreamCallbackIn..st
@@ -0,0 +1,8 @@
+*Seaside-HotwireTurbo
+findTurboStreamCallbackIn: aRequest
+
+ aRequest fields keysDo: [ :key |
+ callbacks at: key ifPresent: [ :callback |
+ callback isTurboStreamCallback
+ ifTrue: [ ^ callback ] ] ].
+ ^ nil
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WACallbackRegistry.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WACallbackRegistry.extension/properties.json
new file mode 100644
index 000000000..addcfdaac
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WACallbackRegistry.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WACallbackRegistry"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAComponent.extension/instance/turboCall..st b/repository/Seaside-HotwireTurbo.package/WAComponent.extension/instance/turboCall..st
new file mode 100644
index 000000000..a4cc89621
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAComponent.extension/instance/turboCall..st
@@ -0,0 +1,5 @@
+*Seaside-HotwireTurbo
+turboCall: aComponent
+
+ aComponent addDecoration: (WATurboFrame newWithId: self turboframeDecoration id).
+ ^ self call: aComponent
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAComponent.extension/instance/turboframeDecoration.st b/repository/Seaside-HotwireTurbo.package/WAComponent.extension/instance/turboframeDecoration.st
new file mode 100644
index 000000000..17ecda7c5
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAComponent.extension/instance/turboframeDecoration.st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+turboframeDecoration
+
+ ^ self decorations detect:[ :dec | dec isTurboFrame ] ifNone: [ nil ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAComponent.extension/instance/turboframeId.st b/repository/Seaside-HotwireTurbo.package/WAComponent.extension/instance/turboframeId.st
new file mode 100644
index 000000000..cfbb355ba
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAComponent.extension/instance/turboframeId.st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+turboframeId
+
+ ^ self turboframeDecoration id
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAComponent.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WAComponent.extension/properties.json
new file mode 100644
index 000000000..94b6f7e9d
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAComponent.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WAComponent"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WADecoration.extension/instance/isTurboFrame.st b/repository/Seaside-HotwireTurbo.package/WADecoration.extension/instance/isTurboFrame.st
new file mode 100644
index 000000000..ff5dbb5a0
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WADecoration.extension/instance/isTurboFrame.st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+isTurboFrame
+
+ ^ false
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WADecoration.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WADecoration.extension/properties.json
new file mode 100644
index 000000000..dc003ef86
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WADecoration.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WADecoration"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAMimeType.extension/class/textVndTurboStreamHtml.st b/repository/Seaside-HotwireTurbo.package/WAMimeType.extension/class/textVndTurboStreamHtml.st
new file mode 100644
index 000000000..511839b0a
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAMimeType.extension/class/textVndTurboStreamHtml.st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+textVndTurboStreamHtml
+
+ ^ self main: 'text' sub: 'vnd.turbo-stream.html'
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WAMimeType.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WAMimeType.extension/properties.json
new file mode 100644
index 000000000..c386a6198
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WAMimeType.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WAMimeType"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WARenderContext.extension/instance/visitor.during..st b/repository/Seaside-HotwireTurbo.package/WARenderContext.extension/instance/visitor.during..st
new file mode 100644
index 000000000..33fe71b9d
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WARenderContext.extension/instance/visitor.during..st
@@ -0,0 +1,8 @@
+*Seaside-HotwireTurbo
+visitor: aVisitor during: aBlock
+ "Set the value of visitor for the duration of aBlock"
+ | previous |
+ previous := visitor.
+ [ visitor := aVisitor.
+ aBlock value ]
+ ensure: [ visitor := previous ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WARenderContext.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WARenderContext.extension/properties.json
new file mode 100644
index 000000000..469a80759
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WARenderContext.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WARenderContext"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WARequest.extension/instance/isTurboFrameRequest.st b/repository/Seaside-HotwireTurbo.package/WARequest.extension/instance/isTurboFrameRequest.st
new file mode 100644
index 000000000..473d46471
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WARequest.extension/instance/isTurboFrameRequest.st
@@ -0,0 +1,3 @@
+*Seaside-HotwireTurbo
+isTurboFrameRequest
+ ^ (self headerAt: 'turbo-frame') notNil
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WARequest.extension/instance/isTurboStreamRequest.st b/repository/Seaside-HotwireTurbo.package/WARequest.extension/instance/isTurboStreamRequest.st
new file mode 100644
index 000000000..4a782bc20
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WARequest.extension/instance/isTurboStreamRequest.st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+isTurboStreamRequest
+
+ ^ self accept anySatisfy: [ :accept | accept value = WAMimeType textVndTurboStreamHtml ]
diff --git a/repository/Seaside-HotwireTurbo.package/WARequest.extension/instance/turboStreamCallbackIn..st b/repository/Seaside-HotwireTurbo.package/WARequest.extension/instance/turboStreamCallbackIn..st
new file mode 100644
index 000000000..973288b0e
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WARequest.extension/instance/turboStreamCallbackIn..st
@@ -0,0 +1,10 @@
+*Seaside-HotwireTurbo
+turboStreamCallbackIn: aRenderContext
+
+ | callbacks |
+ callbacks := aRenderContext callbacks.
+ self fields keysDo: [ :key |
+ callbacks at: key ifPresent: [ :callback |
+ callback isTurboStreamCallback
+ ifTrue: [ ^ callback ] ] ].
+ ^ nil
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WARequest.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WARequest.extension/properties.json
new file mode 100644
index 000000000..487b10fd3
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WARequest.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WARequest"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WASubmitButtonTag.extension/instance/turboStreamCallback..st b/repository/Seaside-HotwireTurbo.package/WASubmitButtonTag.extension/instance/turboStreamCallback..st
new file mode 100644
index 000000000..903a58041
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WASubmitButtonTag.extension/instance/turboStreamCallback..st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+turboStreamCallback: aValuable
+
+ self name: (self storeCallback: ((WATurboStreamCallback on: aValuable) context: canvas context))
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WASubmitButtonTag.extension/instance/turboTarget..st b/repository/Seaside-HotwireTurbo.package/WASubmitButtonTag.extension/instance/turboTarget..st
new file mode 100644
index 000000000..69d48c541
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WASubmitButtonTag.extension/instance/turboTarget..st
@@ -0,0 +1,4 @@
+*Seaside-HotwireTurbo
+turboTarget: aString
+
+ self dataAttributeAt: 'turbo-frame' put: aString
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WASubmitButtonTag.extension/properties.json b/repository/Seaside-HotwireTurbo.package/WASubmitButtonTag.extension/properties.json
new file mode 100644
index 000000000..717195ed5
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WASubmitButtonTag.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WASubmitButtonTag"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/README.md b/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/instance/continue.st b/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/instance/continue.st
new file mode 100644
index 000000000..cdf97915e
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/instance/continue.st
@@ -0,0 +1,11 @@
+processing
+continue
+
+ | renderContinuation |
+ (self requestContext request isTurboFrameRequest or: [ self requestContext request isTurboStreamRequest ])
+ ifTrue: [
+ "TODO: perhaps it's better to have a different rendercontinuation class for rendering a turboframe vs rendering a turbostream"
+ renderContinuation := self createTurboRenderContinuation.
+ self redirectToContinuation: renderContinuation.
+ ^ self ]
+ ifFalse: [ super continue ]
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/instance/createTurboRenderContinuation.st b/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/instance/createTurboRenderContinuation.st
new file mode 100644
index 000000000..8c0e41d18
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/instance/createTurboRenderContinuation.st
@@ -0,0 +1,7 @@
+private
+createTurboRenderContinuation
+
+ | renderContinuation |
+ renderContinuation := WATurboRenderPhaseContinuation new.
+ renderContinuation prepareWithRenderContext: renderContext.
+ ^ renderContinuation
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/properties.json b/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/properties.json
new file mode 100644
index 000000000..d8e2cb441
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WATurboCallbackProcessingActionContinuation.class/properties.json
@@ -0,0 +1,11 @@
+{
+ "commentStamp" : "",
+ "super" : "WACallbackProcessingActionContinuation",
+ "category" : "Seaside-HotwireTurbo",
+ "classinstvars" : [ ],
+ "pools" : [ ],
+ "classvars" : [ ],
+ "instvars" : [ ],
+ "name" : "WATurboCallbackProcessingActionContinuation",
+ "type" : "normal"
+}
\ No newline at end of file
diff --git a/repository/Seaside-HotwireTurbo.package/WATurboFileLibrary.class/README.md b/repository/Seaside-HotwireTurbo.package/WATurboFileLibrary.class/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-HotwireTurbo.package/WATurboFileLibrary.class/instance/turboes2017esmJs.st b/repository/Seaside-HotwireTurbo.package/WATurboFileLibrary.class/instance/turboes2017esmJs.st
new file mode 100644
index 000000000..a3ba2fbf1
--- /dev/null
+++ b/repository/Seaside-HotwireTurbo.package/WATurboFileLibrary.class/instance/turboes2017esmJs.st
@@ -0,0 +1,3972 @@
+uploaded
+turboes2017esmJs
+ ^ '/*
+Turbo 7.3.0
+Copyright © 2023 37signals LLC
+ */
+(function () {
+ if (window.Reflect === undefined ||
+ window.customElements === undefined ||
+ window.customElements.polyfillWrapFlushCallback) {
+ return;
+ }
+ const BuiltInHTMLElement = HTMLElement;
+ const wrapperForTheName = {
+ HTMLElement: function HTMLElement() {
+ return Reflect.construct(BuiltInHTMLElement, [], this.constructor);
+ },
+ };
+ window.HTMLElement = wrapperForTheName["HTMLElement"];
+ HTMLElement.prototype = BuiltInHTMLElement.prototype;
+ HTMLElement.prototype.constructor = HTMLElement;
+ Object.setPrototypeOf(HTMLElement, BuiltInHTMLElement);
+})();
+
+/**
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Javan Makhmali
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+(function(prototype) {
+ if (typeof prototype.requestSubmit == "function") return
+
+ prototype.requestSubmit = function(submitter) {
+ if (submitter) {
+ validateSubmitter(submitter, this);
+ submitter.click();
+ } else {
+ submitter = document.createElement("input");
+ submitter.type = "submit";
+ submitter.hidden = true;
+ this.appendChild(submitter);
+ submitter.click();
+ this.removeChild(submitter);
+ }
+ };
+
+ function validateSubmitter(submitter, form) {
+ submitter instanceof HTMLElement || raise(TypeError, "parameter 1 is not of type ''HTMLElement''");
+ submitter.type == "submit" || raise(TypeError, "The specified element is not a submit button");
+ submitter.form == form || raise(DOMException, "The specified element is not owned by this form element", "NotFoundError");
+ }
+
+ function raise(errorConstructor, message, name) {
+ throw new errorConstructor("Failed to execute ''requestSubmit'' on ''HTMLFormElement'': " + message + ".", name)
+ }
+})(HTMLFormElement.prototype);
+
+const submittersByForm = new WeakMap();
+function findSubmitterFromClickTarget(target) {
+ const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
+ const candidate = element ? element.closest("input, button") : null;
+ return (candidate === null || candidate === void 0 ? void 0 : candidate.type) == "submit" ? candidate : null;
+}
+function clickCaptured(event) {
+ const submitter = findSubmitterFromClickTarget(event.target);
+ if (submitter && submitter.form) {
+ submittersByForm.set(submitter.form, submitter);
+ }
+}
+(function () {
+ if ("submitter" in Event.prototype)
+ return;
+ let prototype = window.Event.prototype;
+ if ("SubmitEvent" in window && /Apple Computer/.test(navigator.vendor)) {
+ prototype = window.SubmitEvent.prototype;
+ }
+ else if ("SubmitEvent" in window) {
+ return;
+ }
+ addEventListener("click", clickCaptured, true);
+ Object.defineProperty(prototype, "submitter", {
+ get() {
+ if (this.type == "submit" && this.target instanceof HTMLFormElement) {
+ return submittersByForm.get(this.target);
+ }
+ },
+ });
+})();
+
+var FrameLoadingStyle;
+(function (FrameLoadingStyle) {
+ FrameLoadingStyle["eager"] = "eager";
+ FrameLoadingStyle["lazy"] = "lazy";
+})(FrameLoadingStyle || (FrameLoadingStyle = {}));
+class FrameElement extends HTMLElement {
+ static get observedAttributes() {
+ return ["disabled", "complete", "loading", "src"];
+ }
+ constructor() {
+ super();
+ this.loaded = Promise.resolve();
+ this.delegate = new FrameElement.delegateConstructor(this);
+ }
+ connectedCallback() {
+ this.delegate.connect();
+ }
+ disconnectedCallback() {
+ this.delegate.disconnect();
+ }
+ reload() {
+ return this.delegate.sourceURLReloaded();
+ }
+ attributeChangedCallback(name) {
+ if (name == "loading") {
+ this.delegate.loadingStyleChanged();
+ }
+ else if (name == "complete") {
+ this.delegate.completeChanged();
+ }
+ else if (name == "src") {
+ this.delegate.sourceURLChanged();
+ }
+ else {
+ this.delegate.disabledChanged();
+ }
+ }
+ get src() {
+ return this.getAttribute("src");
+ }
+ set src(value) {
+ if (value) {
+ this.setAttribute("src", value);
+ }
+ else {
+ this.removeAttribute("src");
+ }
+ }
+ get loading() {
+ return frameLoadingStyleFromString(this.getAttribute("loading") || "");
+ }
+ set loading(value) {
+ if (value) {
+ this.setAttribute("loading", value);
+ }
+ else {
+ this.removeAttribute("loading");
+ }
+ }
+ get disabled() {
+ return this.hasAttribute("disabled");
+ }
+ set disabled(value) {
+ if (value) {
+ this.setAttribute("disabled", "");
+ }
+ else {
+ this.removeAttribute("disabled");
+ }
+ }
+ get autoscroll() {
+ return this.hasAttribute("autoscroll");
+ }
+ set autoscroll(value) {
+ if (value) {
+ this.setAttribute("autoscroll", "");
+ }
+ else {
+ this.removeAttribute("autoscroll");
+ }
+ }
+ get complete() {
+ return !this.delegate.isLoading;
+ }
+ get isActive() {
+ return this.ownerDocument === document && !this.isPreview;
+ }
+ get isPreview() {
+ var _a, _b;
+ return (_b = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.documentElement) === null || _b === void 0 ? void 0 : _b.hasAttribute("data-turbo-preview");
+ }
+}
+function frameLoadingStyleFromString(style) {
+ switch (style.toLowerCase()) {
+ case "lazy":
+ return FrameLoadingStyle.lazy;
+ default:
+ return FrameLoadingStyle.eager;
+ }
+}
+
+function expandURL(locatable) {
+ return new URL(locatable.toString(), document.baseURI);
+}
+function getAnchor(url) {
+ let anchorMatch;
+ if (url.hash) {
+ return url.hash.slice(1);
+ }
+ else if ((anchorMatch = url.href.match(/#(.*)$/))) {
+ return anchorMatch[1];
+ }
+}
+function getAction(form, submitter) {
+ const action = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formaction")) || form.getAttribute("action") || form.action;
+ return expandURL(action);
+}
+function getExtension(url) {
+ return (getLastPathComponent(url).match(/\.[^.]*$/) || [])[0] || "";
+}
+function isHTML(url) {
+ return !!getExtension(url).match(/^(?:|\.(?:htm|html|xhtml|php))$/);
+}
+function isPrefixedBy(baseURL, url) {
+ const prefix = getPrefix(url);
+ return baseURL.href === expandURL(prefix).href || baseURL.href.startsWith(prefix);
+}
+function locationIsVisitable(location, rootLocation) {
+ return isPrefixedBy(location, rootLocation) && isHTML(location);
+}
+function getRequestURL(url) {
+ const anchor = getAnchor(url);
+ return anchor != null ? url.href.slice(0, -(anchor.length + 1)) : url.href;
+}
+function toCacheKey(url) {
+ return getRequestURL(url);
+}
+function urlsAreEqual(left, right) {
+ return expandURL(left).href == expandURL(right).href;
+}
+function getPathComponents(url) {
+ return url.pathname.split("/").slice(1);
+}
+function getLastPathComponent(url) {
+ return getPathComponents(url).slice(-1)[0];
+}
+function getPrefix(url) {
+ return addTrailingSlash(url.origin + url.pathname);
+}
+function addTrailingSlash(value) {
+ return value.endsWith("/") ? value : value + "/";
+}
+
+class FetchResponse {
+ constructor(response) {
+ this.response = response;
+ }
+ get succeeded() {
+ return this.response.ok;
+ }
+ get failed() {
+ return !this.succeeded;
+ }
+ get clientError() {
+ return this.statusCode >= 400 && this.statusCode <= 499;
+ }
+ get serverError() {
+ return this.statusCode >= 500 && this.statusCode <= 599;
+ }
+ get redirected() {
+ return this.response.redirected;
+ }
+ get location() {
+ return expandURL(this.response.url);
+ }
+ get isHTML() {
+ return this.contentType && this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/);
+ }
+ get statusCode() {
+ return this.response.status;
+ }
+ get contentType() {
+ return this.header("Content-Type");
+ }
+ get responseText() {
+ return this.response.clone().text();
+ }
+ get responseHTML() {
+ if (this.isHTML) {
+ return this.response.clone().text();
+ }
+ else {
+ return Promise.resolve(undefined);
+ }
+ }
+ header(name) {
+ return this.response.headers.get(name);
+ }
+}
+
+function activateScriptElement(element) {
+ if (element.getAttribute("data-turbo-eval") == "false") {
+ return element;
+ }
+ else {
+ const createdScriptElement = document.createElement("script");
+ const cspNonce = getMetaContent("csp-nonce");
+ if (cspNonce) {
+ createdScriptElement.nonce = cspNonce;
+ }
+ createdScriptElement.textContent = element.textContent;
+ createdScriptElement.async = false;
+ copyElementAttributes(createdScriptElement, element);
+ return createdScriptElement;
+ }
+}
+function copyElementAttributes(destinationElement, sourceElement) {
+ for (const { name, value } of sourceElement.attributes) {
+ destinationElement.setAttribute(name, value);
+ }
+}
+function createDocumentFragment(html) {
+ const template = document.createElement("template");
+ template.innerHTML = html;
+ return template.content;
+}
+function dispatch(eventName, { target, cancelable, detail } = {}) {
+ const event = new CustomEvent(eventName, {
+ cancelable,
+ bubbles: true,
+ composed: true,
+ detail,
+ });
+ if (target && target.isConnected) {
+ target.dispatchEvent(event);
+ }
+ else {
+ document.documentElement.dispatchEvent(event);
+ }
+ return event;
+}
+function nextAnimationFrame() {
+ return new Promise((resolve) => requestAnimationFrame(() => resolve()));
+}
+function nextEventLoopTick() {
+ return new Promise((resolve) => setTimeout(() => resolve(), 0));
+}
+function nextMicrotask() {
+ return Promise.resolve();
+}
+function parseHTMLDocument(html = "") {
+ return new DOMParser().parseFromString(html, "text/html");
+}
+function unindent(strings, ...values) {
+ const lines = interpolate(strings, values).replace(/^\n/, "").split("\n");
+ const match = lines[0].match(/^\s+/);
+ const indent = match ? match[0].length : 0;
+ return lines.map((line) => line.slice(indent)).join("\n");
+}
+function interpolate(strings, values) {
+ return strings.reduce((result, string, i) => {
+ const value = values[i] == undefined ? "" : values[i];
+ return result + string + value;
+ }, "");
+}
+function uuid() {
+ return Array.from({ length: 36 })
+ .map((_, i) => {
+ if (i == 8 || i == 13 || i == 18 || i == 23) {
+ return "-";
+ }
+ else if (i == 14) {
+ return "4";
+ }
+ else if (i == 19) {
+ return (Math.floor(Math.random() * 4) + 8).toString(16);
+ }
+ else {
+ return Math.floor(Math.random() * 15).toString(16);
+ }
+ })
+ .join("");
+}
+function getAttribute(attributeName, ...elements) {
+ for (const value of elements.map((element) => element === null || element === void 0 ? void 0 : element.getAttribute(attributeName))) {
+ if (typeof value == "string")
+ return value;
+ }
+ return null;
+}
+function hasAttribute(attributeName, ...elements) {
+ return elements.some((element) => element && element.hasAttribute(attributeName));
+}
+function markAsBusy(...elements) {
+ for (const element of elements) {
+ if (element.localName == "turbo-frame") {
+ element.setAttribute("busy", "");
+ }
+ element.setAttribute("aria-busy", "true");
+ }
+}
+function clearBusyState(...elements) {
+ for (const element of elements) {
+ if (element.localName == "turbo-frame") {
+ element.removeAttribute("busy");
+ }
+ element.removeAttribute("aria-busy");
+ }
+}
+function waitForLoad(element, timeoutInMilliseconds = 2000) {
+ return new Promise((resolve) => {
+ const onComplete = () => {
+ element.removeEventListener("error", onComplete);
+ element.removeEventListener("load", onComplete);
+ resolve();
+ };
+ element.addEventListener("load", onComplete, { once: true });
+ element.addEventListener("error", onComplete, { once: true });
+ setTimeout(resolve, timeoutInMilliseconds);
+ });
+}
+function getHistoryMethodForAction(action) {
+ switch (action) {
+ case "replace":
+ return history.replaceState;
+ case "advance":
+ case "restore":
+ return history.pushState;
+ }
+}
+function isAction(action) {
+ return action == "advance" || action == "replace" || action == "restore";
+}
+function getVisitAction(...elements) {
+ const action = getAttribute("data-turbo-action", ...elements);
+ return isAction(action) ? action : null;
+}
+function getMetaElement(name) {
+ return document.querySelector(`meta[name="${name}"]`);
+}
+function getMetaContent(name) {
+ const element = getMetaElement(name);
+ return element && element.content;
+}
+function setMetaContent(name, content) {
+ let element = getMetaElement(name);
+ if (!element) {
+ element = document.createElement("meta");
+ element.setAttribute("name", name);
+ document.head.appendChild(element);
+ }
+ element.setAttribute("content", content);
+ return element;
+}
+function findClosestRecursively(element, selector) {
+ var _a;
+ if (element instanceof Element) {
+ return (element.closest(selector) ||
+ findClosestRecursively(element.assignedSlot || ((_a = element.getRootNode()) === null || _a === void 0 ? void 0 : _a.host), selector));
+ }
+}
+
+var FetchMethod;
+(function (FetchMethod) {
+ FetchMethod[FetchMethod["get"] = 0] = "get";
+ FetchMethod[FetchMethod["post"] = 1] = "post";
+ FetchMethod[FetchMethod["put"] = 2] = "put";
+ FetchMethod[FetchMethod["patch"] = 3] = "patch";
+ FetchMethod[FetchMethod["delete"] = 4] = "delete";
+})(FetchMethod || (FetchMethod = {}));
+function fetchMethodFromString(method) {
+ switch (method.toLowerCase()) {
+ case "get":
+ return FetchMethod.get;
+ case "post":
+ return FetchMethod.post;
+ case "put":
+ return FetchMethod.put;
+ case "patch":
+ return FetchMethod.patch;
+ case "delete":
+ return FetchMethod.delete;
+ }
+}
+class FetchRequest {
+ constructor(delegate, method, location, body = new URLSearchParams(), target = null) {
+ this.abortController = new AbortController();
+ this.resolveRequestPromise = (_value) => { };
+ this.delegate = delegate;
+ this.method = method;
+ this.headers = this.defaultHeaders;
+ this.body = body;
+ this.url = location;
+ this.target = target;
+ }
+ get location() {
+ return this.url;
+ }
+ get params() {
+ return this.url.searchParams;
+ }
+ get entries() {
+ return this.body ? Array.from(this.body.entries()) : [];
+ }
+ cancel() {
+ this.abortController.abort();
+ }
+ async perform() {
+ const { fetchOptions } = this;
+ this.delegate.prepareRequest(this);
+ await this.allowRequestToBeIntercepted(fetchOptions);
+ try {
+ this.delegate.requestStarted(this);
+ const response = await fetch(this.url.href, fetchOptions);
+ return await this.receive(response);
+ }
+ catch (error) {
+ if (error.name !== "AbortError") {
+ if (this.willDelegateErrorHandling(error)) {
+ this.delegate.requestErrored(this, error);
+ }
+ throw error;
+ }
+ }
+ finally {
+ this.delegate.requestFinished(this);
+ }
+ }
+ async receive(response) {
+ const fetchResponse = new FetchResponse(response);
+ const event = dispatch("turbo:before-fetch-response", {
+ cancelable: true,
+ detail: { fetchResponse },
+ target: this.target,
+ });
+ if (event.defaultPrevented) {
+ this.delegate.requestPreventedHandlingResponse(this, fetchResponse);
+ }
+ else if (fetchResponse.succeeded) {
+ this.delegate.requestSucceededWithResponse(this, fetchResponse);
+ }
+ else {
+ this.delegate.requestFailedWithResponse(this, fetchResponse);
+ }
+ return fetchResponse;
+ }
+ get fetchOptions() {
+ var _a;
+ return {
+ method: FetchMethod[this.method].toUpperCase(),
+ credentials: "same-origin",
+ headers: this.headers,
+ redirect: "follow",
+ body: this.isSafe ? null : this.body,
+ signal: this.abortSignal,
+ referrer: (_a = this.delegate.referrer) === null || _a === void 0 ? void 0 : _a.href,
+ };
+ }
+ get defaultHeaders() {
+ return {
+ Accept: "text/html, application/xhtml+xml",
+ };
+ }
+ get isSafe() {
+ return this.method === FetchMethod.get;
+ }
+ get abortSignal() {
+ return this.abortController.signal;
+ }
+ acceptResponseType(mimeType) {
+ this.headers["Accept"] = [mimeType, this.headers["Accept"]].join(", ");
+ }
+ async allowRequestToBeIntercepted(fetchOptions) {
+ const requestInterception = new Promise((resolve) => (this.resolveRequestPromise = resolve));
+ const event = dispatch("turbo:before-fetch-request", {
+ cancelable: true,
+ detail: {
+ fetchOptions,
+ url: this.url,
+ resume: this.resolveRequestPromise,
+ },
+ target: this.target,
+ });
+ if (event.defaultPrevented)
+ await requestInterception;
+ }
+ willDelegateErrorHandling(error) {
+ const event = dispatch("turbo:fetch-request-error", {
+ target: this.target,
+ cancelable: true,
+ detail: { request: this, error: error },
+ });
+ return !event.defaultPrevented;
+ }
+}
+
+class AppearanceObserver {
+ constructor(delegate, element) {
+ this.started = false;
+ this.intersect = (entries) => {
+ const lastEntry = entries.slice(-1)[0];
+ if (lastEntry === null || lastEntry === void 0 ? void 0 : lastEntry.isIntersecting) {
+ this.delegate.elementAppearedInViewport(this.element);
+ }
+ };
+ this.delegate = delegate;
+ this.element = element;
+ this.intersectionObserver = new IntersectionObserver(this.intersect);
+ }
+ start() {
+ if (!this.started) {
+ this.started = true;
+ this.intersectionObserver.observe(this.element);
+ }
+ }
+ stop() {
+ if (this.started) {
+ this.started = false;
+ this.intersectionObserver.unobserve(this.element);
+ }
+ }
+}
+
+class StreamMessage {
+ static wrap(message) {
+ if (typeof message == "string") {
+ return new this(createDocumentFragment(message));
+ }
+ else {
+ return message;
+ }
+ }
+ constructor(fragment) {
+ this.fragment = importStreamElements(fragment);
+ }
+}
+StreamMessage.contentType = "text/vnd.turbo-stream.html";
+function importStreamElements(fragment) {
+ for (const element of fragment.querySelectorAll("turbo-stream")) {
+ const streamElement = document.importNode(element, true);
+ for (const inertScriptElement of streamElement.templateElement.content.querySelectorAll("script")) {
+ inertScriptElement.replaceWith(activateScriptElement(inertScriptElement));
+ }
+ element.replaceWith(streamElement);
+ }
+ return fragment;
+}
+
+var FormSubmissionState;
+(function (FormSubmissionState) {
+ FormSubmissionState[FormSubmissionState["initialized"] = 0] = "initialized";
+ FormSubmissionState[FormSubmissionState["requesting"] = 1] = "requesting";
+ FormSubmissionState[FormSubmissionState["waiting"] = 2] = "waiting";
+ FormSubmissionState[FormSubmissionState["receiving"] = 3] = "receiving";
+ FormSubmissionState[FormSubmissionState["stopping"] = 4] = "stopping";
+ FormSubmissionState[FormSubmissionState["stopped"] = 5] = "stopped";
+})(FormSubmissionState || (FormSubmissionState = {}));
+var FormEnctype;
+(function (FormEnctype) {
+ FormEnctype["urlEncoded"] = "application/x-www-form-urlencoded";
+ FormEnctype["multipart"] = "multipart/form-data";
+ FormEnctype["plain"] = "text/plain";
+})(FormEnctype || (FormEnctype = {}));
+function formEnctypeFromString(encoding) {
+ switch (encoding.toLowerCase()) {
+ case FormEnctype.multipart:
+ return FormEnctype.multipart;
+ case FormEnctype.plain:
+ return FormEnctype.plain;
+ default:
+ return FormEnctype.urlEncoded;
+ }
+}
+class FormSubmission {
+ static confirmMethod(message, _element, _submitter) {
+ return Promise.resolve(confirm(message));
+ }
+ constructor(delegate, formElement, submitter, mustRedirect = false) {
+ this.state = FormSubmissionState.initialized;
+ this.delegate = delegate;
+ this.formElement = formElement;
+ this.submitter = submitter;
+ this.formData = buildFormData(formElement, submitter);
+ this.location = expandURL(this.action);
+ if (this.method == FetchMethod.get) {
+ mergeFormDataEntries(this.location, [...this.body.entries()]);
+ }
+ this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body, this.formElement);
+ this.mustRedirect = mustRedirect;
+ }
+ get method() {
+ var _a;
+ const method = ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("formmethod")) || this.formElement.getAttribute("method") || "";
+ return fetchMethodFromString(method.toLowerCase()) || FetchMethod.get;
+ }
+ get action() {
+ var _a;
+ const formElementAction = typeof this.formElement.action === "string" ? this.formElement.action : null;
+ if ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.hasAttribute("formaction")) {
+ return this.submitter.getAttribute("formaction") || "";
+ }
+ else {
+ return this.formElement.getAttribute("action") || formElementAction || "";
+ }
+ }
+ get body() {
+ if (this.enctype == FormEnctype.urlEncoded || this.method == FetchMethod.get) {
+ return new URLSearchParams(this.stringFormData);
+ }
+ else {
+ return this.formData;
+ }
+ }
+ get enctype() {
+ var _a;
+ return formEnctypeFromString(((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("formenctype")) || this.formElement.enctype);
+ }
+ get isSafe() {
+ return this.fetchRequest.isSafe;
+ }
+ get stringFormData() {
+ return [...this.formData].reduce((entries, [name, value]) => {
+ return entries.concat(typeof value == "string" ? [[name, value]] : []);
+ }, []);
+ }
+ async start() {
+ const { initialized, requesting } = FormSubmissionState;
+ const confirmationMessage = getAttribute("data-turbo-confirm", this.submitter, this.formElement);
+ if (typeof confirmationMessage === "string") {
+ const answer = await FormSubmission.confirmMethod(confirmationMessage, this.formElement, this.submitter);
+ if (!answer) {
+ return;
+ }
+ }
+ if (this.state == initialized) {
+ this.state = requesting;
+ return this.fetchRequest.perform();
+ }
+ }
+ stop() {
+ const { stopping, stopped } = FormSubmissionState;
+ if (this.state != stopping && this.state != stopped) {
+ this.state = stopping;
+ this.fetchRequest.cancel();
+ return true;
+ }
+ }
+ prepareRequest(request) {
+ if (!request.isSafe) {
+ const token = getCookieValue(getMetaContent("csrf-param")) || getMetaContent("csrf-token");
+ if (token) {
+ request.headers["X-CSRF-Token"] = token;
+ }
+ }
+ if (this.requestAcceptsTurboStreamResponse(request)) {
+ request.acceptResponseType(StreamMessage.contentType);
+ }
+ }
+ requestStarted(_request) {
+ var _a;
+ this.state = FormSubmissionState.waiting;
+ (_a = this.submitter) === null || _a === void 0 ? void 0 : _a.setAttribute("disabled", "");
+ this.setSubmitsWith();
+ dispatch("turbo:submit-start", {
+ target: this.formElement,
+ detail: { formSubmission: this },
+ });
+ this.delegate.formSubmissionStarted(this);
+ }
+ requestPreventedHandlingResponse(request, response) {
+ this.result = { success: response.succeeded, fetchResponse: response };
+ }
+ requestSucceededWithResponse(request, response) {
+ if (response.clientError || response.serverError) {
+ this.delegate.formSubmissionFailedWithResponse(this, response);
+ }
+ else if (this.requestMustRedirect(request) && responseSucceededWithoutRedirect(response)) {
+ const error = new Error("Form responses must redirect to another location");
+ this.delegate.formSubmissionErrored(this, error);
+ }
+ else {
+ this.state = FormSubmissionState.receiving;
+ this.result = { success: true, fetchResponse: response };
+ this.delegate.formSubmissionSucceededWithResponse(this, response);
+ }
+ }
+ requestFailedWithResponse(request, response) {
+ this.result = { success: false, fetchResponse: response };
+ this.delegate.formSubmissionFailedWithResponse(this, response);
+ }
+ requestErrored(request, error) {
+ this.result = { success: false, error };
+ this.delegate.formSubmissionErrored(this, error);
+ }
+ requestFinished(_request) {
+ var _a;
+ this.state = FormSubmissionState.stopped;
+ (_a = this.submitter) === null || _a === void 0 ? void 0 : _a.removeAttribute("disabled");
+ this.resetSubmitterText();
+ dispatch("turbo:submit-end", {
+ target: this.formElement,
+ detail: Object.assign({ formSubmission: this }, this.result),
+ });
+ this.delegate.formSubmissionFinished(this);
+ }
+ setSubmitsWith() {
+ if (!this.submitter || !this.submitsWith)
+ return;
+ if (this.submitter.matches("button")) {
+ this.originalSubmitText = this.submitter.innerHTML;
+ this.submitter.innerHTML = this.submitsWith;
+ }
+ else if (this.submitter.matches("input")) {
+ const input = this.submitter;
+ this.originalSubmitText = input.value;
+ input.value = this.submitsWith;
+ }
+ }
+ resetSubmitterText() {
+ if (!this.submitter || !this.originalSubmitText)
+ return;
+ if (this.submitter.matches("button")) {
+ this.submitter.innerHTML = this.originalSubmitText;
+ }
+ else if (this.submitter.matches("input")) {
+ const input = this.submitter;
+ input.value = this.originalSubmitText;
+ }
+ }
+ requestMustRedirect(request) {
+ return !request.isSafe && this.mustRedirect;
+ }
+ requestAcceptsTurboStreamResponse(request) {
+ return !request.isSafe || hasAttribute("data-turbo-stream", this.submitter, this.formElement);
+ }
+ get submitsWith() {
+ var _a;
+ return (_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("data-turbo-submits-with");
+ }
+}
+function buildFormData(formElement, submitter) {
+ const formData = new FormData(formElement);
+ const name = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("name");
+ const value = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("value");
+ if (name) {
+ formData.append(name, value || "");
+ }
+ return formData;
+}
+function getCookieValue(cookieName) {
+ if (cookieName != null) {
+ const cookies = document.cookie ? document.cookie.split("; ") : [];
+ const cookie = cookies.find((cookie) => cookie.startsWith(cookieName));
+ if (cookie) {
+ const value = cookie.split("=").slice(1).join("=");
+ return value ? decodeURIComponent(value) : undefined;
+ }
+ }
+}
+function responseSucceededWithoutRedirect(response) {
+ return response.statusCode == 200 && !response.redirected;
+}
+function mergeFormDataEntries(url, entries) {
+ const searchParams = new URLSearchParams();
+ for (const [name, value] of entries) {
+ if (value instanceof File)
+ continue;
+ searchParams.append(name, value);
+ }
+ url.search = searchParams.toString();
+ return url;
+}
+
+class Snapshot {
+ constructor(element) {
+ this.element = element;
+ }
+ get activeElement() {
+ return this.element.ownerDocument.activeElement;
+ }
+ get children() {
+ return [...this.element.children];
+ }
+ hasAnchor(anchor) {
+ return this.getElementForAnchor(anchor) != null;
+ }
+ getElementForAnchor(anchor) {
+ return anchor ? this.element.querySelector(`[id=''${anchor}''], a[name=''${anchor}'']`) : null;
+ }
+ get isConnected() {
+ return this.element.isConnected;
+ }
+ get firstAutofocusableElement() {
+ const inertDisabledOrHidden = "[inert], :disabled, [hidden], details:not([open]), dialog:not([open])";
+ for (const element of this.element.querySelectorAll("[autofocus]")) {
+ if (element.closest(inertDisabledOrHidden) == null)
+ return element;
+ else
+ continue;
+ }
+ return null;
+ }
+ get permanentElements() {
+ return queryPermanentElementsAll(this.element);
+ }
+ getPermanentElementById(id) {
+ return getPermanentElementById(this.element, id);
+ }
+ getPermanentElementMapForSnapshot(snapshot) {
+ const permanentElementMap = {};
+ for (const currentPermanentElement of this.permanentElements) {
+ const { id } = currentPermanentElement;
+ const newPermanentElement = snapshot.getPermanentElementById(id);
+ if (newPermanentElement) {
+ permanentElementMap[id] = [currentPermanentElement, newPermanentElement];
+ }
+ }
+ return permanentElementMap;
+ }
+}
+function getPermanentElementById(node, id) {
+ return node.querySelector(`#${id}[data-turbo-permanent]`);
+}
+function queryPermanentElementsAll(node) {
+ return node.querySelectorAll("[id][data-turbo-permanent]");
+}
+
+class FormSubmitObserver {
+ constructor(delegate, eventTarget) {
+ this.started = false;
+ this.submitCaptured = () => {
+ this.eventTarget.removeEventListener("submit", this.submitBubbled, false);
+ this.eventTarget.addEventListener("submit", this.submitBubbled, false);
+ };
+ this.submitBubbled = ((event) => {
+ if (!event.defaultPrevented) {
+ const form = event.target instanceof HTMLFormElement ? event.target : undefined;
+ const submitter = event.submitter || undefined;
+ if (form &&
+ submissionDoesNotDismissDialog(form, submitter) &&
+ submissionDoesNotTargetIFrame(form, submitter) &&
+ this.delegate.willSubmitForm(form, submitter)) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ this.delegate.formSubmitted(form, submitter);
+ }
+ }
+ });
+ this.delegate = delegate;
+ this.eventTarget = eventTarget;
+ }
+ start() {
+ if (!this.started) {
+ this.eventTarget.addEventListener("submit", this.submitCaptured, true);
+ this.started = true;
+ }
+ }
+ stop() {
+ if (this.started) {
+ this.eventTarget.removeEventListener("submit", this.submitCaptured, true);
+ this.started = false;
+ }
+ }
+}
+function submissionDoesNotDismissDialog(form, submitter) {
+ const method = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formmethod")) || form.getAttribute("method");
+ return method != "dialog";
+}
+function submissionDoesNotTargetIFrame(form, submitter) {
+ if ((submitter === null || submitter === void 0 ? void 0 : submitter.hasAttribute("formtarget")) || form.hasAttribute("target")) {
+ const target = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formtarget")) || form.target;
+ for (const element of document.getElementsByName(target)) {
+ if (element instanceof HTMLIFrameElement)
+ return false;
+ }
+ return true;
+ }
+ else {
+ return true;
+ }
+}
+
+class View {
+ constructor(delegate, element) {
+ this.resolveRenderPromise = (_value) => { };
+ this.resolveInterceptionPromise = (_value) => { };
+ this.delegate = delegate;
+ this.element = element;
+ }
+ scrollToAnchor(anchor) {
+ const element = this.snapshot.getElementForAnchor(anchor);
+ if (element) {
+ this.scrollToElement(element);
+ this.focusElement(element);
+ }
+ else {
+ this.scrollToPosition({ x: 0, y: 0 });
+ }
+ }
+ scrollToAnchorFromLocation(location) {
+ this.scrollToAnchor(getAnchor(location));
+ }
+ scrollToElement(element) {
+ element.scrollIntoView();
+ }
+ focusElement(element) {
+ if (element instanceof HTMLElement) {
+ if (element.hasAttribute("tabindex")) {
+ element.focus();
+ }
+ else {
+ element.setAttribute("tabindex", "-1");
+ element.focus();
+ element.removeAttribute("tabindex");
+ }
+ }
+ }
+ scrollToPosition({ x, y }) {
+ this.scrollRoot.scrollTo(x, y);
+ }
+ scrollToTop() {
+ this.scrollToPosition({ x: 0, y: 0 });
+ }
+ get scrollRoot() {
+ return window;
+ }
+ async render(renderer) {
+ const { isPreview, shouldRender, newSnapshot: snapshot } = renderer;
+ if (shouldRender) {
+ try {
+ this.renderPromise = new Promise((resolve) => (this.resolveRenderPromise = resolve));
+ this.renderer = renderer;
+ await this.prepareToRenderSnapshot(renderer);
+ const renderInterception = new Promise((resolve) => (this.resolveInterceptionPromise = resolve));
+ const options = { resume: this.resolveInterceptionPromise, render: this.renderer.renderElement };
+ const immediateRender = this.delegate.allowsImmediateRender(snapshot, options);
+ if (!immediateRender)
+ await renderInterception;
+ await this.renderSnapshot(renderer);
+ this.delegate.viewRenderedSnapshot(snapshot, isPreview);
+ this.delegate.preloadOnLoadLinksForView(this.element);
+ this.finishRenderingSnapshot(renderer);
+ }
+ finally {
+ delete this.renderer;
+ this.resolveRenderPromise(undefined);
+ delete this.renderPromise;
+ }
+ }
+ else {
+ this.invalidate(renderer.reloadReason);
+ }
+ }
+ invalidate(reason) {
+ this.delegate.viewInvalidated(reason);
+ }
+ async prepareToRenderSnapshot(renderer) {
+ this.markAsPreview(renderer.isPreview);
+ await renderer.prepareToRender();
+ }
+ markAsPreview(isPreview) {
+ if (isPreview) {
+ this.element.setAttribute("data-turbo-preview", "");
+ }
+ else {
+ this.element.removeAttribute("data-turbo-preview");
+ }
+ }
+ async renderSnapshot(renderer) {
+ await renderer.render();
+ }
+ finishRenderingSnapshot(renderer) {
+ renderer.finishRendering();
+ }
+}
+
+class FrameView extends View {
+ missing() {
+ this.element.innerHTML = `Content missing`;
+ }
+ get snapshot() {
+ return new Snapshot(this.element);
+ }
+}
+
+class LinkInterceptor {
+ constructor(delegate, element) {
+ this.clickBubbled = (event) => {
+ if (this.respondsToEventTarget(event.target)) {
+ this.clickEvent = event;
+ }
+ else {
+ delete this.clickEvent;
+ }
+ };
+ this.linkClicked = ((event) => {
+ if (this.clickEvent && this.respondsToEventTarget(event.target) && event.target instanceof Element) {
+ if (this.delegate.shouldInterceptLinkClick(event.target, event.detail.url, event.detail.originalEvent)) {
+ this.clickEvent.preventDefault();
+ event.preventDefault();
+ this.delegate.linkClickIntercepted(event.target, event.detail.url, event.detail.originalEvent);
+ }
+ }
+ delete this.clickEvent;
+ });
+ this.willVisit = ((_event) => {
+ delete this.clickEvent;
+ });
+ this.delegate = delegate;
+ this.element = element;
+ }
+ start() {
+ this.element.addEventListener("click", this.clickBubbled);
+ document.addEventListener("turbo:click", this.linkClicked);
+ document.addEventListener("turbo:before-visit", this.willVisit);
+ }
+ stop() {
+ this.element.removeEventListener("click", this.clickBubbled);
+ document.removeEventListener("turbo:click", this.linkClicked);
+ document.removeEventListener("turbo:before-visit", this.willVisit);
+ }
+ respondsToEventTarget(target) {
+ const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
+ return element && element.closest("turbo-frame, html") == this.element;
+ }
+}
+
+class LinkClickObserver {
+ constructor(delegate, eventTarget) {
+ this.started = false;
+ this.clickCaptured = () => {
+ this.eventTarget.removeEventListener("click", this.clickBubbled, false);
+ this.eventTarget.addEventListener("click", this.clickBubbled, false);
+ };
+ this.clickBubbled = (event) => {
+ if (event instanceof MouseEvent && this.clickEventIsSignificant(event)) {
+ const target = (event.composedPath && event.composedPath()[0]) || event.target;
+ const link = this.findLinkFromClickTarget(target);
+ if (link && doesNotTargetIFrame(link)) {
+ const location = this.getLocationForLink(link);
+ if (this.delegate.willFollowLinkToLocation(link, location, event)) {
+ event.preventDefault();
+ this.delegate.followedLinkToLocation(link, location);
+ }
+ }
+ }
+ };
+ this.delegate = delegate;
+ this.eventTarget = eventTarget;
+ }
+ start() {
+ if (!this.started) {
+ this.eventTarget.addEventListener("click", this.clickCaptured, true);
+ this.started = true;
+ }
+ }
+ stop() {
+ if (this.started) {
+ this.eventTarget.removeEventListener("click", this.clickCaptured, true);
+ this.started = false;
+ }
+ }
+ clickEventIsSignificant(event) {
+ return !((event.target && event.target.isContentEditable) ||
+ event.defaultPrevented ||
+ event.which > 1 ||
+ event.altKey ||
+ event.ctrlKey ||
+ event.metaKey ||
+ event.shiftKey);
+ }
+ findLinkFromClickTarget(target) {
+ return findClosestRecursively(target, "a[href]:not([target^=_]):not([download])");
+ }
+ getLocationForLink(link) {
+ return expandURL(link.getAttribute("href") || "");
+ }
+}
+function doesNotTargetIFrame(anchor) {
+ if (anchor.hasAttribute("target")) {
+ for (const element of document.getElementsByName(anchor.target)) {
+ if (element instanceof HTMLIFrameElement)
+ return false;
+ }
+ return true;
+ }
+ else {
+ return true;
+ }
+}
+
+class FormLinkClickObserver {
+ constructor(delegate, element) {
+ this.delegate = delegate;
+ this.linkInterceptor = new LinkClickObserver(this, element);
+ }
+ start() {
+ this.linkInterceptor.start();
+ }
+ stop() {
+ this.linkInterceptor.stop();
+ }
+ willFollowLinkToLocation(link, location, originalEvent) {
+ return (this.delegate.willSubmitFormLinkToLocation(link, location, originalEvent) &&
+ link.hasAttribute("data-turbo-method"));
+ }
+ followedLinkToLocation(link, location) {
+ const form = document.createElement("form");
+ const type = "hidden";
+ for (const [name, value] of location.searchParams) {
+ form.append(Object.assign(document.createElement("input"), { type, name, value }));
+ }
+ const action = Object.assign(location, { search: "" });
+ form.setAttribute("data-turbo", "true");
+ form.setAttribute("action", action.href);
+ form.setAttribute("hidden", "");
+ const method = link.getAttribute("data-turbo-method");
+ if (method)
+ form.setAttribute("method", method);
+ const turboFrame = link.getAttribute("data-turbo-frame");
+ if (turboFrame)
+ form.setAttribute("data-turbo-frame", turboFrame);
+ const turboAction = getVisitAction(link);
+ if (turboAction)
+ form.setAttribute("data-turbo-action", turboAction);
+ const turboConfirm = link.getAttribute("data-turbo-confirm");
+ if (turboConfirm)
+ form.setAttribute("data-turbo-confirm", turboConfirm);
+ const turboStream = link.hasAttribute("data-turbo-stream");
+ if (turboStream)
+ form.setAttribute("data-turbo-stream", "");
+ this.delegate.submittedFormLinkToLocation(link, location, form);
+ document.body.appendChild(form);
+ form.addEventListener("turbo:submit-end", () => form.remove(), { once: true });
+ requestAnimationFrame(() => form.requestSubmit());
+ }
+}
+
+class Bardo {
+ static async preservingPermanentElements(delegate, permanentElementMap, callback) {
+ const bardo = new this(delegate, permanentElementMap);
+ bardo.enter();
+ await callback();
+ bardo.leave();
+ }
+ constructor(delegate, permanentElementMap) {
+ this.delegate = delegate;
+ this.permanentElementMap = permanentElementMap;
+ }
+ enter() {
+ for (const id in this.permanentElementMap) {
+ const [currentPermanentElement, newPermanentElement] = this.permanentElementMap[id];
+ this.delegate.enteringBardo(currentPermanentElement, newPermanentElement);
+ this.replaceNewPermanentElementWithPlaceholder(newPermanentElement);
+ }
+ }
+ leave() {
+ for (const id in this.permanentElementMap) {
+ const [currentPermanentElement] = this.permanentElementMap[id];
+ this.replaceCurrentPermanentElementWithClone(currentPermanentElement);
+ this.replacePlaceholderWithPermanentElement(currentPermanentElement);
+ this.delegate.leavingBardo(currentPermanentElement);
+ }
+ }
+ replaceNewPermanentElementWithPlaceholder(permanentElement) {
+ const placeholder = createPlaceholderForPermanentElement(permanentElement);
+ permanentElement.replaceWith(placeholder);
+ }
+ replaceCurrentPermanentElementWithClone(permanentElement) {
+ const clone = permanentElement.cloneNode(true);
+ permanentElement.replaceWith(clone);
+ }
+ replacePlaceholderWithPermanentElement(permanentElement) {
+ const placeholder = this.getPlaceholderById(permanentElement.id);
+ placeholder === null || placeholder === void 0 ? void 0 : placeholder.replaceWith(permanentElement);
+ }
+ getPlaceholderById(id) {
+ return this.placeholders.find((element) => element.content == id);
+ }
+ get placeholders() {
+ return [...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")];
+ }
+}
+function createPlaceholderForPermanentElement(permanentElement) {
+ const element = document.createElement("meta");
+ element.setAttribute("name", "turbo-permanent-placeholder");
+ element.setAttribute("content", permanentElement.id);
+ return element;
+}
+
+class Renderer {
+ constructor(currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {
+ this.activeElement = null;
+ this.currentSnapshot = currentSnapshot;
+ this.newSnapshot = newSnapshot;
+ this.isPreview = isPreview;
+ this.willRender = willRender;
+ this.renderElement = renderElement;
+ this.promise = new Promise((resolve, reject) => (this.resolvingFunctions = { resolve, reject }));
+ }
+ get shouldRender() {
+ return true;
+ }
+ get reloadReason() {
+ return;
+ }
+ prepareToRender() {
+ return;
+ }
+ finishRendering() {
+ if (this.resolvingFunctions) {
+ this.resolvingFunctions.resolve();
+ delete this.resolvingFunctions;
+ }
+ }
+ async preservingPermanentElements(callback) {
+ await Bardo.preservingPermanentElements(this, this.permanentElementMap, callback);
+ }
+ focusFirstAutofocusableElement() {
+ const element = this.connectedSnapshot.firstAutofocusableElement;
+ if (elementIsFocusable(element)) {
+ element.focus();
+ }
+ }
+ enteringBardo(currentPermanentElement) {
+ if (this.activeElement)
+ return;
+ if (currentPermanentElement.contains(this.currentSnapshot.activeElement)) {
+ this.activeElement = this.currentSnapshot.activeElement;
+ }
+ }
+ leavingBardo(currentPermanentElement) {
+ if (currentPermanentElement.contains(this.activeElement) && this.activeElement instanceof HTMLElement) {
+ this.activeElement.focus();
+ this.activeElement = null;
+ }
+ }
+ get connectedSnapshot() {
+ return this.newSnapshot.isConnected ? this.newSnapshot : this.currentSnapshot;
+ }
+ get currentElement() {
+ return this.currentSnapshot.element;
+ }
+ get newElement() {
+ return this.newSnapshot.element;
+ }
+ get permanentElementMap() {
+ return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot);
+ }
+}
+function elementIsFocusable(element) {
+ return element && typeof element.focus == "function";
+}
+
+class FrameRenderer extends Renderer {
+ static renderElement(currentElement, newElement) {
+ var _a;
+ const destinationRange = document.createRange();
+ destinationRange.selectNodeContents(currentElement);
+ destinationRange.deleteContents();
+ const frameElement = newElement;
+ const sourceRange = (_a = frameElement.ownerDocument) === null || _a === void 0 ? void 0 : _a.createRange();
+ if (sourceRange) {
+ sourceRange.selectNodeContents(frameElement);
+ currentElement.appendChild(sourceRange.extractContents());
+ }
+ }
+ constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {
+ super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender);
+ this.delegate = delegate;
+ }
+ get shouldRender() {
+ return true;
+ }
+ async render() {
+ await nextAnimationFrame();
+ this.preservingPermanentElements(() => {
+ this.loadFrameElement();
+ });
+ this.scrollFrameIntoView();
+ await nextAnimationFrame();
+ this.focusFirstAutofocusableElement();
+ await nextAnimationFrame();
+ this.activateScriptElements();
+ }
+ loadFrameElement() {
+ this.delegate.willRenderFrame(this.currentElement, this.newElement);
+ this.renderElement(this.currentElement, this.newElement);
+ }
+ scrollFrameIntoView() {
+ if (this.currentElement.autoscroll || this.newElement.autoscroll) {
+ const element = this.currentElement.firstElementChild;
+ const block = readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"), "end");
+ const behavior = readScrollBehavior(this.currentElement.getAttribute("data-autoscroll-behavior"), "auto");
+ if (element) {
+ element.scrollIntoView({ block, behavior });
+ return true;
+ }
+ }
+ return false;
+ }
+ activateScriptElements() {
+ for (const inertScriptElement of this.newScriptElements) {
+ const activatedScriptElement = activateScriptElement(inertScriptElement);
+ inertScriptElement.replaceWith(activatedScriptElement);
+ }
+ }
+ get newScriptElements() {
+ return this.currentElement.querySelectorAll("script");
+ }
+}
+function readScrollLogicalPosition(value, defaultValue) {
+ if (value == "end" || value == "start" || value == "center" || value == "nearest") {
+ return value;
+ }
+ else {
+ return defaultValue;
+ }
+}
+function readScrollBehavior(value, defaultValue) {
+ if (value == "auto" || value == "smooth") {
+ return value;
+ }
+ else {
+ return defaultValue;
+ }
+}
+
+class ProgressBar {
+ static get defaultCSS() {
+ return unindent `
+ .turbo-progress-bar {
+ position: fixed;
+ display: block;
+ top: 0;
+ left: 0;
+ height: 3px;
+ background: #0076ff;
+ z-index: 2147483647;
+ transition:
+ width ${ProgressBar.animationDuration}ms ease-out,
+ opacity ${ProgressBar.animationDuration / 2}ms ${ProgressBar.animationDuration / 2}ms ease-in;
+ transform: translate3d(0, 0, 0);
+ }
+ `;
+ }
+ constructor() {
+ this.hiding = false;
+ this.value = 0;
+ this.visible = false;
+ this.trickle = () => {
+ this.setValue(this.value + Math.random() / 100);
+ };
+ this.stylesheetElement = this.createStylesheetElement();
+ this.progressElement = this.createProgressElement();
+ this.installStylesheetElement();
+ this.setValue(0);
+ }
+ show() {
+ if (!this.visible) {
+ this.visible = true;
+ this.installProgressElement();
+ this.startTrickling();
+ }
+ }
+ hide() {
+ if (this.visible && !this.hiding) {
+ this.hiding = true;
+ this.fadeProgressElement(() => {
+ this.uninstallProgressElement();
+ this.stopTrickling();
+ this.visible = false;
+ this.hiding = false;
+ });
+ }
+ }
+ setValue(value) {
+ this.value = value;
+ this.refresh();
+ }
+ installStylesheetElement() {
+ document.head.insertBefore(this.stylesheetElement, document.head.firstChild);
+ }
+ installProgressElement() {
+ this.progressElement.style.width = "0";
+ this.progressElement.style.opacity = "1";
+ document.documentElement.insertBefore(this.progressElement, document.body);
+ this.refresh();
+ }
+ fadeProgressElement(callback) {
+ this.progressElement.style.opacity = "0";
+ setTimeout(callback, ProgressBar.animationDuration * 1.5);
+ }
+ uninstallProgressElement() {
+ if (this.progressElement.parentNode) {
+ document.documentElement.removeChild(this.progressElement);
+ }
+ }
+ startTrickling() {
+ if (!this.trickleInterval) {
+ this.trickleInterval = window.setInterval(this.trickle, ProgressBar.animationDuration);
+ }
+ }
+ stopTrickling() {
+ window.clearInterval(this.trickleInterval);
+ delete this.trickleInterval;
+ }
+ refresh() {
+ requestAnimationFrame(() => {
+ this.progressElement.style.width = `${10 + this.value * 90}%`;
+ });
+ }
+ createStylesheetElement() {
+ const element = document.createElement("style");
+ element.type = "text/css";
+ element.textContent = ProgressBar.defaultCSS;
+ if (this.cspNonce) {
+ element.nonce = this.cspNonce;
+ }
+ return element;
+ }
+ createProgressElement() {
+ const element = document.createElement("div");
+ element.className = "turbo-progress-bar";
+ return element;
+ }
+ get cspNonce() {
+ return getMetaContent("csp-nonce");
+ }
+}
+ProgressBar.animationDuration = 300;
+
+class HeadSnapshot extends Snapshot {
+ constructor() {
+ super(...arguments);
+ this.detailsByOuterHTML = this.children
+ .filter((element) => !elementIsNoscript(element))
+ .map((element) => elementWithoutNonce(element))
+ .reduce((result, element) => {
+ const { outerHTML } = element;
+ const details = outerHTML in result
+ ? result[outerHTML]
+ : {
+ type: elementType(element),
+ tracked: elementIsTracked(element),
+ elements: [],
+ };
+ return Object.assign(Object.assign({}, result), { [outerHTML]: Object.assign(Object.assign({}, details), { elements: [...details.elements, element] }) });
+ }, {});
+ }
+ get trackedElementSignature() {
+ return Object.keys(this.detailsByOuterHTML)
+ .filter((outerHTML) => this.detailsByOuterHTML[outerHTML].tracked)
+ .join("");
+ }
+ getScriptElementsNotInSnapshot(snapshot) {
+ return this.getElementsMatchingTypeNotInSnapshot("script", snapshot);
+ }
+ getStylesheetElementsNotInSnapshot(snapshot) {
+ return this.getElementsMatchingTypeNotInSnapshot("stylesheet", snapshot);
+ }
+ getElementsMatchingTypeNotInSnapshot(matchedType, snapshot) {
+ return Object.keys(this.detailsByOuterHTML)
+ .filter((outerHTML) => !(outerHTML in snapshot.detailsByOuterHTML))
+ .map((outerHTML) => this.detailsByOuterHTML[outerHTML])
+ .filter(({ type }) => type == matchedType)
+ .map(({ elements: [element] }) => element);
+ }
+ get provisionalElements() {
+ return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {
+ const { type, tracked, elements } = this.detailsByOuterHTML[outerHTML];
+ if (type == null && !tracked) {
+ return [...result, ...elements];
+ }
+ else if (elements.length > 1) {
+ return [...result, ...elements.slice(1)];
+ }
+ else {
+ return result;
+ }
+ }, []);
+ }
+ getMetaValue(name) {
+ const element = this.findMetaElementByName(name);
+ return element ? element.getAttribute("content") : null;
+ }
+ findMetaElementByName(name) {
+ return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {
+ const { elements: [element], } = this.detailsByOuterHTML[outerHTML];
+ return elementIsMetaElementWithName(element, name) ? element : result;
+ }, undefined);
+ }
+}
+function elementType(element) {
+ if (elementIsScript(element)) {
+ return "script";
+ }
+ else if (elementIsStylesheet(element)) {
+ return "stylesheet";
+ }
+}
+function elementIsTracked(element) {
+ return element.getAttribute("data-turbo-track") == "reload";
+}
+function elementIsScript(element) {
+ const tagName = element.localName;
+ return tagName == "script";
+}
+function elementIsNoscript(element) {
+ const tagName = element.localName;
+ return tagName == "noscript";
+}
+function elementIsStylesheet(element) {
+ const tagName = element.localName;
+ return tagName == "style" || (tagName == "link" && element.getAttribute("rel") == "stylesheet");
+}
+function elementIsMetaElementWithName(element, name) {
+ const tagName = element.localName;
+ return tagName == "meta" && element.getAttribute("name") == name;
+}
+function elementWithoutNonce(element) {
+ if (element.hasAttribute("nonce")) {
+ element.setAttribute("nonce", "");
+ }
+ return element;
+}
+
+class PageSnapshot extends Snapshot {
+ static fromHTMLString(html = "") {
+ return this.fromDocument(parseHTMLDocument(html));
+ }
+ static fromElement(element) {
+ return this.fromDocument(element.ownerDocument);
+ }
+ static fromDocument({ head, body }) {
+ return new this(body, new HeadSnapshot(head));
+ }
+ constructor(element, headSnapshot) {
+ super(element);
+ this.headSnapshot = headSnapshot;
+ }
+ clone() {
+ const clonedElement = this.element.cloneNode(true);
+ const selectElements = this.element.querySelectorAll("select");
+ const clonedSelectElements = clonedElement.querySelectorAll("select");
+ for (const [index, source] of selectElements.entries()) {
+ const clone = clonedSelectElements[index];
+ for (const option of clone.selectedOptions)
+ option.selected = false;
+ for (const option of source.selectedOptions)
+ clone.options[option.index].selected = true;
+ }
+ for (const clonedPasswordInput of clonedElement.querySelectorAll(''input[type="password"]'')) {
+ clonedPasswordInput.value = "";
+ }
+ return new PageSnapshot(clonedElement, this.headSnapshot);
+ }
+ get headElement() {
+ return this.headSnapshot.element;
+ }
+ get rootLocation() {
+ var _a;
+ const root = (_a = this.getSetting("root")) !== null && _a !== void 0 ? _a : "/";
+ return expandURL(root);
+ }
+ get cacheControlValue() {
+ return this.getSetting("cache-control");
+ }
+ get isPreviewable() {
+ return this.cacheControlValue != "no-preview";
+ }
+ get isCacheable() {
+ return this.cacheControlValue != "no-cache";
+ }
+ get isVisitable() {
+ return this.getSetting("visit-control") != "reload";
+ }
+ getSetting(name) {
+ return this.headSnapshot.getMetaValue(`turbo-${name}`);
+ }
+}
+
+var TimingMetric;
+(function (TimingMetric) {
+ TimingMetric["visitStart"] = "visitStart";
+ TimingMetric["requestStart"] = "requestStart";
+ TimingMetric["requestEnd"] = "requestEnd";
+ TimingMetric["visitEnd"] = "visitEnd";
+})(TimingMetric || (TimingMetric = {}));
+var VisitState;
+(function (VisitState) {
+ VisitState["initialized"] = "initialized";
+ VisitState["started"] = "started";
+ VisitState["canceled"] = "canceled";
+ VisitState["failed"] = "failed";
+ VisitState["completed"] = "completed";
+})(VisitState || (VisitState = {}));
+const defaultOptions = {
+ action: "advance",
+ historyChanged: false,
+ visitCachedSnapshot: () => { },
+ willRender: true,
+ updateHistory: true,
+ shouldCacheSnapshot: true,
+ acceptsStreamResponse: false,
+};
+var SystemStatusCode;
+(function (SystemStatusCode) {
+ SystemStatusCode[SystemStatusCode["networkFailure"] = 0] = "networkFailure";
+ SystemStatusCode[SystemStatusCode["timeoutFailure"] = -1] = "timeoutFailure";
+ SystemStatusCode[SystemStatusCode["contentTypeMismatch"] = -2] = "contentTypeMismatch";
+})(SystemStatusCode || (SystemStatusCode = {}));
+class Visit {
+ constructor(delegate, location, restorationIdentifier, options = {}) {
+ this.identifier = uuid();
+ this.timingMetrics = {};
+ this.followedRedirect = false;
+ this.historyChanged = false;
+ this.scrolled = false;
+ this.shouldCacheSnapshot = true;
+ this.acceptsStreamResponse = false;
+ this.snapshotCached = false;
+ this.state = VisitState.initialized;
+ this.delegate = delegate;
+ this.location = location;
+ this.restorationIdentifier = restorationIdentifier || uuid();
+ const { action, historyChanged, referrer, snapshot, snapshotHTML, response, visitCachedSnapshot, willRender, updateHistory, shouldCacheSnapshot, acceptsStreamResponse, } = Object.assign(Object.assign({}, defaultOptions), options);
+ this.action = action;
+ this.historyChanged = historyChanged;
+ this.referrer = referrer;
+ this.snapshot = snapshot;
+ this.snapshotHTML = snapshotHTML;
+ this.response = response;
+ this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action);
+ this.visitCachedSnapshot = visitCachedSnapshot;
+ this.willRender = willRender;
+ this.updateHistory = updateHistory;
+ this.scrolled = !willRender;
+ this.shouldCacheSnapshot = shouldCacheSnapshot;
+ this.acceptsStreamResponse = acceptsStreamResponse;
+ }
+ get adapter() {
+ return this.delegate.adapter;
+ }
+ get view() {
+ return this.delegate.view;
+ }
+ get history() {
+ return this.delegate.history;
+ }
+ get restorationData() {
+ return this.history.getRestorationDataForIdentifier(this.restorationIdentifier);
+ }
+ get silent() {
+ return this.isSamePage;
+ }
+ start() {
+ if (this.state == VisitState.initialized) {
+ this.recordTimingMetric(TimingMetric.visitStart);
+ this.state = VisitState.started;
+ this.adapter.visitStarted(this);
+ this.delegate.visitStarted(this);
+ }
+ }
+ cancel() {
+ if (this.state == VisitState.started) {
+ if (this.request) {
+ this.request.cancel();
+ }
+ this.cancelRender();
+ this.state = VisitState.canceled;
+ }
+ }
+ complete() {
+ if (this.state == VisitState.started) {
+ this.recordTimingMetric(TimingMetric.visitEnd);
+ this.state = VisitState.completed;
+ this.followRedirect();
+ if (!this.followedRedirect) {
+ this.adapter.visitCompleted(this);
+ this.delegate.visitCompleted(this);
+ }
+ }
+ }
+ fail() {
+ if (this.state == VisitState.started) {
+ this.state = VisitState.failed;
+ this.adapter.visitFailed(this);
+ }
+ }
+ changeHistory() {
+ var _a;
+ if (!this.historyChanged && this.updateHistory) {
+ const actionForHistory = this.location.href === ((_a = this.referrer) === null || _a === void 0 ? void 0 : _a.href) ? "replace" : this.action;
+ const method = getHistoryMethodForAction(actionForHistory);
+ this.history.update(method, this.location, this.restorationIdentifier);
+ this.historyChanged = true;
+ }
+ }
+ issueRequest() {
+ if (this.hasPreloadedResponse()) {
+ this.simulateRequest();
+ }
+ else if (this.shouldIssueRequest() && !this.request) {
+ this.request = new FetchRequest(this, FetchMethod.get, this.location);
+ this.request.perform();
+ }
+ }
+ simulateRequest() {
+ if (this.response) {
+ this.startRequest();
+ this.recordResponse();
+ this.finishRequest();
+ }
+ }
+ startRequest() {
+ this.recordTimingMetric(TimingMetric.requestStart);
+ this.adapter.visitRequestStarted(this);
+ }
+ recordResponse(response = this.response) {
+ this.response = response;
+ if (response) {
+ const { statusCode } = response;
+ if (isSuccessful(statusCode)) {
+ this.adapter.visitRequestCompleted(this);
+ }
+ else {
+ this.adapter.visitRequestFailedWithStatusCode(this, statusCode);
+ }
+ }
+ }
+ finishRequest() {
+ this.recordTimingMetric(TimingMetric.requestEnd);
+ this.adapter.visitRequestFinished(this);
+ }
+ loadResponse() {
+ if (this.response) {
+ const { statusCode, responseHTML } = this.response;
+ this.render(async () => {
+ if (this.shouldCacheSnapshot)
+ this.cacheSnapshot();
+ if (this.view.renderPromise)
+ await this.view.renderPromise;
+ if (isSuccessful(statusCode) && responseHTML != null) {
+ await this.view.renderPage(PageSnapshot.fromHTMLString(responseHTML), false, this.willRender, this);
+ this.performScroll();
+ this.adapter.visitRendered(this);
+ this.complete();
+ }
+ else {
+ await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML), this);
+ this.adapter.visitRendered(this);
+ this.fail();
+ }
+ });
+ }
+ }
+ getCachedSnapshot() {
+ const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot();
+ if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) {
+ if (this.action == "restore" || snapshot.isPreviewable) {
+ return snapshot;
+ }
+ }
+ }
+ getPreloadedSnapshot() {
+ if (this.snapshotHTML) {
+ return PageSnapshot.fromHTMLString(this.snapshotHTML);
+ }
+ }
+ hasCachedSnapshot() {
+ return this.getCachedSnapshot() != null;
+ }
+ loadCachedSnapshot() {
+ const snapshot = this.getCachedSnapshot();
+ if (snapshot) {
+ const isPreview = this.shouldIssueRequest();
+ this.render(async () => {
+ this.cacheSnapshot();
+ if (this.isSamePage) {
+ this.adapter.visitRendered(this);
+ }
+ else {
+ if (this.view.renderPromise)
+ await this.view.renderPromise;
+ await this.view.renderPage(snapshot, isPreview, this.willRender, this);
+ this.performScroll();
+ this.adapter.visitRendered(this);
+ if (!isPreview) {
+ this.complete();
+ }
+ }
+ });
+ }
+ }
+ followRedirect() {
+ var _a;
+ if (this.redirectedToLocation && !this.followedRedirect && ((_a = this.response) === null || _a === void 0 ? void 0 : _a.redirected)) {
+ this.adapter.visitProposedToLocation(this.redirectedToLocation, {
+ action: "replace",
+ response: this.response,
+ shouldCacheSnapshot: false,
+ willRender: false,
+ });
+ this.followedRedirect = true;
+ }
+ }
+ goToSamePageAnchor() {
+ if (this.isSamePage) {
+ this.render(async () => {
+ this.cacheSnapshot();
+ this.performScroll();
+ this.changeHistory();
+ this.adapter.visitRendered(this);
+ });
+ }
+ }
+ prepareRequest(request) {
+ if (this.acceptsStreamResponse) {
+ request.acceptResponseType(StreamMessage.contentType);
+ }
+ }
+ requestStarted() {
+ this.startRequest();
+ }
+ requestPreventedHandlingResponse(_request, _response) { }
+ async requestSucceededWithResponse(request, response) {
+ const responseHTML = await response.responseHTML;
+ const { redirected, statusCode } = response;
+ if (responseHTML == undefined) {
+ this.recordResponse({
+ statusCode: SystemStatusCode.contentTypeMismatch,
+ redirected,
+ });
+ }
+ else {
+ this.redirectedToLocation = response.redirected ? response.location : undefined;
+ this.recordResponse({ statusCode: statusCode, responseHTML, redirected });
+ }
+ }
+ async requestFailedWithResponse(request, response) {
+ const responseHTML = await response.responseHTML;
+ const { redirected, statusCode } = response;
+ if (responseHTML == undefined) {
+ this.recordResponse({
+ statusCode: SystemStatusCode.contentTypeMismatch,
+ redirected,
+ });
+ }
+ else {
+ this.recordResponse({ statusCode: statusCode, responseHTML, redirected });
+ }
+ }
+ requestErrored(_request, _error) {
+ this.recordResponse({
+ statusCode: SystemStatusCode.networkFailure,
+ redirected: false,
+ });
+ }
+ requestFinished() {
+ this.finishRequest();
+ }
+ performScroll() {
+ if (!this.scrolled && !this.view.forceReloaded) {
+ if (this.action == "restore") {
+ this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop();
+ }
+ else {
+ this.scrollToAnchor() || this.view.scrollToTop();
+ }
+ if (this.isSamePage) {
+ this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation, this.location);
+ }
+ this.scrolled = true;
+ }
+ }
+ scrollToRestoredPosition() {
+ const { scrollPosition } = this.restorationData;
+ if (scrollPosition) {
+ this.view.scrollToPosition(scrollPosition);
+ return true;
+ }
+ }
+ scrollToAnchor() {
+ const anchor = getAnchor(this.location);
+ if (anchor != null) {
+ this.view.scrollToAnchor(anchor);
+ return true;
+ }
+ }
+ recordTimingMetric(metric) {
+ this.timingMetrics[metric] = new Date().getTime();
+ }
+ getTimingMetrics() {
+ return Object.assign({}, this.timingMetrics);
+ }
+ getHistoryMethodForAction(action) {
+ switch (action) {
+ case "replace":
+ return history.replaceState;
+ case "advance":
+ case "restore":
+ return history.pushState;
+ }
+ }
+ hasPreloadedResponse() {
+ return typeof this.response == "object";
+ }
+ shouldIssueRequest() {
+ if (this.isSamePage) {
+ return false;
+ }
+ else if (this.action == "restore") {
+ return !this.hasCachedSnapshot();
+ }
+ else {
+ return this.willRender;
+ }
+ }
+ cacheSnapshot() {
+ if (!this.snapshotCached) {
+ this.view.cacheSnapshot(this.snapshot).then((snapshot) => snapshot && this.visitCachedSnapshot(snapshot));
+ this.snapshotCached = true;
+ }
+ }
+ async render(callback) {
+ this.cancelRender();
+ await new Promise((resolve) => {
+ this.frame = requestAnimationFrame(() => resolve());
+ });
+ await callback();
+ delete this.frame;
+ }
+ cancelRender() {
+ if (this.frame) {
+ cancelAnimationFrame(this.frame);
+ delete this.frame;
+ }
+ }
+}
+function isSuccessful(statusCode) {
+ return statusCode >= 200 && statusCode < 300;
+}
+
+class BrowserAdapter {
+ constructor(session) {
+ this.progressBar = new ProgressBar();
+ this.showProgressBar = () => {
+ this.progressBar.show();
+ };
+ this.session = session;
+ }
+ visitProposedToLocation(location, options) {
+ this.navigator.startVisit(location, (options === null || options === void 0 ? void 0 : options.restorationIdentifier) || uuid(), options);
+ }
+ visitStarted(visit) {
+ this.location = visit.location;
+ visit.loadCachedSnapshot();
+ visit.issueRequest();
+ visit.goToSamePageAnchor();
+ }
+ visitRequestStarted(visit) {
+ this.progressBar.setValue(0);
+ if (visit.hasCachedSnapshot() || visit.action != "restore") {
+ this.showVisitProgressBarAfterDelay();
+ }
+ else {
+ this.showProgressBar();
+ }
+ }
+ visitRequestCompleted(visit) {
+ visit.loadResponse();
+ }
+ visitRequestFailedWithStatusCode(visit, statusCode) {
+ switch (statusCode) {
+ case SystemStatusCode.networkFailure:
+ case SystemStatusCode.timeoutFailure:
+ case SystemStatusCode.contentTypeMismatch:
+ return this.reload({
+ reason: "request_failed",
+ context: {
+ statusCode,
+ },
+ });
+ default:
+ return visit.loadResponse();
+ }
+ }
+ visitRequestFinished(_visit) {
+ this.progressBar.setValue(1);
+ this.hideVisitProgressBar();
+ }
+ visitCompleted(_visit) { }
+ pageInvalidated(reason) {
+ this.reload(reason);
+ }
+ visitFailed(_visit) { }
+ visitRendered(_visit) { }
+ formSubmissionStarted(_formSubmission) {
+ this.progressBar.setValue(0);
+ this.showFormProgressBarAfterDelay();
+ }
+ formSubmissionFinished(_formSubmission) {
+ this.progressBar.setValue(1);
+ this.hideFormProgressBar();
+ }
+ showVisitProgressBarAfterDelay() {
+ this.visitProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);
+ }
+ hideVisitProgressBar() {
+ this.progressBar.hide();
+ if (this.visitProgressBarTimeout != null) {
+ window.clearTimeout(this.visitProgressBarTimeout);
+ delete this.visitProgressBarTimeout;
+ }
+ }
+ showFormProgressBarAfterDelay() {
+ if (this.formProgressBarTimeout == null) {
+ this.formProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);
+ }
+ }
+ hideFormProgressBar() {
+ this.progressBar.hide();
+ if (this.formProgressBarTimeout != null) {
+ window.clearTimeout(this.formProgressBarTimeout);
+ delete this.formProgressBarTimeout;
+ }
+ }
+ reload(reason) {
+ var _a;
+ dispatch("turbo:reload", { detail: reason });
+ window.location.href = ((_a = this.location) === null || _a === void 0 ? void 0 : _a.toString()) || window.location.href;
+ }
+ get navigator() {
+ return this.session.navigator;
+ }
+}
+
+class CacheObserver {
+ constructor() {
+ this.selector = "[data-turbo-temporary]";
+ this.deprecatedSelector = "[data-turbo-cache=false]";
+ this.started = false;
+ this.removeTemporaryElements = ((_event) => {
+ for (const element of this.temporaryElements) {
+ element.remove();
+ }
+ });
+ }
+ start() {
+ if (!this.started) {
+ this.started = true;
+ addEventListener("turbo:before-cache", this.removeTemporaryElements, false);
+ }
+ }
+ stop() {
+ if (this.started) {
+ this.started = false;
+ removeEventListener("turbo:before-cache", this.removeTemporaryElements, false);
+ }
+ }
+ get temporaryElements() {
+ return [...document.querySelectorAll(this.selector), ...this.temporaryElementsWithDeprecation];
+ }
+ get temporaryElementsWithDeprecation() {
+ const elements = document.querySelectorAll(this.deprecatedSelector);
+ if (elements.length) {
+ console.warn(`The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.`);
+ }
+ return [...elements];
+ }
+}
+
+class FrameRedirector {
+ constructor(session, element) {
+ this.session = session;
+ this.element = element;
+ this.linkInterceptor = new LinkInterceptor(this, element);
+ this.formSubmitObserver = new FormSubmitObserver(this, element);
+ }
+ start() {
+ this.linkInterceptor.start();
+ this.formSubmitObserver.start();
+ }
+ stop() {
+ this.linkInterceptor.stop();
+ this.formSubmitObserver.stop();
+ }
+ shouldInterceptLinkClick(element, _location, _event) {
+ return this.shouldRedirect(element);
+ }
+ linkClickIntercepted(element, url, event) {
+ const frame = this.findFrameElement(element);
+ if (frame) {
+ frame.delegate.linkClickIntercepted(element, url, event);
+ }
+ }
+ willSubmitForm(element, submitter) {
+ return (element.closest("turbo-frame") == null &&
+ this.shouldSubmit(element, submitter) &&
+ this.shouldRedirect(element, submitter));
+ }
+ formSubmitted(element, submitter) {
+ const frame = this.findFrameElement(element, submitter);
+ if (frame) {
+ frame.delegate.formSubmitted(element, submitter);
+ }
+ }
+ shouldSubmit(form, submitter) {
+ var _a;
+ const action = getAction(form, submitter);
+ const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`);
+ const rootLocation = expandURL((_a = meta === null || meta === void 0 ? void 0 : meta.content) !== null && _a !== void 0 ? _a : "/");
+ return this.shouldRedirect(form, submitter) && locationIsVisitable(action, rootLocation);
+ }
+ shouldRedirect(element, submitter) {
+ const isNavigatable = element instanceof HTMLFormElement
+ ? this.session.submissionIsNavigatable(element, submitter)
+ : this.session.elementIsNavigatable(element);
+ if (isNavigatable) {
+ const frame = this.findFrameElement(element, submitter);
+ return frame ? frame != element.closest("turbo-frame") : false;
+ }
+ else {
+ return false;
+ }
+ }
+ findFrameElement(element, submitter) {
+ const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("data-turbo-frame")) || element.getAttribute("data-turbo-frame");
+ if (id && id != "_top") {
+ const frame = this.element.querySelector(`#${id}:not([disabled])`);
+ if (frame instanceof FrameElement) {
+ return frame;
+ }
+ }
+ }
+}
+
+class History {
+ constructor(delegate) {
+ this.restorationIdentifier = uuid();
+ this.restorationData = {};
+ this.started = false;
+ this.pageLoaded = false;
+ this.onPopState = (event) => {
+ if (this.shouldHandlePopState()) {
+ const { turbo } = event.state || {};
+ if (turbo) {
+ this.location = new URL(window.location.href);
+ const { restorationIdentifier } = turbo;
+ this.restorationIdentifier = restorationIdentifier;
+ this.delegate.historyPoppedToLocationWithRestorationIdentifier(this.location, restorationIdentifier);
+ }
+ }
+ };
+ this.onPageLoad = async (_event) => {
+ await nextMicrotask();
+ this.pageLoaded = true;
+ };
+ this.delegate = delegate;
+ }
+ start() {
+ if (!this.started) {
+ addEventListener("popstate", this.onPopState, false);
+ addEventListener("load", this.onPageLoad, false);
+ this.started = true;
+ this.replace(new URL(window.location.href));
+ }
+ }
+ stop() {
+ if (this.started) {
+ removeEventListener("popstate", this.onPopState, false);
+ removeEventListener("load", this.onPageLoad, false);
+ this.started = false;
+ }
+ }
+ push(location, restorationIdentifier) {
+ this.update(history.pushState, location, restorationIdentifier);
+ }
+ replace(location, restorationIdentifier) {
+ this.update(history.replaceState, location, restorationIdentifier);
+ }
+ update(method, location, restorationIdentifier = uuid()) {
+ const state = { turbo: { restorationIdentifier } };
+ method.call(history, state, "", location.href);
+ this.location = location;
+ this.restorationIdentifier = restorationIdentifier;
+ }
+ getRestorationDataForIdentifier(restorationIdentifier) {
+ return this.restorationData[restorationIdentifier] || {};
+ }
+ updateRestorationData(additionalData) {
+ const { restorationIdentifier } = this;
+ const restorationData = this.restorationData[restorationIdentifier];
+ this.restorationData[restorationIdentifier] = Object.assign(Object.assign({}, restorationData), additionalData);
+ }
+ assumeControlOfScrollRestoration() {
+ var _a;
+ if (!this.previousScrollRestoration) {
+ this.previousScrollRestoration = (_a = history.scrollRestoration) !== null && _a !== void 0 ? _a : "auto";
+ history.scrollRestoration = "manual";
+ }
+ }
+ relinquishControlOfScrollRestoration() {
+ if (this.previousScrollRestoration) {
+ history.scrollRestoration = this.previousScrollRestoration;
+ delete this.previousScrollRestoration;
+ }
+ }
+ shouldHandlePopState() {
+ return this.pageIsLoaded();
+ }
+ pageIsLoaded() {
+ return this.pageLoaded || document.readyState == "complete";
+ }
+}
+
+class Navigator {
+ constructor(delegate) {
+ this.delegate = delegate;
+ }
+ proposeVisit(location, options = {}) {
+ if (this.delegate.allowsVisitingLocationWithAction(location, options.action)) {
+ if (locationIsVisitable(location, this.view.snapshot.rootLocation)) {
+ this.delegate.visitProposedToLocation(location, options);
+ }
+ else {
+ window.location.href = location.toString();
+ }
+ }
+ }
+ startVisit(locatable, restorationIdentifier, options = {}) {
+ this.stop();
+ this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, Object.assign({ referrer: this.location }, options));
+ this.currentVisit.start();
+ }
+ submitForm(form, submitter) {
+ this.stop();
+ this.formSubmission = new FormSubmission(this, form, submitter, true);
+ this.formSubmission.start();
+ }
+ stop() {
+ if (this.formSubmission) {
+ this.formSubmission.stop();
+ delete this.formSubmission;
+ }
+ if (this.currentVisit) {
+ this.currentVisit.cancel();
+ delete this.currentVisit;
+ }
+ }
+ get adapter() {
+ return this.delegate.adapter;
+ }
+ get view() {
+ return this.delegate.view;
+ }
+ get history() {
+ return this.delegate.history;
+ }
+ formSubmissionStarted(formSubmission) {
+ if (typeof this.adapter.formSubmissionStarted === "function") {
+ this.adapter.formSubmissionStarted(formSubmission);
+ }
+ }
+ async formSubmissionSucceededWithResponse(formSubmission, fetchResponse) {
+ if (formSubmission == this.formSubmission) {
+ const responseHTML = await fetchResponse.responseHTML;
+ if (responseHTML) {
+ const shouldCacheSnapshot = formSubmission.isSafe;
+ if (!shouldCacheSnapshot) {
+ this.view.clearSnapshotCache();
+ }
+ const { statusCode, redirected } = fetchResponse;
+ const action = this.getActionForFormSubmission(formSubmission);
+ const visitOptions = {
+ action,
+ shouldCacheSnapshot,
+ response: { statusCode, responseHTML, redirected },
+ };
+ this.proposeVisit(fetchResponse.location, visitOptions);
+ }
+ }
+ }
+ async formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
+ const responseHTML = await fetchResponse.responseHTML;
+ if (responseHTML) {
+ const snapshot = PageSnapshot.fromHTMLString(responseHTML);
+ if (fetchResponse.serverError) {
+ await this.view.renderError(snapshot, this.currentVisit);
+ }
+ else {
+ await this.view.renderPage(snapshot, false, true, this.currentVisit);
+ }
+ this.view.scrollToTop();
+ this.view.clearSnapshotCache();
+ }
+ }
+ formSubmissionErrored(formSubmission, error) {
+ console.error(error);
+ }
+ formSubmissionFinished(formSubmission) {
+ if (typeof this.adapter.formSubmissionFinished === "function") {
+ this.adapter.formSubmissionFinished(formSubmission);
+ }
+ }
+ visitStarted(visit) {
+ this.delegate.visitStarted(visit);
+ }
+ visitCompleted(visit) {
+ this.delegate.visitCompleted(visit);
+ }
+ locationWithActionIsSamePage(location, action) {
+ const anchor = getAnchor(location);
+ const currentAnchor = getAnchor(this.view.lastRenderedLocation);
+ const isRestorationToTop = action === "restore" && typeof anchor === "undefined";
+ return (action !== "replace" &&
+ getRequestURL(location) === getRequestURL(this.view.lastRenderedLocation) &&
+ (isRestorationToTop || (anchor != null && anchor !== currentAnchor)));
+ }
+ visitScrolledToSamePageLocation(oldURL, newURL) {
+ this.delegate.visitScrolledToSamePageLocation(oldURL, newURL);
+ }
+ get location() {
+ return this.history.location;
+ }
+ get restorationIdentifier() {
+ return this.history.restorationIdentifier;
+ }
+ getActionForFormSubmission({ submitter, formElement }) {
+ return getVisitAction(submitter, formElement) || "advance";
+ }
+}
+
+var PageStage;
+(function (PageStage) {
+ PageStage[PageStage["initial"] = 0] = "initial";
+ PageStage[PageStage["loading"] = 1] = "loading";
+ PageStage[PageStage["interactive"] = 2] = "interactive";
+ PageStage[PageStage["complete"] = 3] = "complete";
+})(PageStage || (PageStage = {}));
+class PageObserver {
+ constructor(delegate) {
+ this.stage = PageStage.initial;
+ this.started = false;
+ this.interpretReadyState = () => {
+ const { readyState } = this;
+ if (readyState == "interactive") {
+ this.pageIsInteractive();
+ }
+ else if (readyState == "complete") {
+ this.pageIsComplete();
+ }
+ };
+ this.pageWillUnload = () => {
+ this.delegate.pageWillUnload();
+ };
+ this.delegate = delegate;
+ }
+ start() {
+ if (!this.started) {
+ if (this.stage == PageStage.initial) {
+ this.stage = PageStage.loading;
+ }
+ document.addEventListener("readystatechange", this.interpretReadyState, false);
+ addEventListener("pagehide", this.pageWillUnload, false);
+ this.started = true;
+ }
+ }
+ stop() {
+ if (this.started) {
+ document.removeEventListener("readystatechange", this.interpretReadyState, false);
+ removeEventListener("pagehide", this.pageWillUnload, false);
+ this.started = false;
+ }
+ }
+ pageIsInteractive() {
+ if (this.stage == PageStage.loading) {
+ this.stage = PageStage.interactive;
+ this.delegate.pageBecameInteractive();
+ }
+ }
+ pageIsComplete() {
+ this.pageIsInteractive();
+ if (this.stage == PageStage.interactive) {
+ this.stage = PageStage.complete;
+ this.delegate.pageLoaded();
+ }
+ }
+ get readyState() {
+ return document.readyState;
+ }
+}
+
+class ScrollObserver {
+ constructor(delegate) {
+ this.started = false;
+ this.onScroll = () => {
+ this.updatePosition({ x: window.pageXOffset, y: window.pageYOffset });
+ };
+ this.delegate = delegate;
+ }
+ start() {
+ if (!this.started) {
+ addEventListener("scroll", this.onScroll, false);
+ this.onScroll();
+ this.started = true;
+ }
+ }
+ stop() {
+ if (this.started) {
+ removeEventListener("scroll", this.onScroll, false);
+ this.started = false;
+ }
+ }
+ updatePosition(position) {
+ this.delegate.scrollPositionChanged(position);
+ }
+}
+
+class StreamMessageRenderer {
+ render({ fragment }) {
+ Bardo.preservingPermanentElements(this, getPermanentElementMapForFragment(fragment), () => document.documentElement.appendChild(fragment));
+ }
+ enteringBardo(currentPermanentElement, newPermanentElement) {
+ newPermanentElement.replaceWith(currentPermanentElement.cloneNode(true));
+ }
+ leavingBardo() { }
+}
+function getPermanentElementMapForFragment(fragment) {
+ const permanentElementsInDocument = queryPermanentElementsAll(document.documentElement);
+ const permanentElementMap = {};
+ for (const permanentElementInDocument of permanentElementsInDocument) {
+ const { id } = permanentElementInDocument;
+ for (const streamElement of fragment.querySelectorAll("turbo-stream")) {
+ const elementInStream = getPermanentElementById(streamElement.templateElement.content, id);
+ if (elementInStream) {
+ permanentElementMap[id] = [permanentElementInDocument, elementInStream];
+ }
+ }
+ }
+ return permanentElementMap;
+}
+
+class StreamObserver {
+ constructor(delegate) {
+ this.sources = new Set();
+ this.started = false;
+ this.inspectFetchResponse = ((event) => {
+ const response = fetchResponseFromEvent(event);
+ if (response && fetchResponseIsStream(response)) {
+ event.preventDefault();
+ this.receiveMessageResponse(response);
+ }
+ });
+ this.receiveMessageEvent = (event) => {
+ if (this.started && typeof event.data == "string") {
+ this.receiveMessageHTML(event.data);
+ }
+ };
+ this.delegate = delegate;
+ }
+ start() {
+ if (!this.started) {
+ this.started = true;
+ addEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false);
+ }
+ }
+ stop() {
+ if (this.started) {
+ this.started = false;
+ removeEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false);
+ }
+ }
+ connectStreamSource(source) {
+ if (!this.streamSourceIsConnected(source)) {
+ this.sources.add(source);
+ source.addEventListener("message", this.receiveMessageEvent, false);
+ }
+ }
+ disconnectStreamSource(source) {
+ if (this.streamSourceIsConnected(source)) {
+ this.sources.delete(source);
+ source.removeEventListener("message", this.receiveMessageEvent, false);
+ }
+ }
+ streamSourceIsConnected(source) {
+ return this.sources.has(source);
+ }
+ async receiveMessageResponse(response) {
+ const html = await response.responseHTML;
+ if (html) {
+ this.receiveMessageHTML(html);
+ }
+ }
+ receiveMessageHTML(html) {
+ this.delegate.receivedMessageFromStream(StreamMessage.wrap(html));
+ }
+}
+function fetchResponseFromEvent(event) {
+ var _a;
+ const fetchResponse = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.fetchResponse;
+ if (fetchResponse instanceof FetchResponse) {
+ return fetchResponse;
+ }
+}
+function fetchResponseIsStream(response) {
+ var _a;
+ const contentType = (_a = response.contentType) !== null && _a !== void 0 ? _a : "";
+ return contentType.startsWith(StreamMessage.contentType);
+}
+
+class ErrorRenderer extends Renderer {
+ static renderElement(currentElement, newElement) {
+ const { documentElement, body } = document;
+ documentElement.replaceChild(newElement, body);
+ }
+ async render() {
+ this.replaceHeadAndBody();
+ this.activateScriptElements();
+ }
+ replaceHeadAndBody() {
+ const { documentElement, head } = document;
+ documentElement.replaceChild(this.newHead, head);
+ this.renderElement(this.currentElement, this.newElement);
+ }
+ activateScriptElements() {
+ for (const replaceableElement of this.scriptElements) {
+ const parentNode = replaceableElement.parentNode;
+ if (parentNode) {
+ const element = activateScriptElement(replaceableElement);
+ parentNode.replaceChild(element, replaceableElement);
+ }
+ }
+ }
+ get newHead() {
+ return this.newSnapshot.headSnapshot.element;
+ }
+ get scriptElements() {
+ return document.documentElement.querySelectorAll("script");
+ }
+}
+
+class PageRenderer extends Renderer {
+ static renderElement(currentElement, newElement) {
+ if (document.body && newElement instanceof HTMLBodyElement) {
+ document.body.replaceWith(newElement);
+ }
+ else {
+ document.documentElement.appendChild(newElement);
+ }
+ }
+ get shouldRender() {
+ return this.newSnapshot.isVisitable && this.trackedElementsAreIdentical;
+ }
+ get reloadReason() {
+ if (!this.newSnapshot.isVisitable) {
+ return {
+ reason: "turbo_visit_control_is_reload",
+ };
+ }
+ if (!this.trackedElementsAreIdentical) {
+ return {
+ reason: "tracked_element_mismatch",
+ };
+ }
+ }
+ async prepareToRender() {
+ await this.mergeHead();
+ }
+ async render() {
+ if (this.willRender) {
+ await this.replaceBody();
+ }
+ }
+ finishRendering() {
+ super.finishRendering();
+ if (!this.isPreview) {
+ this.focusFirstAutofocusableElement();
+ }
+ }
+ get currentHeadSnapshot() {
+ return this.currentSnapshot.headSnapshot;
+ }
+ get newHeadSnapshot() {
+ return this.newSnapshot.headSnapshot;
+ }
+ get newElement() {
+ return this.newSnapshot.element;
+ }
+ async mergeHead() {
+ const mergedHeadElements = this.mergeProvisionalElements();
+ const newStylesheetElements = this.copyNewHeadStylesheetElements();
+ this.copyNewHeadScriptElements();
+ await mergedHeadElements;
+ await newStylesheetElements;
+ }
+ async replaceBody() {
+ await this.preservingPermanentElements(async () => {
+ this.activateNewBody();
+ await this.assignNewBody();
+ });
+ }
+ get trackedElementsAreIdentical() {
+ return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature;
+ }
+ async copyNewHeadStylesheetElements() {
+ const loadingElements = [];
+ for (const element of this.newHeadStylesheetElements) {
+ loadingElements.push(waitForLoad(element));
+ document.head.appendChild(element);
+ }
+ await Promise.all(loadingElements);
+ }
+ copyNewHeadScriptElements() {
+ for (const element of this.newHeadScriptElements) {
+ document.head.appendChild(activateScriptElement(element));
+ }
+ }
+ async mergeProvisionalElements() {
+ const newHeadElements = [...this.newHeadProvisionalElements];
+ for (const element of this.currentHeadProvisionalElements) {
+ if (!this.isCurrentElementInElementList(element, newHeadElements)) {
+ document.head.removeChild(element);
+ }
+ }
+ for (const element of newHeadElements) {
+ document.head.appendChild(element);
+ }
+ }
+ isCurrentElementInElementList(element, elementList) {
+ for (const [index, newElement] of elementList.entries()) {
+ if (element.tagName == "TITLE") {
+ if (newElement.tagName != "TITLE") {
+ continue;
+ }
+ if (element.innerHTML == newElement.innerHTML) {
+ elementList.splice(index, 1);
+ return true;
+ }
+ }
+ if (newElement.isEqualNode(element)) {
+ elementList.splice(index, 1);
+ return true;
+ }
+ }
+ return false;
+ }
+ removeCurrentHeadProvisionalElements() {
+ for (const element of this.currentHeadProvisionalElements) {
+ document.head.removeChild(element);
+ }
+ }
+ copyNewHeadProvisionalElements() {
+ for (const element of this.newHeadProvisionalElements) {
+ document.head.appendChild(element);
+ }
+ }
+ activateNewBody() {
+ document.adoptNode(this.newElement);
+ this.activateNewBodyScriptElements();
+ }
+ activateNewBodyScriptElements() {
+ for (const inertScriptElement of this.newBodyScriptElements) {
+ const activatedScriptElement = activateScriptElement(inertScriptElement);
+ inertScriptElement.replaceWith(activatedScriptElement);
+ }
+ }
+ async assignNewBody() {
+ await this.renderElement(this.currentElement, this.newElement);
+ }
+ get newHeadStylesheetElements() {
+ return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot);
+ }
+ get newHeadScriptElements() {
+ return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot);
+ }
+ get currentHeadProvisionalElements() {
+ return this.currentHeadSnapshot.provisionalElements;
+ }
+ get newHeadProvisionalElements() {
+ return this.newHeadSnapshot.provisionalElements;
+ }
+ get newBodyScriptElements() {
+ return this.newElement.querySelectorAll("script");
+ }
+}
+
+class SnapshotCache {
+ constructor(size) {
+ this.keys = [];
+ this.snapshots = {};
+ this.size = size;
+ }
+ has(location) {
+ return toCacheKey(location) in this.snapshots;
+ }
+ get(location) {
+ if (this.has(location)) {
+ const snapshot = this.read(location);
+ this.touch(location);
+ return snapshot;
+ }
+ }
+ put(location, snapshot) {
+ this.write(location, snapshot);
+ this.touch(location);
+ return snapshot;
+ }
+ clear() {
+ this.snapshots = {};
+ }
+ read(location) {
+ return this.snapshots[toCacheKey(location)];
+ }
+ write(location, snapshot) {
+ this.snapshots[toCacheKey(location)] = snapshot;
+ }
+ touch(location) {
+ const key = toCacheKey(location);
+ const index = this.keys.indexOf(key);
+ if (index > -1)
+ this.keys.splice(index, 1);
+ this.keys.unshift(key);
+ this.trim();
+ }
+ trim() {
+ for (const key of this.keys.splice(this.size)) {
+ delete this.snapshots[key];
+ }
+ }
+}
+
+class PageView extends View {
+ constructor() {
+ super(...arguments);
+ this.snapshotCache = new SnapshotCache(10);
+ this.lastRenderedLocation = new URL(location.href);
+ this.forceReloaded = false;
+ }
+ renderPage(snapshot, isPreview = false, willRender = true, visit) {
+ const renderer = new PageRenderer(this.snapshot, snapshot, PageRenderer.renderElement, isPreview, willRender);
+ if (!renderer.shouldRender) {
+ this.forceReloaded = true;
+ }
+ else {
+ visit === null || visit === void 0 ? void 0 : visit.changeHistory();
+ }
+ return this.render(renderer);
+ }
+ renderError(snapshot, visit) {
+ visit === null || visit === void 0 ? void 0 : visit.changeHistory();
+ const renderer = new ErrorRenderer(this.snapshot, snapshot, ErrorRenderer.renderElement, false);
+ return this.render(renderer);
+ }
+ clearSnapshotCache() {
+ this.snapshotCache.clear();
+ }
+ async cacheSnapshot(snapshot = this.snapshot) {
+ if (snapshot.isCacheable) {
+ this.delegate.viewWillCacheSnapshot();
+ const { lastRenderedLocation: location } = this;
+ await nextEventLoopTick();
+ const cachedSnapshot = snapshot.clone();
+ this.snapshotCache.put(location, cachedSnapshot);
+ return cachedSnapshot;
+ }
+ }
+ getCachedSnapshotForLocation(location) {
+ return this.snapshotCache.get(location);
+ }
+ get snapshot() {
+ return PageSnapshot.fromElement(this.element);
+ }
+}
+
+class Preloader {
+ constructor(delegate) {
+ this.selector = "a[data-turbo-preload]";
+ this.delegate = delegate;
+ }
+ get snapshotCache() {
+ return this.delegate.navigator.view.snapshotCache;
+ }
+ start() {
+ if (document.readyState === "loading") {
+ return document.addEventListener("DOMContentLoaded", () => {
+ this.preloadOnLoadLinksForView(document.body);
+ });
+ }
+ else {
+ this.preloadOnLoadLinksForView(document.body);
+ }
+ }
+ preloadOnLoadLinksForView(element) {
+ for (const link of element.querySelectorAll(this.selector)) {
+ this.preloadURL(link);
+ }
+ }
+ async preloadURL(link) {
+ const location = new URL(link.href);
+ if (this.snapshotCache.has(location)) {
+ return;
+ }
+ try {
+ const response = await fetch(location.toString(), { headers: { "VND.PREFETCH": "true", Accept: "text/html" } });
+ const responseText = await response.text();
+ const snapshot = PageSnapshot.fromHTMLString(responseText);
+ this.snapshotCache.put(location, snapshot);
+ }
+ catch (_) {
+ }
+ }
+}
+
+class Session {
+ constructor() {
+ this.navigator = new Navigator(this);
+ this.history = new History(this);
+ this.preloader = new Preloader(this);
+ this.view = new PageView(this, document.documentElement);
+ this.adapter = new BrowserAdapter(this);
+ this.pageObserver = new PageObserver(this);
+ this.cacheObserver = new CacheObserver();
+ this.linkClickObserver = new LinkClickObserver(this, window);
+ this.formSubmitObserver = new FormSubmitObserver(this, document);
+ this.scrollObserver = new ScrollObserver(this);
+ this.streamObserver = new StreamObserver(this);
+ this.formLinkClickObserver = new FormLinkClickObserver(this, document.documentElement);
+ this.frameRedirector = new FrameRedirector(this, document.documentElement);
+ this.streamMessageRenderer = new StreamMessageRenderer();
+ this.drive = true;
+ this.enabled = true;
+ this.progressBarDelay = 500;
+ this.started = false;
+ this.formMode = "on";
+ }
+ start() {
+ if (!this.started) {
+ this.pageObserver.start();
+ this.cacheObserver.start();
+ this.formLinkClickObserver.start();
+ this.linkClickObserver.start();
+ this.formSubmitObserver.start();
+ this.scrollObserver.start();
+ this.streamObserver.start();
+ this.frameRedirector.start();
+ this.history.start();
+ this.preloader.start();
+ this.started = true;
+ this.enabled = true;
+ }
+ }
+ disable() {
+ this.enabled = false;
+ }
+ stop() {
+ if (this.started) {
+ this.pageObserver.stop();
+ this.cacheObserver.stop();
+ this.formLinkClickObserver.stop();
+ this.linkClickObserver.stop();
+ this.formSubmitObserver.stop();
+ this.scrollObserver.stop();
+ this.streamObserver.stop();
+ this.frameRedirector.stop();
+ this.history.stop();
+ this.started = false;
+ }
+ }
+ registerAdapter(adapter) {
+ this.adapter = adapter;
+ }
+ visit(location, options = {}) {
+ const frameElement = options.frame ? document.getElementById(options.frame) : null;
+ if (frameElement instanceof FrameElement) {
+ frameElement.src = location.toString();
+ frameElement.loaded;
+ }
+ else {
+ this.navigator.proposeVisit(expandURL(location), options);
+ }
+ }
+ connectStreamSource(source) {
+ this.streamObserver.connectStreamSource(source);
+ }
+ disconnectStreamSource(source) {
+ this.streamObserver.disconnectStreamSource(source);
+ }
+ renderStreamMessage(message) {
+ this.streamMessageRenderer.render(StreamMessage.wrap(message));
+ }
+ clearCache() {
+ this.view.clearSnapshotCache();
+ }
+ setProgressBarDelay(delay) {
+ this.progressBarDelay = delay;
+ }
+ setFormMode(mode) {
+ this.formMode = mode;
+ }
+ get location() {
+ return this.history.location;
+ }
+ get restorationIdentifier() {
+ return this.history.restorationIdentifier;
+ }
+ historyPoppedToLocationWithRestorationIdentifier(location, restorationIdentifier) {
+ if (this.enabled) {
+ this.navigator.startVisit(location, restorationIdentifier, {
+ action: "restore",
+ historyChanged: true,
+ });
+ }
+ else {
+ this.adapter.pageInvalidated({
+ reason: "turbo_disabled",
+ });
+ }
+ }
+ scrollPositionChanged(position) {
+ this.history.updateRestorationData({ scrollPosition: position });
+ }
+ willSubmitFormLinkToLocation(link, location) {
+ return this.elementIsNavigatable(link) && locationIsVisitable(location, this.snapshot.rootLocation);
+ }
+ submittedFormLinkToLocation() { }
+ willFollowLinkToLocation(link, location, event) {
+ return (this.elementIsNavigatable(link) &&
+ locationIsVisitable(location, this.snapshot.rootLocation) &&
+ this.applicationAllowsFollowingLinkToLocation(link, location, event));
+ }
+ followedLinkToLocation(link, location) {
+ const action = this.getActionForLink(link);
+ const acceptsStreamResponse = link.hasAttribute("data-turbo-stream");
+ this.visit(location.href, { action, acceptsStreamResponse });
+ }
+ allowsVisitingLocationWithAction(location, action) {
+ return this.locationWithActionIsSamePage(location, action) || this.applicationAllowsVisitingLocation(location);
+ }
+ visitProposedToLocation(location, options) {
+ extendURLWithDeprecatedProperties(location);
+ this.adapter.visitProposedToLocation(location, options);
+ }
+ visitStarted(visit) {
+ if (!visit.acceptsStreamResponse) {
+ markAsBusy(document.documentElement);
+ }
+ extendURLWithDeprecatedProperties(visit.location);
+ if (!visit.silent) {
+ this.notifyApplicationAfterVisitingLocation(visit.location, visit.action);
+ }
+ }
+ visitCompleted(visit) {
+ clearBusyState(document.documentElement);
+ this.notifyApplicationAfterPageLoad(visit.getTimingMetrics());
+ }
+ locationWithActionIsSamePage(location, action) {
+ return this.navigator.locationWithActionIsSamePage(location, action);
+ }
+ visitScrolledToSamePageLocation(oldURL, newURL) {
+ this.notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL);
+ }
+ willSubmitForm(form, submitter) {
+ const action = getAction(form, submitter);
+ return (this.submissionIsNavigatable(form, submitter) &&
+ locationIsVisitable(expandURL(action), this.snapshot.rootLocation));
+ }
+ formSubmitted(form, submitter) {
+ this.navigator.submitForm(form, submitter);
+ }
+ pageBecameInteractive() {
+ this.view.lastRenderedLocation = this.location;
+ this.notifyApplicationAfterPageLoad();
+ }
+ pageLoaded() {
+ this.history.assumeControlOfScrollRestoration();
+ }
+ pageWillUnload() {
+ this.history.relinquishControlOfScrollRestoration();
+ }
+ receivedMessageFromStream(message) {
+ this.renderStreamMessage(message);
+ }
+ viewWillCacheSnapshot() {
+ var _a;
+ if (!((_a = this.navigator.currentVisit) === null || _a === void 0 ? void 0 : _a.silent)) {
+ this.notifyApplicationBeforeCachingSnapshot();
+ }
+ }
+ allowsImmediateRender({ element }, options) {
+ const event = this.notifyApplicationBeforeRender(element, options);
+ const { defaultPrevented, detail: { render }, } = event;
+ if (this.view.renderer && render) {
+ this.view.renderer.renderElement = render;
+ }
+ return !defaultPrevented;
+ }
+ viewRenderedSnapshot(_snapshot, _isPreview) {
+ this.view.lastRenderedLocation = this.history.location;
+ this.notifyApplicationAfterRender();
+ }
+ preloadOnLoadLinksForView(element) {
+ this.preloader.preloadOnLoadLinksForView(element);
+ }
+ viewInvalidated(reason) {
+ this.adapter.pageInvalidated(reason);
+ }
+ frameLoaded(frame) {
+ this.notifyApplicationAfterFrameLoad(frame);
+ }
+ frameRendered(fetchResponse, frame) {
+ this.notifyApplicationAfterFrameRender(fetchResponse, frame);
+ }
+ applicationAllowsFollowingLinkToLocation(link, location, ev) {
+ const event = this.notifyApplicationAfterClickingLinkToLocation(link, location, ev);
+ return !event.defaultPrevented;
+ }
+ applicationAllowsVisitingLocation(location) {
+ const event = this.notifyApplicationBeforeVisitingLocation(location);
+ return !event.defaultPrevented;
+ }
+ notifyApplicationAfterClickingLinkToLocation(link, location, event) {
+ return dispatch("turbo:click", {
+ target: link,
+ detail: { url: location.href, originalEvent: event },
+ cancelable: true,
+ });
+ }
+ notifyApplicationBeforeVisitingLocation(location) {
+ return dispatch("turbo:before-visit", {
+ detail: { url: location.href },
+ cancelable: true,
+ });
+ }
+ notifyApplicationAfterVisitingLocation(location, action) {
+ return dispatch("turbo:visit", { detail: { url: location.href, action } });
+ }
+ notifyApplicationBeforeCachingSnapshot() {
+ return dispatch("turbo:before-cache");
+ }
+ notifyApplicationBeforeRender(newBody, options) {
+ return dispatch("turbo:before-render", {
+ detail: Object.assign({ newBody }, options),
+ cancelable: true,
+ });
+ }
+ notifyApplicationAfterRender() {
+ return dispatch("turbo:render");
+ }
+ notifyApplicationAfterPageLoad(timing = {}) {
+ return dispatch("turbo:load", {
+ detail: { url: this.location.href, timing },
+ });
+ }
+ notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL) {
+ dispatchEvent(new HashChangeEvent("hashchange", {
+ oldURL: oldURL.toString(),
+ newURL: newURL.toString(),
+ }));
+ }
+ notifyApplicationAfterFrameLoad(frame) {
+ return dispatch("turbo:frame-load", { target: frame });
+ }
+ notifyApplicationAfterFrameRender(fetchResponse, frame) {
+ return dispatch("turbo:frame-render", {
+ detail: { fetchResponse },
+ target: frame,
+ cancelable: true,
+ });
+ }
+ submissionIsNavigatable(form, submitter) {
+ if (this.formMode == "off") {
+ return false;
+ }
+ else {
+ const submitterIsNavigatable = submitter ? this.elementIsNavigatable(submitter) : true;
+ if (this.formMode == "optin") {
+ return submitterIsNavigatable && form.closest(''[data-turbo="true"]'') != null;
+ }
+ else {
+ return submitterIsNavigatable && this.elementIsNavigatable(form);
+ }
+ }
+ }
+ elementIsNavigatable(element) {
+ const container = findClosestRecursively(element, "[data-turbo]");
+ const withinFrame = findClosestRecursively(element, "turbo-frame");
+ if (this.drive || withinFrame) {
+ if (container) {
+ return container.getAttribute("data-turbo") != "false";
+ }
+ else {
+ return true;
+ }
+ }
+ else {
+ if (container) {
+ return container.getAttribute("data-turbo") == "true";
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ getActionForLink(link) {
+ return getVisitAction(link) || "advance";
+ }
+ get snapshot() {
+ return this.view.snapshot;
+ }
+}
+function extendURLWithDeprecatedProperties(url) {
+ Object.defineProperties(url, deprecatedLocationPropertyDescriptors);
+}
+const deprecatedLocationPropertyDescriptors = {
+ absoluteURL: {
+ get() {
+ return this.toString();
+ },
+ },
+};
+
+class Cache {
+ constructor(session) {
+ this.session = session;
+ }
+ clear() {
+ this.session.clearCache();
+ }
+ resetCacheControl() {
+ this.setCacheControl("");
+ }
+ exemptPageFromCache() {
+ this.setCacheControl("no-cache");
+ }
+ exemptPageFromPreview() {
+ this.setCacheControl("no-preview");
+ }
+ setCacheControl(value) {
+ setMetaContent("turbo-cache-control", value);
+ }
+}
+
+const StreamActions = {
+ after() {
+ this.targetElements.forEach((e) => { var _a; return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e.nextSibling); });
+ },
+ append() {
+ this.removeDuplicateTargetChildren();
+ this.targetElements.forEach((e) => e.append(this.templateContent));
+ },
+ before() {
+ this.targetElements.forEach((e) => { var _a; return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e); });
+ },
+ prepend() {
+ this.removeDuplicateTargetChildren();
+ this.targetElements.forEach((e) => e.prepend(this.templateContent));
+ },
+ remove() {
+ this.targetElements.forEach((e) => e.remove());
+ },
+ replace() {
+ this.targetElements.forEach((e) => e.replaceWith(this.templateContent));
+ },
+ update() {
+ this.targetElements.forEach((targetElement) => {
+ targetElement.innerHTML = "";
+ targetElement.append(this.templateContent);
+ });
+ },
+};
+
+const session = new Session();
+const cache = new Cache(session);
+const { navigator: navigator$1 } = session;
+function start() {
+ session.start();
+}
+function registerAdapter(adapter) {
+ session.registerAdapter(adapter);
+}
+function visit(location, options) {
+ session.visit(location, options);
+}
+function connectStreamSource(source) {
+ session.connectStreamSource(source);
+}
+function disconnectStreamSource(source) {
+ session.disconnectStreamSource(source);
+}
+function renderStreamMessage(message) {
+ session.renderStreamMessage(message);
+}
+function clearCache() {
+ console.warn("Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`");
+ session.clearCache();
+}
+function setProgressBarDelay(delay) {
+ session.setProgressBarDelay(delay);
+}
+function setConfirmMethod(confirmMethod) {
+ FormSubmission.confirmMethod = confirmMethod;
+}
+function setFormMode(mode) {
+ session.setFormMode(mode);
+}
+
+var Turbo = /*#__PURE__*/Object.freeze({
+ __proto__: null,
+ navigator: navigator$1,
+ session: session,
+ cache: cache,
+ PageRenderer: PageRenderer,
+ PageSnapshot: PageSnapshot,
+ FrameRenderer: FrameRenderer,
+ start: start,
+ registerAdapter: registerAdapter,
+ visit: visit,
+ connectStreamSource: connectStreamSource,
+ disconnectStreamSource: disconnectStreamSource,
+ renderStreamMessage: renderStreamMessage,
+ clearCache: clearCache,
+ setProgressBarDelay: setProgressBarDelay,
+ setConfirmMethod: setConfirmMethod,
+ setFormMode: setFormMode,
+ StreamActions: StreamActions
+});
+
+class TurboFrameMissingError extends Error {
+}
+
+class FrameController {
+ constructor(element) {
+ this.fetchResponseLoaded = (_fetchResponse) => { };
+ this.currentFetchRequest = null;
+ this.resolveVisitPromise = () => { };
+ this.connected = false;
+ this.hasBeenLoaded = false;
+ this.ignoredAttributes = new Set();
+ this.action = null;
+ this.visitCachedSnapshot = ({ element }) => {
+ const frame = element.querySelector("#" + this.element.id);
+ if (frame && this.previousFrameElement) {
+ frame.replaceChildren(...this.previousFrameElement.children);
+ }
+ delete this.previousFrameElement;
+ };
+ this.element = element;
+ this.view = new FrameView(this, this.element);
+ this.appearanceObserver = new AppearanceObserver(this, this.element);
+ this.formLinkClickObserver = new FormLinkClickObserver(this, this.element);
+ this.linkInterceptor = new LinkInterceptor(this, this.element);
+ this.restorationIdentifier = uuid();
+ this.formSubmitObserver = new FormSubmitObserver(this, this.element);
+ }
+ connect() {
+ if (!this.connected) {
+ this.connected = true;
+ if (this.loadingStyle == FrameLoadingStyle.lazy) {
+ this.appearanceObserver.start();
+ }
+ else {
+ this.loadSourceURL();
+ }
+ this.formLinkClickObserver.start();
+ this.linkInterceptor.start();
+ this.formSubmitObserver.start();
+ }
+ }
+ disconnect() {
+ if (this.connected) {
+ this.connected = false;
+ this.appearanceObserver.stop();
+ this.formLinkClickObserver.stop();
+ this.linkInterceptor.stop();
+ this.formSubmitObserver.stop();
+ }
+ }
+ disabledChanged() {
+ if (this.loadingStyle == FrameLoadingStyle.eager) {
+ this.loadSourceURL();
+ }
+ }
+ sourceURLChanged() {
+ if (this.isIgnoringChangesTo("src"))
+ return;
+ if (this.element.isConnected) {
+ this.complete = false;
+ }
+ if (this.loadingStyle == FrameLoadingStyle.eager || this.hasBeenLoaded) {
+ this.loadSourceURL();
+ }
+ }
+ sourceURLReloaded() {
+ const { src } = this.element;
+ this.ignoringChangesToAttribute("complete", () => {
+ this.element.removeAttribute("complete");
+ });
+ this.element.src = null;
+ this.element.src = src;
+ return this.element.loaded;
+ }
+ completeChanged() {
+ if (this.isIgnoringChangesTo("complete"))
+ return;
+ this.loadSourceURL();
+ }
+ loadingStyleChanged() {
+ if (this.loadingStyle == FrameLoadingStyle.lazy) {
+ this.appearanceObserver.start();
+ }
+ else {
+ this.appearanceObserver.stop();
+ this.loadSourceURL();
+ }
+ }
+ async loadSourceURL() {
+ if (this.enabled && this.isActive && !this.complete && this.sourceURL) {
+ this.element.loaded = this.visit(expandURL(this.sourceURL));
+ this.appearanceObserver.stop();
+ await this.element.loaded;
+ this.hasBeenLoaded = true;
+ }
+ }
+ async loadResponse(fetchResponse) {
+ if (fetchResponse.redirected || (fetchResponse.succeeded && fetchResponse.isHTML)) {
+ this.sourceURL = fetchResponse.response.url;
+ }
+ try {
+ const html = await fetchResponse.responseHTML;
+ if (html) {
+ const document = parseHTMLDocument(html);
+ const pageSnapshot = PageSnapshot.fromDocument(document);
+ if (pageSnapshot.isVisitable) {
+ await this.loadFrameResponse(fetchResponse, document);
+ }
+ else {
+ await this.handleUnvisitableFrameResponse(fetchResponse);
+ }
+ }
+ }
+ finally {
+ this.fetchResponseLoaded = () => { };
+ }
+ }
+ elementAppearedInViewport(element) {
+ this.proposeVisitIfNavigatedWithAction(element, element);
+ this.loadSourceURL();
+ }
+ willSubmitFormLinkToLocation(link) {
+ return this.shouldInterceptNavigation(link);
+ }
+ submittedFormLinkToLocation(link, _location, form) {
+ const frame = this.findFrameElement(link);
+ if (frame)
+ form.setAttribute("data-turbo-frame", frame.id);
+ }
+ shouldInterceptLinkClick(element, _location, _event) {
+ return this.shouldInterceptNavigation(element);
+ }
+ linkClickIntercepted(element, location) {
+ this.navigateFrame(element, location);
+ }
+ willSubmitForm(element, submitter) {
+ return element.closest("turbo-frame") == this.element && this.shouldInterceptNavigation(element, submitter);
+ }
+ formSubmitted(element, submitter) {
+ if (this.formSubmission) {
+ this.formSubmission.stop();
+ }
+ this.formSubmission = new FormSubmission(this, element, submitter);
+ const { fetchRequest } = this.formSubmission;
+ this.prepareRequest(fetchRequest);
+ this.formSubmission.start();
+ }
+ prepareRequest(request) {
+ var _a;
+ request.headers["Turbo-Frame"] = this.id;
+ if ((_a = this.currentNavigationElement) === null || _a === void 0 ? void 0 : _a.hasAttribute("data-turbo-stream")) {
+ request.acceptResponseType(StreamMessage.contentType);
+ }
+ }
+ requestStarted(_request) {
+ markAsBusy(this.element);
+ }
+ requestPreventedHandlingResponse(_request, _response) {
+ this.resolveVisitPromise();
+ }
+ async requestSucceededWithResponse(request, response) {
+ await this.loadResponse(response);
+ this.resolveVisitPromise();
+ }
+ async requestFailedWithResponse(request, response) {
+ await this.loadResponse(response);
+ this.resolveVisitPromise();
+ }
+ requestErrored(request, error) {
+ console.error(error);
+ this.resolveVisitPromise();
+ }
+ requestFinished(_request) {
+ clearBusyState(this.element);
+ }
+ formSubmissionStarted({ formElement }) {
+ markAsBusy(formElement, this.findFrameElement(formElement));
+ }
+ formSubmissionSucceededWithResponse(formSubmission, response) {
+ const frame = this.findFrameElement(formSubmission.formElement, formSubmission.submitter);
+ frame.delegate.proposeVisitIfNavigatedWithAction(frame, formSubmission.formElement, formSubmission.submitter);
+ frame.delegate.loadResponse(response);
+ if (!formSubmission.isSafe) {
+ session.clearCache();
+ }
+ }
+ formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
+ this.element.delegate.loadResponse(fetchResponse);
+ session.clearCache();
+ }
+ formSubmissionErrored(formSubmission, error) {
+ console.error(error);
+ }
+ formSubmissionFinished({ formElement }) {
+ clearBusyState(formElement, this.findFrameElement(formElement));
+ }
+ allowsImmediateRender({ element: newFrame }, options) {
+ const event = dispatch("turbo:before-frame-render", {
+ target: this.element,
+ detail: Object.assign({ newFrame }, options),
+ cancelable: true,
+ });
+ const { defaultPrevented, detail: { render }, } = event;
+ if (this.view.renderer && render) {
+ this.view.renderer.renderElement = render;
+ }
+ return !defaultPrevented;
+ }
+ viewRenderedSnapshot(_snapshot, _isPreview) { }
+ preloadOnLoadLinksForView(element) {
+ session.preloadOnLoadLinksForView(element);
+ }
+ viewInvalidated() { }
+ willRenderFrame(currentElement, _newElement) {
+ this.previousFrameElement = currentElement.cloneNode(true);
+ }
+ async loadFrameResponse(fetchResponse, document) {
+ const newFrameElement = await this.extractForeignFrameElement(document.body);
+ if (newFrameElement) {
+ const snapshot = new Snapshot(newFrameElement);
+ const renderer = new FrameRenderer(this, this.view.snapshot, snapshot, FrameRenderer.renderElement, false, false);
+ if (this.view.renderPromise)
+ await this.view.renderPromise;
+ this.changeHistory();
+ await this.view.render(renderer);
+ this.complete = true;
+ session.frameRendered(fetchResponse, this.element);
+ session.frameLoaded(this.element);
+ this.fetchResponseLoaded(fetchResponse);
+ }
+ else if (this.willHandleFrameMissingFromResponse(fetchResponse)) {
+ this.handleFrameMissingFromResponse(fetchResponse);
+ }
+ }
+ async visit(url) {
+ var _a;
+ const request = new FetchRequest(this, FetchMethod.get, url, new URLSearchParams(), this.element);
+ (_a = this.currentFetchRequest) === null || _a === void 0 ? void 0 : _a.cancel();
+ this.currentFetchRequest = request;
+ return new Promise((resolve) => {
+ this.resolveVisitPromise = () => {
+ this.resolveVisitPromise = () => { };
+ this.currentFetchRequest = null;
+ resolve();
+ };
+ request.perform();
+ });
+ }
+ navigateFrame(element, url, submitter) {
+ const frame = this.findFrameElement(element, submitter);
+ frame.delegate.proposeVisitIfNavigatedWithAction(frame, element, submitter);
+ this.withCurrentNavigationElement(element, () => {
+ frame.src = url;
+ });
+ }
+ proposeVisitIfNavigatedWithAction(frame, element, submitter) {
+ this.action = getVisitAction(submitter, element, frame);
+ if (this.action) {
+ const pageSnapshot = PageSnapshot.fromElement(frame).clone();
+ const { visitCachedSnapshot } = frame.delegate;
+ frame.delegate.fetchResponseLoaded = (fetchResponse) => {
+ if (frame.src) {
+ const { statusCode, redirected } = fetchResponse;
+ const responseHTML = frame.ownerDocument.documentElement.outerHTML;
+ const response = { statusCode, redirected, responseHTML };
+ const options = {
+ response,
+ visitCachedSnapshot,
+ willRender: false,
+ updateHistory: false,
+ restorationIdentifier: this.restorationIdentifier,
+ snapshot: pageSnapshot,
+ };
+ if (this.action)
+ options.action = this.action;
+ session.visit(frame.src, options);
+ }
+ };
+ }
+ }
+ changeHistory() {
+ if (this.action) {
+ const method = getHistoryMethodForAction(this.action);
+ session.history.update(method, expandURL(this.element.src || ""), this.restorationIdentifier);
+ }
+ }
+ async handleUnvisitableFrameResponse(fetchResponse) {
+ console.warn(`The response (${fetchResponse.statusCode}) from is performing a full page visit due to turbo-visit-control.`);
+ await this.visitResponse(fetchResponse.response);
+ }
+ willHandleFrameMissingFromResponse(fetchResponse) {
+ this.element.setAttribute("complete", "");
+ const response = fetchResponse.response;
+ const visit = async (url, options = {}) => {
+ if (url instanceof Response) {
+ this.visitResponse(url);
+ }
+ else {
+ session.visit(url, options);
+ }
+ };
+ const event = dispatch("turbo:frame-missing", {
+ target: this.element,
+ detail: { response, visit },
+ cancelable: true,
+ });
+ return !event.defaultPrevented;
+ }
+ handleFrameMissingFromResponse(fetchResponse) {
+ this.view.missing();
+ this.throwFrameMissingError(fetchResponse);
+ }
+ throwFrameMissingError(fetchResponse) {
+ const message = `The response (${fetchResponse.statusCode}) did not contain the expected and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`;
+ throw new TurboFrameMissingError(message);
+ }
+ async visitResponse(response) {
+ const wrapped = new FetchResponse(response);
+ const responseHTML = await wrapped.responseHTML;
+ const { location, redirected, statusCode } = wrapped;
+ return session.visit(location, { response: { redirected, statusCode, responseHTML } });
+ }
+ findFrameElement(element, submitter) {
+ var _a;
+ const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target");
+ return (_a = getFrameElementById(id)) !== null && _a !== void 0 ? _a : this.element;
+ }
+ async extractForeignFrameElement(container) {
+ let element;
+ const id = CSS.escape(this.id);
+ try {
+ element = activateElement(container.querySelector(`turbo-frame#${id}`), this.sourceURL);
+ if (element) {
+ return element;
+ }
+ element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.sourceURL);
+ if (element) {
+ await element.loaded;
+ return await this.extractForeignFrameElement(element);
+ }
+ }
+ catch (error) {
+ console.error(error);
+ return new FrameElement();
+ }
+ return null;
+ }
+ formActionIsVisitable(form, submitter) {
+ const action = getAction(form, submitter);
+ return locationIsVisitable(expandURL(action), this.rootLocation);
+ }
+ shouldInterceptNavigation(element, submitter) {
+ const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target");
+ if (element instanceof HTMLFormElement && !this.formActionIsVisitable(element, submitter)) {
+ return false;
+ }
+ if (!this.enabled || id == "_top") {
+ return false;
+ }
+ if (id) {
+ const frameElement = getFrameElementById(id);
+ if (frameElement) {
+ return !frameElement.disabled;
+ }
+ }
+ if (!session.elementIsNavigatable(element)) {
+ return false;
+ }
+ if (submitter && !session.elementIsNavigatable(submitter)) {
+ return false;
+ }
+ return true;
+ }
+ get id() {
+ return this.element.id;
+ }
+ get enabled() {
+ return !this.element.disabled;
+ }
+ get sourceURL() {
+ if (this.element.src) {
+ return this.element.src;
+ }
+ }
+ set sourceURL(sourceURL) {
+ this.ignoringChangesToAttribute("src", () => {
+ this.element.src = sourceURL !== null && sourceURL !== void 0 ? sourceURL : null;
+ });
+ }
+ get loadingStyle() {
+ return this.element.loading;
+ }
+ get isLoading() {
+ return this.formSubmission !== undefined || this.resolveVisitPromise() !== undefined;
+ }
+ get complete() {
+ return this.element.hasAttribute("complete");
+ }
+ set complete(value) {
+ this.ignoringChangesToAttribute("complete", () => {
+ if (value) {
+ this.element.setAttribute("complete", "");
+ }
+ else {
+ this.element.removeAttribute("complete");
+ }
+ });
+ }
+ get isActive() {
+ return this.element.isActive && this.connected;
+ }
+ get rootLocation() {
+ var _a;
+ const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`);
+ const root = (_a = meta === null || meta === void 0 ? void 0 : meta.content) !== null && _a !== void 0 ? _a : "/";
+ return expandURL(root);
+ }
+ isIgnoringChangesTo(attributeName) {
+ return this.ignoredAttributes.has(attributeName);
+ }
+ ignoringChangesToAttribute(attributeName, callback) {
+ this.ignoredAttributes.add(attributeName);
+ callback();
+ this.ignoredAttributes.delete(attributeName);
+ }
+ withCurrentNavigationElement(element, callback) {
+ this.currentNavigationElement = element;
+ callback();
+ delete this.currentNavigationElement;
+ }
+}
+function getFrameElementById(id) {
+ if (id != null) {
+ const element = document.getElementById(id);
+ if (element instanceof FrameElement) {
+ return element;
+ }
+ }
+}
+function activateElement(element, currentURL) {
+ if (element) {
+ const src = element.getAttribute("src");
+ if (src != null && currentURL != null && urlsAreEqual(src, currentURL)) {
+ throw new Error(`Matching element has a source URL which references itself`);
+ }
+ if (element.ownerDocument !== document) {
+ element = document.importNode(element, true);
+ }
+ if (element instanceof FrameElement) {
+ element.connectedCallback();
+ element.disconnectedCallback();
+ return element;
+ }
+ }
+}
+
+class StreamElement extends HTMLElement {
+ static async renderElement(newElement) {
+ await newElement.performAction();
+ }
+ async connectedCallback() {
+ try {
+ await this.render();
+ }
+ catch (error) {
+ console.error(error);
+ }
+ finally {
+ this.disconnect();
+ }
+ }
+ async render() {
+ var _a;
+ return ((_a = this.renderPromise) !== null && _a !== void 0 ? _a : (this.renderPromise = (async () => {
+ const event = this.beforeRenderEvent;
+ if (this.dispatchEvent(event)) {
+ await nextAnimationFrame();
+ await event.detail.render(this);
+ }
+ })()));
+ }
+ disconnect() {
+ try {
+ this.remove();
+ }
+ catch (_a) { }
+ }
+ removeDuplicateTargetChildren() {
+ this.duplicateChildren.forEach((c) => c.remove());
+ }
+ get duplicateChildren() {
+ var _a;
+ const existingChildren = this.targetElements.flatMap((e) => [...e.children]).filter((c) => !!c.id);
+ const newChildrenIds = [...(((_a = this.templateContent) === null || _a === void 0 ? void 0 : _a.children) || [])].filter((c) => !!c.id).map((c) => c.id);
+ return existingChildren.filter((c) => newChildrenIds.includes(c.id));
+ }
+ get performAction() {
+ if (this.action) {
+ const actionFunction = StreamActions[this.action];
+ if (actionFunction) {
+ return actionFunction;
+ }
+ this.raise("unknown action");
+ }
+ this.raise("action attribute is missing");
+ }
+ get targetElements() {
+ if (this.target) {
+ return this.targetElementsById;
+ }
+ else if (this.targets) {
+ return this.targetElementsByQuery;
+ }
+ else {
+ this.raise("target or targets attribute is missing");
+ }
+ }
+ get templateContent() {
+ return this.templateElement.content.cloneNode(true);
+ }
+ get templateElement() {
+ if (this.firstElementChild === null) {
+ const template = this.ownerDocument.createElement("template");
+ this.appendChild(template);
+ return template;
+ }
+ else if (this.firstElementChild instanceof HTMLTemplateElement) {
+ return this.firstElementChild;
+ }
+ this.raise("first child element must be a element");
+ }
+ get action() {
+ return this.getAttribute("action");
+ }
+ get target() {
+ return this.getAttribute("target");
+ }
+ get targets() {
+ return this.getAttribute("targets");
+ }
+ raise(message) {
+ throw new Error(`${this.description}: ${message}`);
+ }
+ get description() {
+ var _a, _b;
+ return (_b = ((_a = this.outerHTML.match(/<[^>]+>/)) !== null && _a !== void 0 ? _a : [])[0]) !== null && _b !== void 0 ? _b : "";
+ }
+ get beforeRenderEvent() {
+ return new CustomEvent("turbo:before-stream-render", {
+ bubbles: true,
+ cancelable: true,
+ detail: { newStream: this, render: StreamElement.renderElement },
+ });
+ }
+ get targetElementsById() {
+ var _a;
+ const element = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.getElementById(this.target);
+ if (element !== null) {
+ return [element];
+ }
+ else {
+ return [];
+ }
+ }
+ get targetElementsByQuery() {
+ var _a;
+ const elements = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.querySelectorAll(this.targets);
+ if (elements.length !== 0) {
+ return Array.prototype.slice.call(elements);
+ }
+ else {
+ return [];
+ }
+ }
+}
+
+class StreamSourceElement extends HTMLElement {
+ constructor() {
+ super(...arguments);
+ this.streamSource = null;
+ }
+ connectedCallback() {
+ this.streamSource = this.src.match(/^ws{1,2}:/) ? new WebSocket(this.src) : new EventSource(this.src);
+ connectStreamSource(this.streamSource);
+ }
+ disconnectedCallback() {
+ if (this.streamSource) {
+ disconnectStreamSource(this.streamSource);
+ }
+ }
+ get src() {
+ return this.getAttribute("src") || "";
+ }
+}
+
+FrameElement.delegateConstructor = FrameController;
+if (customElements.get("turbo-frame") === undefined) {
+ customElements.define("turbo-frame", FrameElement);
+}
+if (customElements.get("turbo-stream") === undefined) {
+ customElements.define("turbo-stream", StreamElement);
+}
+if (customElements.get("turbo-stream-source") === undefined) {
+ customElements.define("turbo-stream-source", StreamSourceElement);
+}
+
+(() => {
+ let element = document.currentScript;
+ if (!element)
+ return;
+ if (element.hasAttribute("data-turbo-suppress-warning"))
+ return;
+ element = element.parentElement;
+ while (element) {
+ if (element == document.body) {
+ return console.warn(unindent `
+ You are loading Turbo from a '.
self
assert: [ :html | html script defer; with: 'alert("")' ]
- gives: ''
\ No newline at end of file
+ gives: ''.
+ self
+ assert: [ :html | html script type: 'module'; with: 'alert("")' ]
+ gives: ''
\ No newline at end of file
diff --git a/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/.filetree b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/.filetree
new file mode 100644
index 000000000..57a679737
--- /dev/null
+++ b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/.filetree
@@ -0,0 +1,5 @@
+{
+ "separateMethodMetaAndSource" : false,
+ "noMethodMetaData" : true,
+ "useCypressPropertiesFile" : true
+}
\ No newline at end of file
diff --git a/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/WAJsonStreamTest.extension/instance/testOrderedDictionary.st b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/WAJsonStreamTest.extension/instance/testOrderedDictionary.st
new file mode 100644
index 000000000..504c723d7
--- /dev/null
+++ b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/WAJsonStreamTest.extension/instance/testOrderedDictionary.st
@@ -0,0 +1,34 @@
+*Seaside-Tests-Pharo70-JSON-Extensions
+testOrderedDictionary
+ self
+ assert:
+ ((OrderedDictionary new)
+ at: 'foo' put: 1;
+ at: 'bar' put: 2;
+ at: 'zork' put: 3;
+ yourself)
+ equals: '{"foo": 1, "bar": 2, "zork": 3}'.
+ self
+ assert:
+ ((OrderedDictionary new)
+ at: '' put: 'empty';
+ yourself)
+ equals: '{"": "empty"}'.
+ self
+ assert:
+ ((OrderedDictionary new)
+ at: 1 put: 'not-a-string';
+ yourself)
+ equals: '{1: "not-a-string"}'.
+ self
+ assert:
+ ((OrderedDictionary new)
+ at: '1abc' put: 'not-an-id';
+ yourself)
+ equals: '{"1abc": "not-an-id"}'.
+ self
+ assert:
+ ((OrderedDictionary new)
+ at: 'abc1' put: 'totally sexy';
+ yourself)
+ equals: '{"abc1": "totally sexy"}'
\ No newline at end of file
diff --git a/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/WAJsonStreamTest.extension/properties.json b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/WAJsonStreamTest.extension/properties.json
new file mode 100644
index 000000000..8e29b2deb
--- /dev/null
+++ b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/WAJsonStreamTest.extension/properties.json
@@ -0,0 +1,3 @@
+{
+ "name" : "WAJsonStreamTest"
+}
\ No newline at end of file
diff --git a/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/monticello.meta/categories.st b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/monticello.meta/categories.st
new file mode 100644
index 000000000..56d385391
--- /dev/null
+++ b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/monticello.meta/categories.st
@@ -0,0 +1 @@
+SystemOrganization addCategory: #'Seaside-Tests-Pharo70-JSON-Extensions'!
diff --git a/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/monticello.meta/initializers.st b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/monticello.meta/initializers.st
new file mode 100644
index 000000000..e69de29bb
diff --git a/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/monticello.meta/package b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/monticello.meta/package
new file mode 100644
index 000000000..646dbada7
--- /dev/null
+++ b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/monticello.meta/package
@@ -0,0 +1 @@
+(name 'Seaside-Tests-Pharo70-JSON-Extensions')
\ No newline at end of file
diff --git a/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/properties.json b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/properties.json
new file mode 100644
index 000000000..6f31cf5a2
--- /dev/null
+++ b/repository/Seaside-Tests-Pharo70-JSON-Extensions.package/properties.json
@@ -0,0 +1 @@
+{ }
\ No newline at end of file