@yorkie-js/react 0.6.22 → 0.6.23

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.
@@ -5,7 +5,7 @@ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { createContext, useMemo, useState, useEffect, useContext, useCallback } from "react";
7
7
  const name$1 = "@yorkie-js/react";
8
- const version$1 = "0.6.22";
8
+ const version$1 = "0.6.23";
9
9
  const pkg$1 = {
10
10
  name: name$1,
11
11
  version: version$1
@@ -4690,7 +4690,6 @@ let Operation$1 = (_e = class extends Message {
4690
4690
  { no: 3, name: "move", kind: "message", T: Operation_Move, oneof: "body" },
4691
4691
  { no: 4, name: "remove", kind: "message", T: Operation_Remove, oneof: "body" },
4692
4692
  { no: 5, name: "edit", kind: "message", T: Operation_Edit, oneof: "body" },
4693
- { no: 6, name: "select", kind: "message", T: Operation_Select, oneof: "body" },
4694
4693
  { no: 7, name: "style", kind: "message", T: Operation_Style, oneof: "body" },
4695
4694
  { no: 8, name: "increase", kind: "message", T: Operation_Increase, oneof: "body" },
4696
4695
  { no: 9, name: "tree_edit", kind: "message", T: Operation_TreeEdit, oneof: "body" },
@@ -4940,49 +4939,6 @@ __publicField(_Operation_Edit, "fields", proto3.util.newFieldList(() => [
4940
4939
  } }
4941
4940
  ]));
4942
4941
  let Operation_Edit = _Operation_Edit;
4943
- const _Operation_Select = class _Operation_Select extends Message {
4944
- constructor(data) {
4945
- super();
4946
- /**
4947
- * @generated from field: yorkie.v1.TimeTicket parent_created_at = 1;
4948
- */
4949
- __publicField(this, "parentCreatedAt");
4950
- /**
4951
- * @generated from field: yorkie.v1.TextNodePos from = 2;
4952
- */
4953
- __publicField(this, "from");
4954
- /**
4955
- * @generated from field: yorkie.v1.TextNodePos to = 3;
4956
- */
4957
- __publicField(this, "to");
4958
- /**
4959
- * @generated from field: yorkie.v1.TimeTicket executed_at = 4;
4960
- */
4961
- __publicField(this, "executedAt");
4962
- proto3.util.initPartial(data, this);
4963
- }
4964
- static fromBinary(bytes, options) {
4965
- return new _Operation_Select().fromBinary(bytes, options);
4966
- }
4967
- static fromJson(jsonValue, options) {
4968
- return new _Operation_Select().fromJson(jsonValue, options);
4969
- }
4970
- static fromJsonString(jsonString, options) {
4971
- return new _Operation_Select().fromJsonString(jsonString, options);
4972
- }
4973
- static equals(a, b) {
4974
- return proto3.util.equals(_Operation_Select, a, b);
4975
- }
4976
- };
4977
- __publicField(_Operation_Select, "runtime", proto3);
4978
- __publicField(_Operation_Select, "typeName", "yorkie.v1.Operation.Select");
4979
- __publicField(_Operation_Select, "fields", proto3.util.newFieldList(() => [
4980
- { no: 1, name: "parent_created_at", kind: "message", T: TimeTicket$1 },
4981
- { no: 2, name: "from", kind: "message", T: TextNodePos },
4982
- { no: 3, name: "to", kind: "message", T: TextNodePos },
4983
- { no: 4, name: "executed_at", kind: "message", T: TimeTicket$1 }
4984
- ]));
4985
- let Operation_Select = _Operation_Select;
4986
4942
  const _Operation_Style = class _Operation_Style extends Message {
4987
4943
  constructor(data) {
4988
4944
  super();
@@ -6445,9 +6401,9 @@ const _DocumentSummary = class _DocumentSummary extends Message {
6445
6401
  */
6446
6402
  __publicField(this, "key", "");
6447
6403
  /**
6448
- * @generated from field: string snapshot = 3;
6404
+ * @generated from field: string root = 3;
6449
6405
  */
6450
- __publicField(this, "snapshot", "");
6406
+ __publicField(this, "root", "");
6451
6407
  /**
6452
6408
  * @generated from field: int32 attached_clients = 7;
6453
6409
  */
@@ -6460,6 +6416,10 @@ const _DocumentSummary = class _DocumentSummary extends Message {
6460
6416
  * @generated from field: string schema_key = 9;
6461
6417
  */
6462
6418
  __publicField(this, "schemaKey", "");
6419
+ /**
6420
+ * @generated from field: map<string, yorkie.v1.Presence> presences = 10;
6421
+ */
6422
+ __publicField(this, "presences", {});
6463
6423
  /**
6464
6424
  * @generated from field: google.protobuf.Timestamp created_at = 4;
6465
6425
  */
@@ -6506,7 +6466,7 @@ __publicField(_DocumentSummary, "fields", proto3.util.newFieldList(() => [
6506
6466
  },
6507
6467
  {
6508
6468
  no: 3,
6509
- name: "snapshot",
6469
+ name: "root",
6510
6470
  kind: "scalar",
6511
6471
  T: 9
6512
6472
  /* ScalarType.STRING */
@@ -6526,6 +6486,7 @@ __publicField(_DocumentSummary, "fields", proto3.util.newFieldList(() => [
6526
6486
  T: 9
6527
6487
  /* ScalarType.STRING */
6528
6488
  },
6489
+ { no: 10, name: "presences", kind: "map", K: 9, V: { kind: "message", T: Presence$1 } },
6529
6490
  { no: 4, name: "created_at", kind: "message", T: Timestamp },
6530
6491
  { no: 5, name: "accessed_at", kind: "message", T: Timestamp },
6531
6492
  { no: 6, name: "updated_at", kind: "message", T: Timestamp }
@@ -8280,7 +8241,7 @@ class CRDTElement {
8280
8241
  * `remove` removes this element.
8281
8242
  */
8282
8243
  remove(removedAt) {
8283
- if (removedAt && removedAt.after(this.getPositionedAt()) && (!this.removedAt || removedAt.after(this.removedAt))) {
8244
+ if (removedAt && removedAt.after(this.createdAt) && (!this.removedAt || removedAt.after(this.removedAt))) {
8284
8245
  this.removedAt = removedAt;
8285
8246
  return true;
8286
8247
  }
@@ -10314,6 +10275,7 @@ class RGATreeListNode extends SplayNode {
10314
10275
  super(value);
10315
10276
  __publicField(this, "prev");
10316
10277
  __publicField(this, "next");
10278
+ __publicField(this, "movedFrom");
10317
10279
  this.value = value;
10318
10280
  }
10319
10281
  /**
@@ -10380,6 +10342,18 @@ class RGATreeListNode extends SplayNode {
10380
10342
  getNext() {
10381
10343
  return this.next;
10382
10344
  }
10345
+ /**
10346
+ * `getMovedFrom` returns the previous element before the element moved.
10347
+ */
10348
+ getMovedFrom() {
10349
+ return this.movedFrom;
10350
+ }
10351
+ /**
10352
+ * `setMovedFrom` sets the previous element before the element moved.
10353
+ */
10354
+ setMovedFrom(movedFrom) {
10355
+ this.movedFrom = movedFrom;
10356
+ }
10383
10357
  /**
10384
10358
  * `getValue` returns a element value.
10385
10359
  */
@@ -10439,6 +10413,9 @@ class RGATreeList {
10439
10413
  `cant find the given node: ${createdAt.toIDString()}`
10440
10414
  );
10441
10415
  }
10416
+ while (node.getValue().getMovedAt() && node.getValue().getMovedAt().after(executedAt) && node.getMovedFrom()) {
10417
+ node = node.getMovedFrom();
10418
+ }
10442
10419
  while (node.getNext() && node.getNext().getPositionedAt().after(executedAt)) {
10443
10420
  node = node.getNext();
10444
10421
  }
@@ -10463,30 +10440,51 @@ class RGATreeList {
10463
10440
  }
10464
10441
  this.nodeMapByIndex.insertAfter(prevNode, newNode);
10465
10442
  this.nodeMapByCreatedAt.set(newNode.getCreatedAt().toIDString(), newNode);
10443
+ return newNode;
10466
10444
  }
10467
10445
  /**
10468
10446
  * `moveAfter` moves the given `createdAt` element
10469
10447
  * after the `prevCreatedAt` element.
10470
10448
  */
10471
10449
  moveAfter(prevCreatedAt, createdAt, executedAt) {
10472
- const prevNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
10450
+ let prevNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
10473
10451
  if (!prevNode) {
10474
10452
  throw new YorkieError(
10475
10453
  Code.ErrInvalidArgument,
10476
10454
  `cant find the given node: ${prevCreatedAt.toIDString()}`
10477
10455
  );
10478
10456
  }
10479
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
10457
+ let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
10480
10458
  if (!node) {
10481
10459
  throw new YorkieError(
10482
10460
  Code.ErrInvalidArgument,
10483
10461
  `cant find the given node: ${createdAt.toIDString()}`
10484
10462
  );
10485
10463
  }
10486
- if (prevNode !== node && (!node.getValue().getMovedAt() || executedAt.after(node.getValue().getMovedAt()))) {
10464
+ if (prevNode !== node && executedAt.after(node.getPositionedAt())) {
10465
+ const movedFrom = node.getPrev();
10466
+ let nextNode = node.getNext();
10487
10467
  this.release(node);
10488
- this.insertAfter(prevNode.getCreatedAt(), node.getValue(), executedAt);
10468
+ node = this.insertAfter(
10469
+ prevNode.getCreatedAt(),
10470
+ node.getValue(),
10471
+ executedAt
10472
+ );
10489
10473
  node.getValue().setMovedAt(executedAt);
10474
+ node.setMovedFrom(movedFrom);
10475
+ while (nextNode && nextNode.getPositionedAt().after(executedAt)) {
10476
+ prevNode = node;
10477
+ node = nextNode;
10478
+ nextNode = node.getNext();
10479
+ this.release(node);
10480
+ node = this.insertAfter(
10481
+ prevNode.getCreatedAt(),
10482
+ node.getValue(),
10483
+ executedAt
10484
+ );
10485
+ node.getValue().setMovedAt(executedAt);
10486
+ node.setMovedFrom(movedFrom);
10487
+ }
10490
10488
  }
10491
10489
  }
10492
10490
  /**
@@ -10565,6 +10563,20 @@ class RGATreeList {
10565
10563
  }
10566
10564
  return node.getValue();
10567
10565
  }
10566
+ /**
10567
+ * `set` sets the given element at the given creation time.
10568
+ */
10569
+ set(createdAt, element, executedAt) {
10570
+ const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
10571
+ if (!node) {
10572
+ throw new YorkieError(
10573
+ Code.ErrInvalidArgument,
10574
+ `cant find the given node: ${createdAt.toIDString()}`
10575
+ );
10576
+ }
10577
+ this.insertAfter(node.getCreatedAt(), element, executedAt);
10578
+ return this.delete(createdAt, executedAt);
10579
+ }
10568
10580
  /**
10569
10581
  * `deleteByIndex` deletes the node of the given index.
10570
10582
  */
@@ -10708,6 +10720,12 @@ class CRDTArray extends CRDTContainer {
10708
10720
  deleteByIndex(index, editedAt) {
10709
10721
  return this.elements.deleteByIndex(index, editedAt);
10710
10722
  }
10723
+ /**
10724
+ * `set` sets the given element at the given position of the creation time.
10725
+ */
10726
+ set(createdAt, value, executedAt) {
10727
+ return this.elements.set(createdAt, value, executedAt);
10728
+ }
10711
10729
  /**
10712
10730
  * `getLastCreatedAt` get last created element.
10713
10731
  */
@@ -16124,6 +16142,77 @@ class TreeStyleOperation extends Operation {
16124
16142
  return this.attributesToRemove;
16125
16143
  }
16126
16144
  }
16145
+ class ArraySetOperation extends Operation {
16146
+ constructor(parentCreatedAt, createdAt, value, executedAt) {
16147
+ super(parentCreatedAt, executedAt);
16148
+ __publicField(this, "createdAt");
16149
+ __publicField(this, "value");
16150
+ this.createdAt = createdAt;
16151
+ this.value = value;
16152
+ }
16153
+ /**
16154
+ * `create` creates a new instance of ArraySetOperation.
16155
+ */
16156
+ static create(parentCreatedAt, createdAt, value, executedAt) {
16157
+ return new ArraySetOperation(parentCreatedAt, createdAt, value, executedAt);
16158
+ }
16159
+ /**
16160
+ * `execute` executes this operation on the given `CRDTRoot`.
16161
+ */
16162
+ execute(root) {
16163
+ const parentObject = root.findByCreatedAt(this.getParentCreatedAt());
16164
+ if (!parentObject) {
16165
+ throw new YorkieError(
16166
+ Code.ErrInvalidArgument,
16167
+ `fail to find ${this.getParentCreatedAt()}`
16168
+ );
16169
+ }
16170
+ if (!(parentObject instanceof CRDTArray)) {
16171
+ throw new YorkieError(
16172
+ Code.ErrInvalidArgument,
16173
+ `fail to execute, only array can execute set`
16174
+ );
16175
+ }
16176
+ const value = this.value.deepcopy();
16177
+ parentObject.insertAfter(this.createdAt, value, this.getExecutedAt());
16178
+ parentObject.delete(this.createdAt, this.getExecutedAt());
16179
+ root.registerElement(value);
16180
+ const reverseOp = void 0;
16181
+ return {
16182
+ opInfos: [
16183
+ {
16184
+ type: "array-set",
16185
+ path: root.createPath(this.getParentCreatedAt())
16186
+ }
16187
+ ],
16188
+ reverseOp
16189
+ };
16190
+ }
16191
+ /**
16192
+ * `getEffectedCreatedAt` returns the creation time of the effected element.
16193
+ */
16194
+ getEffectedCreatedAt() {
16195
+ return this.createdAt;
16196
+ }
16197
+ /**
16198
+ * `toTestString` returns a string containing the meta data.
16199
+ */
16200
+ toTestString() {
16201
+ return `${this.getParentCreatedAt().toTestString()}.ARRAY_SET.${this.createdAt.toTestString()}=${this.value.toSortedJSON()}`;
16202
+ }
16203
+ /**
16204
+ * `getCreatedAt` returns the creation time of the target element.
16205
+ */
16206
+ getCreatedAt() {
16207
+ return this.createdAt;
16208
+ }
16209
+ /**
16210
+ * `getValue` returns the value of this operation.
16211
+ */
16212
+ getValue() {
16213
+ return this.value;
16214
+ }
16215
+ }
16127
16216
  function toPresence(presence) {
16128
16217
  const pbPresence = new Presence$1();
16129
16218
  const pbDataMap = pbPresence.data;
@@ -16421,6 +16510,21 @@ function toOperation(operation) {
16421
16510
  );
16422
16511
  pbOperation.body.case = "treeStyle";
16423
16512
  pbOperation.body.value = pbTreeStyleOperation;
16513
+ } else if (operation instanceof ArraySetOperation) {
16514
+ const arraySetOperation = operation;
16515
+ const pbArraySetOperation = new Operation_ArraySet();
16516
+ pbArraySetOperation.parentCreatedAt = toTimeTicket(
16517
+ arraySetOperation.getParentCreatedAt()
16518
+ );
16519
+ pbArraySetOperation.createdAt = toTimeTicket(
16520
+ arraySetOperation.getCreatedAt()
16521
+ );
16522
+ pbArraySetOperation.value = toElementSimple(arraySetOperation.getValue());
16523
+ pbArraySetOperation.executedAt = toTimeTicket(
16524
+ arraySetOperation.getExecutedAt()
16525
+ );
16526
+ pbOperation.body.case = "arraySet";
16527
+ pbOperation.body.value = pbArraySetOperation;
16424
16528
  } else {
16425
16529
  throw new YorkieError(Code.ErrUnimplemented, "unimplemented operation");
16426
16530
  }
@@ -16960,8 +17064,6 @@ function fromOperation(pbOperation) {
16960
17064
  attributes,
16961
17065
  fromTimeTicket(pbStyleOperation.executedAt)
16962
17066
  );
16963
- } else if (pbOperation.body.case === "select") {
16964
- return;
16965
17067
  } else if (pbOperation.body.case === "increase") {
16966
17068
  const pbIncreaseOperation = pbOperation.body.value;
16967
17069
  return IncreaseOperation.create(
@@ -17005,6 +17107,14 @@ function fromOperation(pbOperation) {
17005
17107
  fromTimeTicket(pbTreeStyleOperation.executedAt)
17006
17108
  );
17007
17109
  }
17110
+ } else if (pbOperation.body.case === "arraySet") {
17111
+ const pbArraySetOperation = pbOperation.body.value;
17112
+ return ArraySetOperation.create(
17113
+ fromTimeTicket(pbArraySetOperation.parentCreatedAt),
17114
+ fromTimeTicket(pbArraySetOperation.createdAt),
17115
+ fromElementSimple(pbArraySetOperation.value),
17116
+ fromTimeTicket(pbArraySetOperation.executedAt)
17117
+ );
17008
17118
  } else {
17009
17119
  throw new YorkieError(Code.ErrUnimplemented, `unimplemented operation`);
17010
17120
  }
@@ -18307,6 +18417,15 @@ class ArrayProxy {
18307
18417
  return () => {
18308
18418
  return toWrappedElement(context, target.getLast());
18309
18419
  };
18420
+ } else if (method === "delete") {
18421
+ return (index) => {
18422
+ const deleted = ArrayProxy.deleteInternalByIndex(
18423
+ context,
18424
+ target,
18425
+ index
18426
+ );
18427
+ return toWrappedElement(context, deleted);
18428
+ };
18310
18429
  } else if (method === "deleteByID") {
18311
18430
  return (createdAt) => {
18312
18431
  const deleted = ArrayProxy.deleteInternalByID(
@@ -18326,6 +18445,16 @@ class ArrayProxy {
18326
18445
  );
18327
18446
  return toWrappedElement(context, inserted);
18328
18447
  };
18448
+ } else if (method === "insertIntegerAfter") {
18449
+ return (index, value) => {
18450
+ const array2 = ArrayProxy.insertIntegerAfterInternal(
18451
+ context,
18452
+ target,
18453
+ index,
18454
+ value
18455
+ );
18456
+ return toWrappedElement(context, array2);
18457
+ };
18329
18458
  } else if (method === "insertBefore") {
18330
18459
  return (nextID, value) => {
18331
18460
  const inserted = ArrayProxy.insertBeforeInternal(
@@ -18336,6 +18465,16 @@ class ArrayProxy {
18336
18465
  );
18337
18466
  return toWrappedElement(context, inserted);
18338
18467
  };
18468
+ } else if (method === "setInteger") {
18469
+ return (index, value) => {
18470
+ const array2 = ArrayProxy.setIntegerInternal(
18471
+ context,
18472
+ target,
18473
+ index,
18474
+ value
18475
+ );
18476
+ return toWrappedElement(context, array2);
18477
+ };
18339
18478
  } else if (method === "moveBefore") {
18340
18479
  return (nextID, id) => {
18341
18480
  ArrayProxy.moveBeforeInternal(context, target, nextID, id);
@@ -18344,6 +18483,15 @@ class ArrayProxy {
18344
18483
  return (prevID, id) => {
18345
18484
  ArrayProxy.moveAfterInternal(context, target, prevID, id);
18346
18485
  };
18486
+ } else if (method === "moveAfterByIndex") {
18487
+ return (prevIndex, targetIndex) => {
18488
+ ArrayProxy.moveAfterByIndexInternal(
18489
+ context,
18490
+ target,
18491
+ prevIndex,
18492
+ targetIndex
18493
+ );
18494
+ };
18347
18495
  } else if (method === "moveFront") {
18348
18496
  return (id) => {
18349
18497
  ArrayProxy.moveFrontInternal(context, target, id);
@@ -18477,7 +18625,6 @@ class ArrayProxy {
18477
18625
  */
18478
18626
  static moveAfterInternal(context, target, prevCreatedAt, createdAt) {
18479
18627
  const ticket = context.issueTimeTicket();
18480
- target.moveAfter(prevCreatedAt, createdAt, ticket);
18481
18628
  context.push(
18482
18629
  MoveOperation.create(
18483
18630
  target.getCreatedAt(),
@@ -18486,6 +18633,33 @@ class ArrayProxy {
18486
18633
  ticket
18487
18634
  )
18488
18635
  );
18636
+ target.moveAfter(prevCreatedAt, createdAt, ticket);
18637
+ }
18638
+ /**
18639
+ * `moveAfterByIndexInternal` moves the given element to its new position
18640
+ * after the given previous element.
18641
+ */
18642
+ static moveAfterByIndexInternal(context, target, prevIndex, targetIndex) {
18643
+ const prevElem = target.get(prevIndex);
18644
+ if (!prevElem) {
18645
+ throw new YorkieError(
18646
+ Code.ErrInvalidArgument,
18647
+ `index out of bounds: ${prevIndex}`
18648
+ );
18649
+ }
18650
+ const targetElem = target.get(targetIndex);
18651
+ if (!targetElem) {
18652
+ throw new YorkieError(
18653
+ Code.ErrInvalidArgument,
18654
+ `index out of bounds: ${targetIndex}`
18655
+ );
18656
+ }
18657
+ ArrayProxy.moveAfterInternal(
18658
+ context,
18659
+ target,
18660
+ prevElem.getCreatedAt(),
18661
+ targetElem.getCreatedAt()
18662
+ );
18489
18663
  }
18490
18664
  /**
18491
18665
  * `moveFrontInternal` moves the given `createdAt` element
@@ -18534,6 +18708,25 @@ class ArrayProxy {
18534
18708
  );
18535
18709
  return element;
18536
18710
  }
18711
+ /**
18712
+ * `insertIntegerAfterInternal` inserts the given integer after the given previous element.
18713
+ */
18714
+ static insertIntegerAfterInternal(context, target, index, value) {
18715
+ const prevElem = target.get(index);
18716
+ if (!prevElem) {
18717
+ throw new YorkieError(
18718
+ Code.ErrInvalidArgument,
18719
+ `index out of bounds: ${index}`
18720
+ );
18721
+ }
18722
+ ArrayProxy.insertAfterInternal(
18723
+ context,
18724
+ target,
18725
+ prevElem.getCreatedAt(),
18726
+ value
18727
+ );
18728
+ return target;
18729
+ }
18537
18730
  /**
18538
18731
  * `insertBeforeInternal` inserts the value before the previously created element.
18539
18732
  */
@@ -18545,6 +18738,39 @@ class ArrayProxy {
18545
18738
  value
18546
18739
  );
18547
18740
  }
18741
+ /**
18742
+ * `setIntegerInternal` sets the given integer at the given index.
18743
+ */
18744
+ static setIntegerInternal(context, target, index, value) {
18745
+ const prev = target.get(index);
18746
+ if (!prev) {
18747
+ throw new YorkieError(
18748
+ Code.ErrInvalidArgument,
18749
+ `index out of bounds: ${index}`
18750
+ );
18751
+ }
18752
+ ArrayProxy.setByIndexInternal(context, target, prev.getCreatedAt(), value);
18753
+ return target;
18754
+ }
18755
+ /**
18756
+ * `setByIndexInternal` sets the element of the given index.
18757
+ */
18758
+ static setByIndexInternal(context, target, createdAt, value) {
18759
+ const ticket = context.issueTimeTicket();
18760
+ const element = buildCRDTElement(context, value, ticket);
18761
+ const copiedValue = element.deepcopy();
18762
+ context.push(
18763
+ ArraySetOperation.create(
18764
+ target.getCreatedAt(),
18765
+ createdAt,
18766
+ copiedValue,
18767
+ ticket
18768
+ )
18769
+ );
18770
+ target.set(createdAt, element, ticket);
18771
+ context.registerElement(element, target);
18772
+ return element;
18773
+ }
18548
18774
  /**
18549
18775
  * `deleteInternalByIndex` deletes target element of given index.
18550
18776
  */
@@ -21296,7 +21522,7 @@ function createAuthInterceptor(apiKey, token) {
21296
21522
  };
21297
21523
  }
21298
21524
  const name = "@yorkie-js/sdk";
21299
- const version = "0.6.22";
21525
+ const version = "0.6.23";
21300
21526
  const pkg = {
21301
21527
  name,
21302
21528
  version