@breakside/jskit 2022.3.0 → 2022.6.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 (65) 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/JSColor.js +9 -0
  7. package/Frameworks/Foundation.jsframework/JS/JSMediaType.js +1 -1
  8. package/Frameworks/Foundation.jsframework/JS/JSUserDefaults.js +28 -7
  9. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  10. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  11. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  12. package/Info.json +2 -2
  13. package/Node/io.breakside.jskit-bundle.js +2 -2
  14. package/Root/Frameworks/APIKit/APIRequest.js +99 -0
  15. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  16. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  17. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  18. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  19. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  20. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  21. package/Root/Frameworks/DBKit/DBMongoStore.js +1 -0
  22. package/Root/Frameworks/DBKit/DBRedisStore.js +136 -117
  23. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  24. package/Root/Frameworks/DOM/Info.yaml +1 -1
  25. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  26. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  27. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  28. package/Root/Frameworks/Foundation/JSColor.js +9 -0
  29. package/Root/Frameworks/Foundation/JSMediaType.js +1 -1
  30. package/Root/Frameworks/Foundation/JSUserDefaults.js +28 -7
  31. package/Root/Frameworks/ImageKit/IKColorProfile.js +133 -21
  32. package/Root/Frameworks/ImageKit/IKMatrix.js +1 -1
  33. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  34. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  35. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  36. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  37. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  38. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  39. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  40. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  41. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  42. package/Root/Frameworks/ServerKit/SKAMQPJobQueue.js +1 -1
  43. package/Root/Frameworks/ServerKit/SKApplication+Node.js +5 -3
  44. package/Root/Frameworks/ServerKit/SKHTTPRequest.js +44 -0
  45. package/Root/Frameworks/ServerKit/SKJobQueue.js +1 -1
  46. package/Root/Frameworks/ServerKit/SKRedisJobQueue.js +7 -3
  47. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  48. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  49. package/Root/Frameworks/TestKit/TKMock.js +1 -1
  50. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  51. package/Root/Frameworks/UIKit/UIBrowserViewController.js +2 -6
  52. package/Root/Frameworks/UIKit/UIHTMLApplication.js +21 -5
  53. package/Root/Frameworks/UIKit/UINavigationBar.js +7 -1
  54. package/Root/Frameworks/UIKit/UINavigationController.js +228 -112
  55. package/Root/Frameworks/UIKit/UINavigationItem.js +4 -0
  56. package/Root/Frameworks/UIKit/UIPopupButton.js +8 -0
  57. package/Root/Frameworks/UIKit/UISplitViewController.js +185 -77
  58. package/Root/Frameworks/UIKit/UITabViewController.js +4 -10
  59. package/Root/Frameworks/UIKit/UIViewController.js +133 -50
  60. package/Root/Frameworks/UIKit/UIWindow.js +4 -15
  61. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  62. package/Root/Frameworks/UIKitTesting/UIMockApplication.js +6 -0
  63. package/Root/Templates/http/${PROJECT_NAME}/Dockerfile +1 -1
  64. package/Root/Templates/node/${PROJECT_NAME}/Dockerfile +4 -2
  65. package/package.json +1 -1
