@breakside/jskit 2025.14.0 → 2025.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/Frameworks/DOM.jsframework/Info.json +2 -2
  2. package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
  3. package/Frameworks/FontKit.jsframework/Info.json +2 -2
  4. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  5. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  6. package/Frameworks/Foundation.jsframework/JS/JSDiff.js +148 -53
  7. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  8. package/Frameworks/Foundation.jsframework/sources.json +1 -0
  9. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  10. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  11. package/Info.json +2 -2
  12. package/Node/io.breakside.jskit-bundle.js +2 -2
  13. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  14. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  15. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  16. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  17. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  18. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  19. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  20. package/Root/Frameworks/DOM/Info.yaml +1 -1
  21. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  22. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  23. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  24. package/Root/Frameworks/Foundation/JSDiff.js +148 -53
  25. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  26. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  27. package/Root/Frameworks/MediaKit/MKAsset+HTML.js +1 -1
  28. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  29. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  30. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  31. package/Root/Frameworks/PDFKit/PDFFont.js +1 -1
  32. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  33. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  34. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  35. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  36. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  37. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  38. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  39. package/Root/Frameworks/UIKit/UIHTMLApplication.js +1 -1
  40. package/Root/Frameworks/UIKit/UIHTMLWindowServer.js +1 -1
  41. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  42. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.DOM",
4
- "JSBundleVersion": "2025.14.0",
4
+ "JSBundleVersion": "2025.20.1",
5
5
  "JSDevelopmentLanguage": "en",
6
6
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
7
7
  "JSBundleEnvironments": {
@@ -9,5 +9,5 @@
9
9
  "node": "DOM+Node.js"
10
10
  },
11
11
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
12
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
12
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
13
13
  }
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.DOM",
6
- "JSBundleVersion": "2025.14.0",
6
+ "JSBundleVersion": "2025.20.1",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
11
11
  "node": "DOM+Node.js"
12
12
  },
13
13
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
14
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
14
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
15
15
  },
16
16
  "Resources": [],
17
17
  "ResourceLookup": {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.FontKit",
4
- "JSBundleVersion": "2025.14.0",
4
+ "JSBundleVersion": "2025.20.1",
5
5
  "JSDevelopmentLanguage": "en",
6
6
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
7
7
  "JSBundleEnvironments": {
8
8
  "html": "FontKit+HTML.js"
9
9
  },
10
10
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
11
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
11
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
12
12
  }
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.JSKit.FontKit'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.FontKit",
6
- "JSBundleVersion": "2025.14.0",
6
+ "JSBundleVersion": "2025.20.1",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
10
10
  "html": "FontKit+HTML.js"
11
11
  },
12
12
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
13
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
13
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
14
14
  },
15
15
  "Resources": [],
16
16
  "ResourceLookup": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.Foundation",
4
- "JSBundleVersion": "2025.14.0",
4
+ "JSBundleVersion": "2025.20.1",
5
5
  "JSDevelopmentLanguage": "en",
6
6
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
7
7
  "JSBundleEnvironments": {
@@ -9,5 +9,5 @@
9
9
  "node": "Foundation+Node.js"
10
10
  },
11
11
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
12
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
12
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
13
13
  }
@@ -20,80 +20,175 @@ JSClass("JSDiff", JSObject, {
20
20
  this.initWithArrays(a, b);
21
21
  },
22
22
 
23
+ operations: JSLazyInitProperty(function(){
24
+ return this.shortestOperationList();
25
+ }),
26
+
23
27
  commonIndexes: JSLazyInitProperty(function(){
28
+ var operations = this.operations;
29
+ var operationIndex = 0;
30
+ var operationCount = operations.length;
31
+ var m = this.a.length;
32
+ var n = this.b.length;
33
+ var commonIndexes = [];
34
+ var i = 0;
35
+ var j = 0;
36
+ while (i < m && j < n){
37
+ if (operationIndex < operationCount && operations[operationIndex].originalIndex === i){
38
+ if (operations[operationIndex].operator === JSDiff.Operator.delete){
39
+ ++i;
40
+ }else{
41
+ ++j;
42
+ }
43
+ ++operationIndex;
44
+ }else{
45
+ commonIndexes.push([i, j]);
46
+ ++i;
47
+ ++j;
48
+ }
49
+ }
50
+ return commonIndexes;
51
+ }),
52
+
53
+ shortestOperationList: function(){
54
+ var operations = [];
24
55
  var a = this.a;
25
56
  var b = this.b;
26
57
  if (this.mapFunction !== null){
27
58
  a = a.map(this.mapFunction);
28
59
  b = b.map(this.mapFunction);
29
60
  }
30
- return this.indexesOfLongestCommonSubsequence(a, 0, a.length - 1, b, 0, b.length - 1);
31
- }),
32
-
33
- recursionCount: 0,
34
- comparisonCount: 0,
61
+ var m = a.length;
62
+ var n = b.length;
63
+ var i = 0;
64
+ var j = 0;
35
65
 
36
- indexesOfLongestCommonSubsequence: function(a, i0, i1, b, j0, j1){
37
- ++this.recursionCount;
38
- if (i1 >= i0 && j1 >= j0){
66
+ // common prefix
67
+ for (; i < m && j < n; ++i, ++j){
39
68
  ++this.comparisonCount;
40
- if (a[i0] === b[j0]){
41
- var head = [];
42
- ++this.comparisonCount;
43
- while (i1 >= i0 && j1 >= j0 && a[i0] === b[i0]){
44
- head.push([i0, j0]);
45
- ++i0;
46
- ++j0;
47
- ++this.comparisonCount;
48
- }
49
- return head.concat(this.indexesOfLongestCommonSubsequence(a, i0, i1, b, j0, j1));
69
+ if (a[i] !== b[j]){
70
+ break;
50
71
  }
72
+ }
73
+
74
+ // common suffix
75
+ for (; m > i && n > j; --m, --n){
51
76
  ++this.comparisonCount;
52
- if (a[i1] === b[j1]){
53
- var tail = [];
77
+ if (a[m - 1] !== b[n - 1]){
78
+ break;
79
+ }
80
+ }
81
+
82
+ // special case, a and b are equal
83
+ if (i === m && j === n){
84
+ return operations;
85
+ }
86
+
87
+ // special case, b contains all of a plus extra at the end
88
+ if (i === m){
89
+ for (; j < n; ++j){
90
+ operations.push(JSDiffOperation(JSDiff.Operator.insert, i, j));
91
+ }
92
+ return operations;
93
+ }
94
+
95
+ // special case, b contains only the start of a
96
+ if (j === n){
97
+ for (; i < m; ++i){
98
+ operations.push(JSDiffOperation(JSDiff.Operator.delete, i, j));
99
+ }
100
+ return operations;
101
+ }
102
+
103
+ var operationCount = 1;
104
+ var maximumOperationCount = Math.min(m + n, this.maximumOperationCount);
105
+ var diagonalNumber;
106
+ var minimumDiagonalNumber = -1;
107
+ var maximumDiagonalNumber = 1;
108
+ var diagonals = {};
109
+ var diagonal;
110
+ var referenceDiagonal;
111
+ var operation;
112
+ var operator;
113
+ diagonals[0] = {
114
+ i: i,
115
+ operation: null
116
+ };
117
+ for (; operationCount <= maximumOperationCount; ++operationCount){
118
+ for (diagonalNumber = minimumDiagonalNumber; diagonalNumber <= maximumDiagonalNumber; diagonalNumber += 2){
54
119
  ++this.comparisonCount;
55
- while (i1 >= i0 && j1 >= j0 && a[i1] === b[j1]){
56
- tail.unshift([i1, j1]);
57
- --i1;
58
- --j1;
120
+ if (diagonalNumber === -operationCount || (diagonalNumber !== operationCount && diagonals[diagonalNumber + 1].i >= diagonals[diagonalNumber - 1].i)){
121
+ referenceDiagonal = diagonals[diagonalNumber + 1];
122
+ i = referenceDiagonal.i + 1;
123
+ j = i + diagonalNumber;
124
+ operation = JSDiffOperation(JSDiff.Operator.delete, i - 1, j);
125
+ }else{
126
+ referenceDiagonal = diagonals[diagonalNumber - 1];
127
+ i = referenceDiagonal.i;
128
+ j = i + diagonalNumber;
129
+ operation = JSDiffOperation(JSDiff.Operator.insert, i, j - 1);
130
+ }
131
+ operation.previous = referenceDiagonal.operation;
132
+ for (; i < m && j < n; ++i, ++j){
59
133
  ++this.comparisonCount;
134
+ if (a[i] !== b[j]){
135
+ break;
136
+ }
137
+ }
138
+ diagonal = diagonals[diagonalNumber];
139
+ if (diagonal === undefined){
140
+ diagonal = {
141
+ i: i,
142
+ operation: operation,
143
+ };
144
+ diagonals[diagonalNumber] = diagonal;
145
+ }else{
146
+ diagonal.i = i;
147
+ diagonal.operation = operation;
148
+ }
149
+ if (i === m && j === n){
150
+ while (operation !== null){
151
+ operations.unshift(operation);
152
+ operation = operation.previous;
153
+ }
154
+ return operations;
155
+ }
156
+ if (i === m){
157
+ minimumDiagonalNumber = diagonalNumber + 2;
158
+ }
159
+ if (j === n){
160
+ maximumDiagonalNumber = diagonalNumber - 2;
60
161
  }
61
- return this.indexesOfLongestCommonSubsequence(a, i0, i1, b, j0, j1).concat(tail);
62
- }
63
- var sequence1 = this.indexesOfLongestCommonSubsequence(a, i0, i1, b, j0, j1 - 1);
64
- var sequence2 = this.indexesOfLongestCommonSubsequence(a, i0, i1 - 1, b, j0, j1);
65
- if (sequence1.length >= sequence2.length){
66
- return sequence1;
67
162
  }
68
- return sequence2;
163
+ --minimumDiagonalNumber;
164
+ ++maximumDiagonalNumber;
69
165
  }
70
- return [];
71
- },
72
166
 
73
- operations: function(){
74
- var a = [];
75
- var b = [];
76
- var i, l;
77
- var j, k;
78
- var commonIndexes = this.commonIndexes;
79
- for (i = 0, l = a.length; i < l; ++i){
80
- }
81
- return [a, b];
167
+ return null;
82
168
  },
83
169
 
84
- longestCommonSubsequence: function(){
85
- var commonIndexes = this.commonIndexes;
86
- var sequence = [];
87
- var i, l;
88
- for (i = 0, l = commonIndexes.length; i < l; ++i){
89
- sequence.push(this.a[commonIndexes[i][0]]);
90
- }
91
- return sequence;
92
- }
170
+ maximumOperationCount: Infinity,
171
+ comparisonCount: 0,
93
172
 
94
173
  });
95
174
 
96
- JSDiff.Operation = {
175
+ JSGlobalObject.JSDiffOperation = function(operator, originalIndex, modifiedIndex){
176
+ if (this === undefined){
177
+ return new JSDiffOperation(operator, originalIndex, modifiedIndex);
178
+ }
179
+ if (operator instanceof JSDiffOperation){
180
+ this.operator = operator.operator;
181
+ this.originalIndex = operator.originalIndex;
182
+ this.modifiedIndex = operator.modifiedIndex;
183
+ }else{
184
+ this.operator = operator;
185
+ this.originalIndex = originalIndex;
186
+ this.modifiedIndex = modifiedIndex;
187
+ }
188
+ this.previous = null;
189
+ };
190
+
191
+ JSDiff.Operator = {
97
192
  insert: 1,
98
193
  delete: 2
99
- };
194
+ };
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.Foundation",
6
- "JSBundleVersion": "2025.14.0",
6
+ "JSBundleVersion": "2025.20.1",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
11
11
  "node": "Foundation+Node.js"
12
12
  },
13
13
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
14
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
14
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
15
15
  },
16
16
  "Resources": [
17
17
  {
@@ -268,6 +268,7 @@
268
268
  "JSDistributedNotificationCenter",
269
269
  "JSSynchronizer",
270
270
  "JSDiff",
271
+ "JSDiffOperation",
271
272
  "JSCRC32",
272
273
  "JSZip",
273
274
  "JSMD5Hash",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
4
- "JSBundleVersion": "2025.14.0",
4
+ "JSBundleVersion": "2025.20.1",
5
5
  "JSDevelopmentLanguage": "en",
6
6
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
7
7
  "JSBundleEnvironments": {
@@ -9,5 +9,5 @@
9
9
  "node": "SecurityKit+Node.js"
10
10
  },
11
11
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
12
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
12
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
13
13
  }
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
6
- "JSBundleVersion": "2025.14.0",
6
+ "JSBundleVersion": "2025.20.1",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
11
11
  "node": "SecurityKit+Node.js"
12
12
  },
13
13
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
14
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
14
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
15
15
  },
16
16
  "Resources": [],
17
17
  "ResourceLookup": {
package/Info.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "JSBundleType": "node",
3
3
  "JSBundleIdentifier": "io.breakside.jskit",
4
- "JSBundleVersion": "2025.14.0",
4
+ "JSBundleVersion": "2025.20.1",
5
5
  "JSExecutableName": "jskit",
6
6
  "NPMOrganization": "breakside",
7
7
  "JSResources": [
8
8
  "Tests/HTMLTestRunner.js",
9
9
  "Tests/NodeTestRunner.js"
10
10
  ],
11
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
11
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
12
12
  }
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.jskit'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "node",
5
5
  "JSBundleIdentifier": "io.breakside.jskit",
6
- "JSBundleVersion": "2025.14.0",
6
+ "JSBundleVersion": "2025.20.1",
7
7
  "JSExecutableName": "jskit",
8
8
  "NPMOrganization": "breakside",
9
9
  "JSResources": [
10
10
  "Tests/HTMLTestRunner.js",
11
11
  "Tests/NodeTestRunner.js"
12
12
  ],
13
- "GitRevision": "f1d43e0f93d2dc5ac63e6709fb7f84f7f9291995"
13
+ "GitRevision": "779dfd7ca024731d76463b6a3d5c731d567d0d70"
14
14
  },
15
15
  "Resources": [
16
16
  {
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.APIKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSIncludeDirectories:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.APIKitTesting
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.AuthKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.CSSOM
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ChartKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  # JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ConferenceKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.DBKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.DOM
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.Dispatch
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSCopyright: Copyright © 2020 Breakside Inc.
5
5
  JSBundleEnvironments:
6
6
  html: Dispatch+HTML.js
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.FontKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.Foundation
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -20,80 +20,175 @@ JSClass("JSDiff", JSObject, {
20
20
  this.initWithArrays(a, b);
21
21
  },
22
22
 
23
+ operations: JSLazyInitProperty(function(){
24
+ return this.shortestOperationList();
25
+ }),
26
+
23
27
  commonIndexes: JSLazyInitProperty(function(){
28
+ var operations = this.operations;
29
+ var operationIndex = 0;
30
+ var operationCount = operations.length;
31
+ var m = this.a.length;
32
+ var n = this.b.length;
33
+ var commonIndexes = [];
34
+ var i = 0;
35
+ var j = 0;
36
+ while (i < m && j < n){
37
+ if (operationIndex < operationCount && operations[operationIndex].originalIndex === i){
38
+ if (operations[operationIndex].operator === JSDiff.Operator.delete){
39
+ ++i;
40
+ }else{
41
+ ++j;
42
+ }
43
+ ++operationIndex;
44
+ }else{
45
+ commonIndexes.push([i, j]);
46
+ ++i;
47
+ ++j;
48
+ }
49
+ }
50
+ return commonIndexes;
51
+ }),
52
+
53
+ shortestOperationList: function(){
54
+ var operations = [];
24
55
  var a = this.a;
25
56
  var b = this.b;
26
57
  if (this.mapFunction !== null){
27
58
  a = a.map(this.mapFunction);
28
59
  b = b.map(this.mapFunction);
29
60
  }
30
- return this.indexesOfLongestCommonSubsequence(a, 0, a.length - 1, b, 0, b.length - 1);
31
- }),
32
-
33
- recursionCount: 0,
34
- comparisonCount: 0,
61
+ var m = a.length;
62
+ var n = b.length;
63
+ var i = 0;
64
+ var j = 0;
35
65
 
36
- indexesOfLongestCommonSubsequence: function(a, i0, i1, b, j0, j1){
37
- ++this.recursionCount;
38
- if (i1 >= i0 && j1 >= j0){
66
+ // common prefix
67
+ for (; i < m && j < n; ++i, ++j){
39
68
  ++this.comparisonCount;
40
- if (a[i0] === b[j0]){
41
- var head = [];
42
- ++this.comparisonCount;
43
- while (i1 >= i0 && j1 >= j0 && a[i0] === b[i0]){
44
- head.push([i0, j0]);
45
- ++i0;
46
- ++j0;
47
- ++this.comparisonCount;
48
- }
49
- return head.concat(this.indexesOfLongestCommonSubsequence(a, i0, i1, b, j0, j1));
69
+ if (a[i] !== b[j]){
70
+ break;
50
71
  }
72
+ }
73
+
74
+ // common suffix
75
+ for (; m > i && n > j; --m, --n){
51
76
  ++this.comparisonCount;
52
- if (a[i1] === b[j1]){
53
- var tail = [];
77
+ if (a[m - 1] !== b[n - 1]){
78
+ break;
79
+ }
80
+ }
81
+
82
+ // special case, a and b are equal
83
+ if (i === m && j === n){
84
+ return operations;
85
+ }
86
+
87
+ // special case, b contains all of a plus extra at the end
88
+ if (i === m){
89
+ for (; j < n; ++j){
90
+ operations.push(JSDiffOperation(JSDiff.Operator.insert, i, j));
91
+ }
92
+ return operations;
93
+ }
94
+
95
+ // special case, b contains only the start of a
96
+ if (j === n){
97
+ for (; i < m; ++i){
98
+ operations.push(JSDiffOperation(JSDiff.Operator.delete, i, j));
99
+ }
100
+ return operations;
101
+ }
102
+
103
+ var operationCount = 1;
104
+ var maximumOperationCount = Math.min(m + n, this.maximumOperationCount);
105
+ var diagonalNumber;
106
+ var minimumDiagonalNumber = -1;
107
+ var maximumDiagonalNumber = 1;
108
+ var diagonals = {};
109
+ var diagonal;
110
+ var referenceDiagonal;
111
+ var operation;
112
+ var operator;
113
+ diagonals[0] = {
114
+ i: i,
115
+ operation: null
116
+ };
117
+ for (; operationCount <= maximumOperationCount; ++operationCount){
118
+ for (diagonalNumber = minimumDiagonalNumber; diagonalNumber <= maximumDiagonalNumber; diagonalNumber += 2){
54
119
  ++this.comparisonCount;
55
- while (i1 >= i0 && j1 >= j0 && a[i1] === b[j1]){
56
- tail.unshift([i1, j1]);
57
- --i1;
58
- --j1;
120
+ if (diagonalNumber === -operationCount || (diagonalNumber !== operationCount && diagonals[diagonalNumber + 1].i >= diagonals[diagonalNumber - 1].i)){
121
+ referenceDiagonal = diagonals[diagonalNumber + 1];
122
+ i = referenceDiagonal.i + 1;
123
+ j = i + diagonalNumber;
124
+ operation = JSDiffOperation(JSDiff.Operator.delete, i - 1, j);
125
+ }else{
126
+ referenceDiagonal = diagonals[diagonalNumber - 1];
127
+ i = referenceDiagonal.i;
128
+ j = i + diagonalNumber;
129
+ operation = JSDiffOperation(JSDiff.Operator.insert, i, j - 1);
130
+ }
131
+ operation.previous = referenceDiagonal.operation;
132
+ for (; i < m && j < n; ++i, ++j){
59
133
  ++this.comparisonCount;
134
+ if (a[i] !== b[j]){
135
+ break;
136
+ }
137
+ }
138
+ diagonal = diagonals[diagonalNumber];
139
+ if (diagonal === undefined){
140
+ diagonal = {
141
+ i: i,
142
+ operation: operation,
143
+ };
144
+ diagonals[diagonalNumber] = diagonal;
145
+ }else{
146
+ diagonal.i = i;
147
+ diagonal.operation = operation;
148
+ }
149
+ if (i === m && j === n){
150
+ while (operation !== null){
151
+ operations.unshift(operation);
152
+ operation = operation.previous;
153
+ }
154
+ return operations;
155
+ }
156
+ if (i === m){
157
+ minimumDiagonalNumber = diagonalNumber + 2;
158
+ }
159
+ if (j === n){
160
+ maximumDiagonalNumber = diagonalNumber - 2;
60
161
  }
61
- return this.indexesOfLongestCommonSubsequence(a, i0, i1, b, j0, j1).concat(tail);
62
- }
63
- var sequence1 = this.indexesOfLongestCommonSubsequence(a, i0, i1, b, j0, j1 - 1);
64
- var sequence2 = this.indexesOfLongestCommonSubsequence(a, i0, i1 - 1, b, j0, j1);
65
- if (sequence1.length >= sequence2.length){
66
- return sequence1;
67
162
  }
68
- return sequence2;
163
+ --minimumDiagonalNumber;
164
+ ++maximumDiagonalNumber;
69
165
  }
70
- return [];
71
- },
72
166
 
73
- operations: function(){
74
- var a = [];
75
- var b = [];
76
- var i, l;
77
- var j, k;
78
- var commonIndexes = this.commonIndexes;
79
- for (i = 0, l = a.length; i < l; ++i){
80
- }
81
- return [a, b];
167
+ return null;
82
168
  },
83
169
 
84
- longestCommonSubsequence: function(){
85
- var commonIndexes = this.commonIndexes;
86
- var sequence = [];
87
- var i, l;
88
- for (i = 0, l = commonIndexes.length; i < l; ++i){
89
- sequence.push(this.a[commonIndexes[i][0]]);
90
- }
91
- return sequence;
92
- }
170
+ maximumOperationCount: Infinity,
171
+ comparisonCount: 0,
93
172
 
94
173
  });
95
174
 
96
- JSDiff.Operation = {
175
+ JSGlobalObject.JSDiffOperation = function(operator, originalIndex, modifiedIndex){
176
+ if (this === undefined){
177
+ return new JSDiffOperation(operator, originalIndex, modifiedIndex);
178
+ }
179
+ if (operator instanceof JSDiffOperation){
180
+ this.operator = operator.operator;
181
+ this.originalIndex = operator.originalIndex;
182
+ this.modifiedIndex = operator.modifiedIndex;
183
+ }else{
184
+ this.operator = operator;
185
+ this.originalIndex = originalIndex;
186
+ this.modifiedIndex = modifiedIndex;
187
+ }
188
+ this.previous = null;
189
+ };
190
+
191
+ JSDiff.Operator = {
97
192
  insert: 1,
98
193
  delete: 2
99
- };
194
+ };
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ImageKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -97,7 +97,7 @@ MKAsset.definePropertiesFromExtensions({
97
97
  }else if (this.isKindOfClass(MKRemoteAsset)){
98
98
  video.src = this.url.encodedString;
99
99
  }else{
100
- logger.warning("unsupported asset class: %{public}", this.$class.className);
100
+ logger.warn("unsupported asset class: %{public}", this.$class.className);
101
101
  JSRunLoop.main.schedule(completion, target, null);
102
102
  }
103
103
  video.load();
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKitUI
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.NotificationKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.PDFKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -460,7 +460,7 @@ JSGlobalObject.PDFType0Font.prototype = Object.create(PDFFont.prototype, {
460
460
 
461
461
  widthOfData: {
462
462
  value: function PDFType0Font_widthOfData(data, characterSpacing){
463
- logger.warning("Type0 font widthOfData called but not implemented, always returns 0");
463
+ logger.warn("Type0 font widthOfData called but not implemented, always returns 0");
464
464
  return 0;
465
465
  }
466
466
  },
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.QRKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SearchKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SecurityKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKitTesting
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.TestKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKit
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -88,7 +88,7 @@ JSClass("UIHTMLApplication", UIApplication, {
88
88
  }
89
89
  }
90
90
  }catch (e){
91
- logger.warning("unable to open URL `%{public}`: %{error}", url.encodedString, e);
91
+ logger.warn("unable to open URL `%{public}`: %{error}", url.encodedString, e);
92
92
  }
93
93
  }
94
94
  },
@@ -1437,7 +1437,7 @@ JSClass("UIHTMLDataTransferPasteboard", UIPasteboard, {
1437
1437
  var json = JSON.stringify(dictionaries);
1438
1438
  this._dataTransfer.setData(type, json);
1439
1439
  }catch (e){
1440
- logger.warning("Unable to serialize pasteboard objects to JSON: %{error}", e);
1440
+ logger.warn("Unable to serialize pasteboard objects to JSON: %{error}", e);
1441
1441
  }
1442
1442
  }
1443
1443
  }
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKitTesting
3
- JSBundleVersion: 2025.14.0
3
+ JSBundleVersion: 2025.20.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "node": ">=10.10.0"
10
10
  },
11
11
  "name": "@breakside/jskit",
12
- "version": "2025.14.0",
12
+ "version": "2025.20.1",
13
13
  "license": "SEE LICENSE IN LICENSE.txt",
14
14
  "files": [
15
15
  "*"