@@ -41,7 +41,7 @@ JSClass("DBRedisStore", DBObjectStore, {
41
41
 
42
42
  open: function(completion){
43
43
  logger.info("Redis client connecting to %{public}:%d...", this.url.host, this.url.port || 6379);
44
- this.client = this.redis.createClient({url: this.url.encodedString});
44
+ this.client = this.redis.createClient({url: this.url.encodedString, legacyMode: true});
45
45
  var store = this;
46
46
  var errorHandler = function(error){
47
47
  logger.info("Failed to open Redis connection: %{error}", error);
@@ -67,8 +67,12 @@ JSClass("DBRedisStore", DBObjectStore, {
67
67
  store.close(fn);
68
68
  }
69
69
  };
70
- this.client.on("error", errorHandler);
71
- this.client.on("ready", readyHandler);
70
+ if (this.client.connect){
71
+ this.client.connect().then(readyHandler, errorHandler);
72
+ }else{
73
+ this.client.on("error", errorHandler);
74
+ this.client.on("ready", readyHandler);
75
+ }
72
76
  },
73
77
 
74
78
  closeCallback: null,
@@ -233,7 +237,7 @@ JSClass("DBRedisStore", DBObjectStore, {
233
237
 
234
238
  watchClientQueue: null,
235
239
 
236
- dequeueReusableWatchClient: function(){
240
+ dequeueReusableWatchClient: function(completion, target){
237
241
  if (this.watchClientQueue === null){
238
242
  this.watchClientQueue = [];
239
243
  }
@@ -245,7 +249,17 @@ JSClass("DBRedisStore", DBObjectStore, {
245
249
  return this.watchClientQueue.shift();
246
250
  }
247
251
  logger.info("opening watch client to %{public}:%d", this.url.host, this.url.port || 6379);
248
- return this.redis.createClient({url: this.url.encodedString});
252
+ var client = this.redis.createClient({url: this.url.encodedString, legacyMode: true});
253
+ if (client.connect){
254
+ client.connect().then(function(){
255
+ completion.call(target, client);
256
+ }, function(error){
257
+ logger.error("Error connecting to watch client: %{error}", error);
258
+ completion.call(target, null);
259
+ });
260
+ }else{
261
+ completion.call(target, client);
262
+ }
249
263
  },
250
264
 
251
265
  enqueueReusableWatchClient: function(client){
@@ -277,120 +291,125 @@ JSClass("DBRedisStore", DBObjectStore, {
277
291
  },
278
292
 
279
293
  exclusiveSave: function(id, change, completion){
280
- var watchClient = this.dequeueReusableWatchClient();
281
- var maxRetires = 30;
282
- var waitInterval = JSTimeInterval.milliseconds(20);
283
- var retires = 0;
284
- var store = this;
285
- var trySave = function(){
286
- try{
287
- watchClient.watch(id, function(error){
288
- if (error !== null){
289
- logger.error("Failure calling redis watch: %{error}", error);
290
- watchClient.quit();
291
- completion(false);
292
- return;
293
- }
294
- try{
295
- watchClient.get(id, function(error, json){
296
- if (error !== null){
297
- logger.error("Failure calling redis get: %{error}", error);
298
- watchClient.quit();
299
- completion(false);
300
- return;
301
- }
302
- var object = null;
303
- try{
304
- object = JSON.parse(json);
305
- }catch (e){
306
- logger.error("Failure parsing object json: %{error}", error);
307
- watchClient.quit();
308
- completion(false);
309
- return;
310
- }
311
- try{
312
- watchClient.ttl(id, function(error, ttl){
313
- if (error !== null){
314
- logger.error("Failure calling redis ttl: %{error}", error);
315
- watchClient.quit();
316
- completion(false);
317
- return;
318
- }
319
- try{
320
- change(object, function(changedObject){
321
- if (changedObject === null){
322
- watchClient.quit();
323
- completion(false);
324
- return;
325
- }
326
- var changedJSON = null;
327
- try{
328
- changedJSON = JSON.stringify(changedObject);
329
- }catch (e){
330
- logger.error("Failed to serialize object for redis: %{error}", e);
331
- watchClient.quit();
332
- completion(false);
333
- return;
334
- }
335
- var args = [id, changedJSON];
336
- if (ttl > 0){
337
- args.push("EX");
338
- args.push(ttl);
339
- }
340
- try{
341
- watchClient.multi().set(args).exec(function(error, results){
342
- if (error !== null){
343
- logger.error("Failure calling redis multi/set/exec: %{error}", error);
344
- watchClient.quit();
345
- completion(false);
346
- return;
347
- }
348
- if (results === null){
349
- // null results means the transaction failed, so it's our signal to retry
350
- ++retires;
351
- if (retires > maxRetires){
352
- store.enqueueReusableWatchClient(watchClient);
353
- completion(true);
354
- return;
355
- }
356
- JSTimer.scheduledTimerWithInterval(waitInterval, trySave);
357
- waitInterval = Math.min(1, waitInterval * 2);
358
- return;
359
- }
360
- store.enqueueReusableWatchClient(watchClient);
361
- completion(true);
362
- });
363
- }catch (e){
364
- logger.error("Error thrown calling redis multi/set/exec: %{error}", e);
365
- watchClient.quit();
366
- completion(false);
367
- }
368
- });
369
- }catch (e){
370
- logger.error("Error thrown calling change function: %{error}", e);
371
- watchClient.quit();
372
- completion(false);
373
- }
374
- });
375
- }catch (e){
376
- logger.error("Error thrown calling redis ttl: %{error}", error);
377
- watchClient.quit();
378
- completion(false);
379
- }
380
- });
381
- }catch (e){
382
- logger.error("Error thrown calling redis get: %{error}", error);
383
- watchClient.quit();
384
- completion(false);
385
- }
386
- });
387
- }catch (e){
388
- logger.error("Error thrown calling redis watch: %{error}", e);
389
- watchClient.quit();
294
+ this.dequeueReusableWatchClient(function(watchClient){
295
+ if (watchClient === null){
390
296
  completion(false);
297
+ return;
391
298
  }
392
- };
393
- trySave();
299
+ var maxRetires = 30;
300
+ var waitInterval = JSTimeInterval.milliseconds(20);
301
+ var retires = 0;
302
+ var store = this;
303
+ var trySave = function(){
304
+ try{
305
+ watchClient.watch(id, function(error){
306
+ if (error !== null){
307
+ logger.error("Failure calling redis watch: %{error}", error);
308
+ watchClient.quit();
309
+ completion(false);
310
+ return;
311
+ }
312
+ try{
313
+ watchClient.get(id, function(error, json){
314
+ if (error !== null){
315
+ logger.error("Failure calling redis get: %{error}", error);
316
+ watchClient.quit();
317
+ completion(false);
318
+ return;
319
+ }
320
+ var object = null;
321
+ try{
322
+ object = JSON.parse(json);
323
+ }catch (e){
324
+ logger.error("Failure parsing object json: %{error}", error);
325
+ watchClient.quit();
326
+ completion(false);
327
+ return;
328
+ }
329
+ try{
330
+ watchClient.ttl(id, function(error, ttl){
331
+ if (error !== null){
332
+ logger.error("Failure calling redis ttl: %{error}", error);
333
+ watchClient.quit();
334
+ completion(false);
335
+ return;
336
+ }
337
+ try{
338
+ change(object, function(changedObject){
339
+ if (changedObject === null){
340
+ watchClient.quit();
341
+ completion(false);
342
+ return;
343
+ }
344
+ var changedJSON = null;
345
+ try{
346
+ changedJSON = JSON.stringify(changedObject);
347
+ }catch (e){
348
+ logger.error("Failed to serialize object for redis: %{error}", e);
349
+ watchClient.quit();
350
+ completion(false);
351
+ return;
352
+ }
353
+ var args = [id, changedJSON];
354
+ if (ttl > 0){
355
+ args.push("EX");
356
+ args.push(ttl);
357
+ }
358
+ try{
359
+ watchClient.multi().set(args).exec(function(error, results){
360
+ if (error !== null){
361
+ logger.error("Failure calling redis multi/set/exec: %{error}", error);
362
+ watchClient.quit();
363
+ completion(false);
364
+ return;
365
+ }
366
+ if (results === null){
367
+ // null results means the transaction failed, so it's our signal to retry
368
+ ++retires;
369
+ if (retires > maxRetires){
370
+ store.enqueueReusableWatchClient(watchClient);
371
+ completion(true);
372
+ return;
373
+ }
374
+ JSTimer.scheduledTimerWithInterval(waitInterval, trySave);
375
+ waitInterval = Math.min(1, waitInterval * 2);
376
+ return;
377
+ }
378
+ store.enqueueReusableWatchClient(watchClient);
379
+ completion(true);
380
+ });
381
+ }catch (e){
382
+ logger.error("Error thrown calling redis multi/set/exec: %{error}", e);
383
+ watchClient.quit();
384
+ completion(false);
385
+ }
386
+ });
387
+ }catch (e){
388
+ logger.error("Error thrown calling change function: %{error}", e);
389
+ watchClient.quit();
390
+ completion(false);
391
+ }
392
+ });
393
+ }catch (e){
394
+ logger.error("Error thrown calling redis ttl: %{error}", error);
395
+ watchClient.quit();
396
+ completion(false);
397
+ }
398
+ });
399
+ }catch (e){
400
+ logger.error("Error thrown calling redis get: %{error}", error);
401
+ watchClient.quit();
402
+ completion(false);
403
+ }
404
+ });
405
+ }catch (e){
406
+ logger.error("Error thrown calling redis watch: %{error}", e);
407
+ watchClient.quit();
408
+ completion(false);
409
+ }
410
+ };
411
+ trySave();
412
+ }, this);
394
413
  },
395
414
 
396
415
  saveChange: function(change, completion){
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.DBKit
3
- JSBundleVersion: 2022.3.0
3
+ JSBundleVersion: 2022.6.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: 2022.3.0
3
+ JSBundleVersion: 2022.6.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: 2022.3.0
3
+ JSBundleVersion: 2022.6.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: 2022.3.0
3
+ JSBundleVersion: 2022.6.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: 2022.3.0
3
+ JSBundleVersion: 2022.6.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -300,6 +300,15 @@ JSClass('JSColor', JSObject, {
300
300
  return JSColor.initWithSpaceAndComponents(JSColorSpace.gray, gray);
301
301
  },
302
302
 
303
+ colorInSpace: function(space){
304
+ if (space === this._space){
305
+ return this;
306
+ }
307
+ var components = space.componentsFromSpace(this._space, this._components);
308
+ components.push(this._components[this._components.length - 1]);
309
+ return JSColor.initWithSpaceAndComponents(space, components);
310
+ },
311
+
303
312
  rgbaHexStringRepresentation: function(){
304
313
  var color = this.rgbaColor();
305
314
  var r = Math.round(color.red * 255);
@@ -17,7 +17,7 @@
17
17
  'use strict';
18
18
 
19
19
  JSGlobalObject.JSMediaType = function(str, parameters){
20
- if (str === null || str === undefined){
20
+ if (str === null || str === undefined || str === ""){
21
21
  return null;
22
22
  }
23
23
  if (this === undefined){
@@ -29,12 +29,17 @@ var logger = JSLog("foundation", "user-defaults");
29
29
  JSClass("JSUserDefaults", JSObject, {
30
30
 
31
31
  identifier: JSReadOnlyProperty('_identifier', null),
32
+ _fileManager: null,
32
33
  _defaults: null,
33
34
  _values: null,
34
35
 
35
- initWithIdentifier: function(identifier){
36
+ initWithIdentifier: function(identifier, fileManager){
37
+ if (fileManager === undefined){
38
+ fileManager = JSFileManager.shared;
39
+ }
40
+ this._fileManager = fileManager;
36
41
  this._identifier = identifier;
37
- this._url = JSFileManager.shared.persistentContainerURL.appendingPathComponents(['Preferences', '%s.prefs.json'.sprintf(this._identifier)]);
42
+ this._url = this._fileManager.persistentContainerURL.appendingPathComponents(['Preferences', '%s.prefs.json'.sprintf(this._identifier)]);
38
43
  this._defaults = {};
39
44
  },
40
45
 
@@ -42,7 +47,7 @@ JSClass("JSUserDefaults", JSObject, {
42
47
  if (!completion){
43
48
  completion = Promise.completion(Promise.resolveTrue);
44
49
  }
45
- JSFileManager.shared.contentsAtURL(this._url, function JSUserDefaults_open_contents(data){
50
+ this._fileManager.contentsAtURL(this._url, function JSUserDefaults_open_contents(data){
46
51
  try{
47
52
  if (data !== null){
48
53
  var json = String.initWithData(data, String.Encoding.utf8);
@@ -60,6 +65,19 @@ JSClass("JSUserDefaults", JSObject, {
60
65
  },
61
66
 
62
67
  close: function(completion, target){
68
+ if (!completion){
69
+ completion = Promise.completion(Promise.resolveTrue);
70
+ }
71
+ this.synchronize(function(success){
72
+ if (success){
73
+ this._values = null;
74
+ }
75
+ completion.call(target, success);
76
+ }, this);
77
+ return completion.promise;
78
+ },
79
+
80
+ synchronize: function(completion, target){
63
81
  if (!completion){
64
82
  completion = Promise.completion(Promise.resolveTrue);
65
83
  }
@@ -75,9 +93,6 @@ JSClass("JSUserDefaults", JSObject, {
75
93
  }
76
94
  if (needsSave){
77
95
  this._persist(function JSUserDefaults_close_persisted(success){
78
- if (success){
79
- this._values = null;
80
- }
81
96
  completion.call(target, success);
82
97
  }, this);
83
98
  }else{
@@ -89,6 +104,9 @@ JSClass("JSUserDefaults", JSObject, {
89
104
  // MARK: - Getting and Setting values
90
105
 
91
106
  valueForKey: function(key){
107
+ if (this._values === null){
108
+ throw new Error("JSUserDefaults is closed, cannot get value. Be sure to call open() first.");
109
+ }
92
110
  if (key in this._values){
93
111
  return this._values[key];
94
112
  }
@@ -99,6 +117,9 @@ JSClass("JSUserDefaults", JSObject, {
99
117
  },
100
118
 
101
119
  setValueForKey: function(value, key){
120
+ if (this._values === null){
121
+ throw new Error("JSUserDefaults is closed, cannot set value. Be sure to call open() first.");
122
+ }
102
123
  this._values[key] = value;
103
124
  this._persistAfterDelay();
104
125
  this._definePropertyForKey(key);
@@ -161,7 +182,7 @@ JSClass("JSUserDefaults", JSObject, {
161
182
  }else{
162
183
  var data = JSON.stringify(this._values).utf8();
163
184
  logger.info("saving user defaults");
164
- JSFileManager.shared.createFileAtURL(this._url, data, function JSUserDefaults_persist_createFile(success){
185
+ this._fileManager.createFileAtURL(this._url, data, function JSUserDefaults_persist_createFile(success){
165
186
  if (!success){
166
187
  logger.error("failed to write user defaults");
167
188
  }else{
@@ -803,47 +803,159 @@ JSClass("IKColorProfileLookupTable8", IKColorProfileType, {
803
803
  JSClass("IKColorProfileLookupTable16", IKColorProfileType, {
804
804
 
805
805
  type: IKColorProfile.DataType.lookupTable16,
806
+ numberOfInputTableEntries: 0,
807
+ mumberOfOutputTableEntries: 0,
808
+ numberOfInputChannels: 0,
809
+ numberOfOutputChannels: 0,
810
+ numberOfGridPoints: 0,
811
+ matrix: null,
812
+ inputTables: null,
813
+ outputTables: null,
814
+ lookupTableDataView: null,
815
+ stride: 0,
806
816
 
807
817
  initWithData: function(data){
808
818
  IKColorProfileLookupTable16.$super.initWithData.call(this, data);
809
819
  var dataView = data.dataView();
810
- // TODO:
820
+ if (data.length < 48){
821
+ logger.warn("not enough data for lut8 matrix");
822
+ return null;
823
+ }
824
+ this.numberOfInputChannels = dataView.getUint8(8);
825
+ this.numberOfOutputChannels = dataView.getUint8(9);
826
+ this.numberOfGridPoints = dataView.getUint8(10);
827
+ this.matrix = IKMatrix([
828
+ [s15Fixed16(dataView.getUint32(12)), s15Fixed16(dataView.getUint32(16)), s15Fixed16(dataView.getUint32(20))],
829
+ [s15Fixed16(dataView.getUint32(24)), s15Fixed16(dataView.getUint32(28)), s15Fixed16(dataView.getUint32(32))],
830
+ [s15Fixed16(dataView.getUint32(36)), s15Fixed16(dataView.getUint32(40)), s15Fixed16(dataView.getUint32(44))]
831
+ ]);
832
+ this.numberOfInputTableEntries = dataView.getUint16(48);
833
+ this.numberOfOutputTableEntries = dataView.getUint16(50);
834
+ var offset = 52;
835
+ var end;
836
+ var i, j, k;
837
+ var table;
838
+ this.stride = this.numberOfOutputChannels + this.numberOfOutputChannels;
839
+ this.inputTables = [];
840
+ this.outputTables = [];
841
+ for (i = 0; i < this.numberOfInputChannels; ++i){
842
+ this.stride *= this.numberOfGridPoints;
843
+ end = offset + this.numberOfInputTableEntries + this.numberOfInputTableEntries;
844
+ if (data.length < end){
845
+ logger.warn("not enough data for lut16 input tables");
846
+ return null;
847
+ }
848
+ table = [];
849
+ for (; offset < end; offset += 2){
850
+ table.push(dataView.getUint16(offset) / 65535.0);
851
+ }
852
+ this.inputTables.push(table);
853
+ }
854
+ end = offset + this.stride;
855
+ if (data.length < end){
856
+ logger.warn("not enough data for lut8 clut");
857
+ return null;
858
+ }
859
+ this.lookupTableDataView = this.data.subdataInRange(JSRange(offset, this.stride)).dataView();
860
+ offset += this.stride;
861
+ for (i = 0; i < this.numberOfOutputChannels; ++i){
862
+ end = offset + this.numberOfOutputTableEntries + this.numberOfOutputTableEntries;
863
+ if (data.length < end){
864
+ logger.warn("not enough data for lut8 output tables");
865
+ return null;
866
+ }
867
+ table = [];
868
+ for (; offset < end; offset += 2){
869
+ table.push(dataView.getUint16(offset) / 65535.0);
870
+ }
871
+ this.outputTables.push(table);
872
+ }
811
873
  },
812
874
 
813
875
  lookup: function(components){
876
+ var input = [];
877
+ var i, j, l;
878
+ var x, x0, x1;
879
+ var offsetCount;
880
+ var offsets = [0];
881
+ var weights = [1];
882
+ var w0, w1;
883
+ var stride = this.stride;
884
+ var d;
885
+ for (i = 0; i < this.numberOfInputChannels; ++i){
886
+ stride /= this.numberOfGridPoints;
887
+ x = this.inputTables[i][Math.round(Math.max(0, Math.min(1, components[i])) * (this.numberOfInputTableEntries - 1))];
888
+ x *= (this.numberOfGridPoints - 1);
889
+ x0 = Math.floor(x);
890
+ d = x0 * stride;
891
+ for (j = 0, l = offsets.length; j < l; ++j){
892
+ offsets[j] += d;
893
+ }
894
+ if (x > x0){
895
+ x1 = x0 + 1;
896
+ w1 = (x - x0);
897
+ w0 = 1 - w1;
898
+ for (j = 0, l = offsets.length; j < l; ++j){
899
+ offsets.push(offsets[j] + stride);
900
+ weights.push(weights[j] * w1);
901
+ weights[j] *= w0;
902
+ }
903
+ }
904
+ }
905
+ var output = [];
906
+ for (i = 0; i < this.numberOfOutputChannels; ++i){
907
+ output.push(0);
908
+ }
909
+ var offset;
910
+ for (i = 0, l = offsets.length; i < l; ++i){
911
+ offset = offsets[i];
912
+ for (j = 0; j < this.numberOfOutputChannels; ++j, offset += 2){
913
+ x = (this.lookupTableDataView.getUint16(offset) / 65535.0) * (this.numberOfOutputTableEntries - 1);
914
+ x0 = Math.floor(x);
915
+ if (x0 < x){
916
+ x1 = x0 + 1;
917
+ w1 = (x - x0);
918
+ w0 = 1 - w1;
919
+ output[j] += (this.outputTables[j][x0] * w0 + this.outputTables[j][x1] * w1) * weights[i];
920
+ }else{
921
+ output[j] += this.outputTables[j][x0] * weights[i];
922
+ }
923
+ }
924
+ }
925
+ return output;
814
926
  }
815
927
 
816
928
  });
817
929
 
818
- JSClass("IKColorProfileLookupTableAToB", IKColorProfileType, {
930
+ // JSClass("IKColorProfileLookupTableAToB", IKColorProfileType, {
819
931
 
820
- type: IKColorProfile.DataType.lookupTableAToB,
932
+ // type: IKColorProfile.DataType.lookupTableAToB,
821
933
 
822
- initWithData: function(data){
823
- IKColorProfileLookupTableAToB.$super.initWithData.call(this, data);
824
- var dataView = data.dataView();
825
- // TODO:
826
- },
934
+ // initWithData: function(data){
935
+ // IKColorProfileLookupTableAToB.$super.initWithData.call(this, data);
936
+ // var dataView = data.dataView();
937
+ // // TODO:
938
+ // },
827
939
 
828
- lookup: function(components){
829
- }
940
+ // lookup: function(components){
941
+ // }
830
942
 
831
- });
943
+ // });
832
944
 
833
- JSClass("IKColorProfileLookupTableBToA", IKColorProfileType, {
945
+ // JSClass("IKColorProfileLookupTableBToA", IKColorProfileType, {
834
946
 
835
- type: IKColorProfile.DataType.lookupTableBToA,
947
+ // type: IKColorProfile.DataType.lookupTableBToA,
836
948
 
837
- initWithData: function(data){
838
- IKColorProfileLookupTableBToA.$super.initWithData.call(this, data);
839
- var dataView = data.dataView();
840
- // TODO:
841
- },
949
+ // initWithData: function(data){
950
+ // IKColorProfileLookupTableBToA.$super.initWithData.call(this, data);
951
+ // var dataView = data.dataView();
952
+ // // TODO:
953
+ // },
842
954
 
843
- lookup: function(components){
844
- }
955
+ // lookup: function(components){
956
+ // }
845
957
 
846
- });
958
+ // });
847
959
 
848
960
  JSClass("IKColorProfileComponentConverter", JSObject, {
849
961
 
@@ -1,4 +1,4 @@
1
- // // Copyright 2022 Breakside Inc.
1
+ // Copyright 2022 Breakside Inc.
2
2
  //
3
3
  // Licensed under the Breakside Public License, Version 1.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ImageKit
3
- JSBundleVersion: 2022.3.0
3
+ JSBundleVersion: 2022.6.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: 2022.3.0
3
+ JSBundleVersion: 2022.6.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.MediaKitUI
3
- JSBundleVersion: 2022.3.0
3
+ JSBundleVersion: 2022.6.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: 2022.3.0
3
+ JSBundleVersion: 2022.6.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  JSBundleEnvironments: