@yorkie-js/sdk 0.7.5 → 0.7.6

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.
@@ -5792,7 +5792,7 @@
5792
5792
  }
5793
5793
  };
5794
5794
  }
5795
- const file_src_api_yorkie_v1_resources = /* @__PURE__ */ fileDesc("CiFzcmMvYXBpL3lvcmtpZS92MS9yZXNvdXJjZXMucHJvdG8SCXlvcmtpZS52MSKuAQoIU25hcHNob3QSJAoEcm9vdBgBIAEoCzIWLnlvcmtpZS52MS5KU09ORWxlbWVudBI1CglwcmVzZW5jZXMYAiADKAsyIi55b3JraWUudjEuU25hcHNob3QuUHJlc2VuY2VzRW50cnkaRQoOUHJlc2VuY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLlByZXNlbmNlOgI4ASL7AQoKQ2hhbmdlUGFjaxIUCgxkb2N1bWVudF9rZXkYASABKAkSKQoKY2hlY2twb2ludBgCIAEoCzIVLnlvcmtpZS52MS5DaGVja3BvaW50EhAKCHNuYXBzaG90GAMgASgMEiIKB2NoYW5nZXMYBCADKAsyES55b3JraWUudjEuQ2hhbmdlEjAKEW1pbl9zeW5jZWRfdGlja2V0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgGIAEoCBIwCg52ZXJzaW9uX3ZlY3RvchgHIAEoCzIYLnlvcmtpZS52MS5WZXJzaW9uVmVjdG9yIpgBCgZDaGFuZ2USHwoCaWQYASABKAsyEy55b3JraWUudjEuQ2hhbmdlSUQSDwoHbWVzc2FnZRgCIAEoCRIoCgpvcGVyYXRpb25zGAMgAygLMhQueW9ya2llLnYxLk9wZXJhdGlvbhIyCg9wcmVzZW5jZV9jaGFuZ2UYBCABKAsyGS55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UihwEKCENoYW5nZUlEEhIKCmNsaWVudF9zZXEYASABKA0SEgoKc2VydmVyX3NlcRgCIAEoAxIPCgdsYW1wb3J0GAMgASgDEhAKCGFjdG9yX2lkGAQgASgMEjAKDnZlcnNpb25fdmVjdG9yGAUgASgLMhgueW9ya2llLnYxLlZlcnNpb25WZWN0b3IidAoNVmVyc2lvblZlY3RvchI0CgZ2ZWN0b3IYASADKAsyJC55b3JraWUudjEuVmVyc2lvblZlY3Rvci5WZWN0b3JFbnRyeRotCgtWZWN0b3JFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAM6AjgBItkaCglPcGVyYXRpb24SJwoDc2V0GAEgASgLMhgueW9ya2llLnYxLk9wZXJhdGlvbi5TZXRIABInCgNhZGQYAiABKAsyGC55b3JraWUudjEuT3BlcmF0aW9uLkFkZEgAEikKBG1vdmUYAyABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLk1vdmVIABItCgZyZW1vdmUYBCABKAsyGy55b3JraWUudjEuT3BlcmF0aW9uLlJlbW92ZUgAEikKBGVkaXQYBSABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLkVkaXRIABIrCgVzdHlsZRgHIAEoCzIaLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGVIABIxCghpbmNyZWFzZRgIIAEoCzIdLnlvcmtpZS52MS5PcGVyYXRpb24uSW5jcmVhc2VIABIyCgl0cmVlX2VkaXQYCSABKAsyHS55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0SAASNAoKdHJlZV9zdHlsZRgKIAEoCzIeLnlvcmtpZS52MS5PcGVyYXRpb24uVHJlZVN0eWxlSAASMgoJYXJyYXlfc2V0GAsgASgLMh0ueW9ya2llLnYxLk9wZXJhdGlvbi5BcnJheVNldEgAGp0BCgNTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBILCgNrZXkYAiABKAkSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrAAQoDQWRkEjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSLgoPcHJldl9jcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBq/AQoETW92ZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Ei4KD3ByZXZfY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCmNyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIqCgtleGVjdXRlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GpEBCgZSZW1vdmUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLZXhlY3V0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrZAwoERWRpdBIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSUwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyMi55b3JraWUudjEuT3BlcmF0aW9uLkVkaXQuQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5Eg8KB2NvbnRlbnQYBSABKAkSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBI9CgphdHRyaWJ1dGVzGAcgAygLMikueW9ya2llLnYxLk9wZXJhdGlvbi5FZGl0LkF0dHJpYnV0ZXNFbnRyeRpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGjEKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGukDCgVTdHlsZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSPgoKYXR0cmlidXRlcxgEIAMoCzIqLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSVAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBiADKAsyMy55b3JraWUudjEuT3BlcmF0aW9uLlN0eWxlLkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRIcChRhdHRyaWJ1dGVzX3RvX3JlbW92ZRgHIAMoCRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGqQBCghJbmNyZWFzZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EisKBXZhbHVlGAIgASgLMhwueW9ya2llLnYxLkpTT05FbGVtZW50U2ltcGxlEioKC2V4ZWN1dGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDQoFYWN0b3IYBCABKAkakwMKCFRyZWVFZGl0EjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIAoEZnJvbRgCIAEoCzISLnlvcmtpZS52MS5UcmVlUG9zEh4KAnRvGAMgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSVwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyNi55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0LkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRImCghjb250ZW50cxgFIAMoCzIULnlvcmtpZS52MS5UcmVlTm9kZXMSEwoLc3BsaXRfbGV2ZWwYByABKAUSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGu0DCglUcmVlU3R5bGUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIgCgRmcm9tGAIgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSHgoCdG8YAyABKAsyEi55b3JraWUudjEuVHJlZVBvcxJCCgphdHRyaWJ1dGVzGAQgAygLMi4ueW9ya2llLnYxLk9wZXJhdGlvbi5UcmVlU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSHAoUYXR0cmlidXRlc190b19yZW1vdmUYBiADKAkSWAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYByADKAsyNy55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVTdHlsZS5DcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaUQoYQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0OgI4ARrAAQoIQXJyYXlTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldEIGCgRib2R5IsUBChFKU09ORWxlbWVudFNpbXBsZRIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIgoEdHlwZRgEIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYBSABKAwinwsKC0pTT05FbGVtZW50EjgKC2pzb25fb2JqZWN0GAEgASgLMiEueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05PYmplY3RIABI2Cgpqc29uX2FycmF5GAIgASgLMiAueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05BcnJheUgAEjUKCXByaW1pdGl2ZRgDIAEoCzIgLnlvcmtpZS52MS5KU09ORWxlbWVudC5QcmltaXRpdmVIABIrCgR0ZXh0GAUgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRleHRIABIxCgdjb3VudGVyGAYgASgLMh4ueW9ya2llLnYxLkpTT05FbGVtZW50LkNvdW50ZXJIABIrCgR0cmVlGAcgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRyZWVIABquAQoKSlNPTk9iamVjdBIhCgVub2RlcxgBIAMoCzISLnlvcmtpZS52MS5SSFROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBqtAQoJSlNPTkFycmF5EiEKBW5vZGVzGAEgAygLMhIueW9ya2llLnYxLlJHQU5vZGUSKQoKY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Gr0BCglQcmltaXRpdmUSIgoEdHlwZRgBIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYAiABKAwSKQoKY3JlYXRlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgFIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GqkBCgRUZXh0EiIKBW5vZGVzGAEgAygLMhMueW9ya2llLnYxLlRleHROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrYAQoHQ291bnRlchIiCgR0eXBlGAEgASgOMhQueW9ya2llLnYxLlZhbHVlVHlwZRINCgV2YWx1ZRgCIAEoDBIpCgpjcmVhdGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSFQoNaGxsX3JlZ2lzdGVycxgHIAEoDEoECAYQBxqpAQoEVHJlZRIiCgVub2RlcxgBIAMoCzITLnlvcmtpZS52MS5UcmVlTm9kZRIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXRCBgoEYm9keSI/CgdSSFROb2RlEgsKA2tleRgBIAEoCRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50IlQKB1JHQU5vZGUSIAoEbmV4dBgBIAEoCzISLnlvcmtpZS52MS5SR0FOb2RlEicKB2VsZW1lbnQYAiABKAsyFi55b3JraWUudjEuSlNPTkVsZW1lbnQiWAoITm9kZUF0dHISDQoFdmFsdWUYASABKAkSKQoKdXBkYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EhIKCmlzX3JlbW92ZWQYAyABKAgilAIKCFRleHROb2RlEiEKAmlkGAEgASgLMhUueW9ya2llLnYxLlRleHROb2RlSUQSDQoFdmFsdWUYAiABKAkSKQoKcmVtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EioKC2luc19wcmV2X2lkGAQgASgLMhUueW9ya2llLnYxLlRleHROb2RlSUQSNwoKYXR0cmlidXRlcxgFIAMoCzIjLnlvcmtpZS52MS5UZXh0Tm9kZS5BdHRyaWJ1dGVzRW50cnkaRgoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5Ob2RlQXR0cjoCOAEiRwoKVGV4dE5vZGVJRBIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFIrMDCghUcmVlTm9kZRIhCgJpZBgBIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEgwKBHR5cGUYAiABKAkSDQoFdmFsdWUYAyABKAkSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EioKC2luc19wcmV2X2lkGAUgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSKgoLaW5zX25leHRfaWQYBiABKAsyFS55b3JraWUudjEuVHJlZU5vZGVJRBINCgVkZXB0aBgHIAEoBRI3CgphdHRyaWJ1dGVzGAggAygLMiMueW9ya2llLnYxLlRyZWVOb2RlLkF0dHJpYnV0ZXNFbnRyeRIqCgttZXJnZWRfZnJvbRgJIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEigKCW1lcmdlZF9hdBgKIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GkYKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSIgoFdmFsdWUYAiABKAsyEy55b3JraWUudjEuTm9kZUF0dHI6AjgBIjEKCVRyZWVOb2RlcxIkCgdjb250ZW50GAEgAygLMhMueW9ya2llLnYxLlRyZWVOb2RlIkcKClRyZWVOb2RlSUQSKQoKY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Eg4KBm9mZnNldBgCIAEoBSJjCgdUcmVlUG9zEigKCXBhcmVudF9pZBgBIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEi4KD2xlZnRfc2libGluZ19pZBgCIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEImsKBFVzZXISCgoCaWQYASABKAkSFQoNYXV0aF9wcm92aWRlchgCIAEoCRIQCgh1c2VybmFtZRgDIAEoCRIuCgpjcmVhdGVkX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCKJAQoGTWVtYmVyEgoKAmlkGAEgASgJEhIKCnByb2plY3RfaWQYAiABKAkSDwoHdXNlcl9pZBgDIAEoCRIQCgh1c2VybmFtZRgEIAEoCRIMCgRyb2xlGAUgASgJEi4KCmludml0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIukGCgdQcm9qZWN0EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSEgoKcHVibGljX2tleRgDIAEoCRISCgpzZWNyZXRfa2V5GAQgASgJEhgKEGF1dGhfd2ViaG9va191cmwYBSABKAkSHAoUYXV0aF93ZWJob29rX21ldGhvZHMYBiADKAkSIAoYYXV0aF93ZWJob29rX21heF9yZXRyaWVzGBEgASgEEiYKHmF1dGhfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgSIAEoCRImCh5hdXRoX3dlYmhvb2tfbWF4X3dhaXRfaW50ZXJ2YWwYEyABKAkSJAocYXV0aF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgUIAEoCRIZChFldmVudF93ZWJob29rX3VybBgHIAEoCRIcChRldmVudF93ZWJob29rX2V2ZW50cxgIIAMoCRIhChlldmVudF93ZWJob29rX21heF9yZXRyaWVzGBUgASgEEicKH2V2ZW50X3dlYmhvb2tfbWluX3dhaXRfaW50ZXJ2YWwYFiABKAkSJwofZXZlbnRfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgXIAEoCRIlCh1ldmVudF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgYIAEoCRIjChtjbGllbnRfZGVhY3RpdmF0ZV90aHJlc2hvbGQYCSABKAkSGgoSc25hcHNob3RfdGhyZXNob2xkGBkgASgDEhkKEXNuYXBzaG90X2ludGVydmFsGBogASgDEiQKHG1heF9zdWJzY3JpYmVyc19wZXJfZG9jdW1lbnQYCiABKAUSJAocbWF4X2F0dGFjaG1lbnRzX3Blcl9kb2N1bWVudBgLIAEoBRIdChVtYXhfc2l6ZV9wZXJfZG9jdW1lbnQYDyABKAUSGAoQcmVtb3ZlX29uX2RldGFjaBgQIAEoCBIdChVhdXRvX3JldmlzaW9uX2VuYWJsZWQYGyABKAgSFwoPYWxsb3dlZF9vcmlnaW5zGA4gAygJEi4KCmNyZWF0ZWRfYXQYDCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi4KCnVwZGF0ZWRfYXQYDSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIi8KC01ldHJpY1BvaW50EhEKCXRpbWVzdGFtcBgBIAEoAxINCgV2YWx1ZRgCIAEoBSKjDAoWVXBkYXRhYmxlUHJvamVjdEZpZWxkcxIqCgRuYW1lGAEgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjYKEGF1dGhfd2ViaG9va191cmwYAiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSUgoUYXV0aF93ZWJob29rX21ldGhvZHMYAyABKAsyNC55b3JraWUudjEuVXBkYXRhYmxlUHJvamVjdEZpZWxkcy5BdXRoV2ViaG9va01ldGhvZHMSPgoYYXV0aF93ZWJob29rX21heF9yZXRyaWVzGAwgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlEkQKHmF1dGhfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgNIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJECh5hdXRoX3dlYmhvb2tfbWF4X3dhaXRfaW50ZXJ2YWwYDiABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSQgocYXV0aF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgPIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRI3ChFldmVudF93ZWJob29rX3VybBgEIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJSChRldmVudF93ZWJob29rX2V2ZW50cxgFIAEoCzI0LnlvcmtpZS52MS5VcGRhdGFibGVQcm9qZWN0RmllbGRzLkV2ZW50V2ViaG9va0V2ZW50cxI/ChlldmVudF93ZWJob29rX21heF9yZXRyaWVzGBAgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlEkUKH2V2ZW50X3dlYmhvb2tfbWluX3dhaXRfaW50ZXJ2YWwYESABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSRQofZXZlbnRfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgSIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJDCh1ldmVudF93ZWJob29rX3JlcXVlc3RfdGltZW91dBgTIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRI3ChJzbmFwc2hvdF90aHJlc2hvbGQYFCABKAsyGy5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZRI2ChFzbmFwc2hvdF9pbnRlcnZhbBgVIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEkEKG2NsaWVudF9kZWFjdGl2YXRlX3RocmVzaG9sZBgGIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJBChxtYXhfc3Vic2NyaWJlcnNfcGVyX2RvY3VtZW50GAcgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSQQocbWF4X2F0dGFjaG1lbnRzX3Blcl9kb2N1bWVudBgIIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjoKFW1heF9zaXplX3Blcl9kb2N1bWVudBgKIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjQKEHJlbW92ZV9vbl9kZXRhY2gYCyABKAsyGi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlEjkKFWF1dG9fcmV2aXNpb25fZW5hYmxlZBgWIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSSQoPYWxsb3dlZF9vcmlnaW5zGAkgASgLMjAueW9ya2llLnYxLlVwZGF0YWJsZVByb2plY3RGaWVsZHMuQWxsb3dlZE9yaWdpbnMaJQoSQXV0aFdlYmhvb2tNZXRob2RzEg8KB21ldGhvZHMYASADKAkaJAoSRXZlbnRXZWJob29rRXZlbnRzEg4KBmV2ZW50cxgBIAMoCRohCg5BbGxvd2VkT3JpZ2lucxIPCgdvcmlnaW5zGAEgAygJIqcDCg9Eb2N1bWVudFN1bW1hcnkSCgoCaWQYASABKAkSCwoDa2V5GAIgASgJEgwKBHJvb3QYAyABKAkSGAoQYXR0YWNoZWRfY2xpZW50cxgHIAEoBRIpCg1kb2N1bWVudF9zaXplGAggASgLMhIueW9ya2llLnYxLkRvY1NpemUSEgoKc2NoZW1hX2tleRgJIAEoCRI8CglwcmVzZW5jZXMYCiADKAsyKS55b3JraWUudjEuRG9jdW1lbnRTdW1tYXJ5LlByZXNlbmNlc0VudHJ5Ei4KCmNyZWF0ZWRfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KC2FjY2Vzc2VkX2F0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIuCgp1cGRhdGVkX2F0GAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBpFCg5QcmVzZW5jZXNFbnRyeRILCgNrZXkYASABKAkSIgoFdmFsdWUYAiABKAsyEy55b3JraWUudjEuUHJlc2VuY2U6AjgBItoBCg5QcmVzZW5jZUNoYW5nZRIyCgR0eXBlGAEgASgOMiQueW9ya2llLnYxLlByZXNlbmNlQ2hhbmdlLkNoYW5nZVR5cGUSJQoIcHJlc2VuY2UYAiABKAsyEy55b3JraWUudjEuUHJlc2VuY2UibQoKQ2hhbmdlVHlwZRIbChdDSEFOR0VfVFlQRV9VTlNQRUNJRklFRBAAEhMKD0NIQU5HRV9UWVBFX1BVVBABEhYKEkNIQU5HRV9UWVBFX0RFTEVURRACEhUKEUNIQU5HRV9UWVBFX0NMRUFSEAMiZAoIUHJlc2VuY2USKwoEZGF0YRgBIAMoCzIdLnlvcmtpZS52MS5QcmVzZW5jZS5EYXRhRW50cnkaKwoJRGF0YUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiNAoOQ2hhbm5lbFN1bW1hcnkSCwoDa2V5GAEgASgJEhUKDXNlc3Npb25fY291bnQYAiABKAUiNAoKQ2hlY2twb2ludBISCgpzZXJ2ZXJfc2VxGAEgASgDEhIKCmNsaWVudF9zZXEYAiABKA0iYQoLVGV4dE5vZGVQb3MSKQoKY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Eg4KBm9mZnNldBgCIAEoBRIXCg9yZWxhdGl2ZV9vZmZzZXQYAyABKAUiQgoKVGltZVRpY2tldBIPCgdsYW1wb3J0GAEgASgDEhEKCWRlbGltaXRlchgCIAEoDRIQCghhY3Rvcl9pZBgDIAEoDCIuCgxEb2NFdmVudEJvZHkSDQoFdG9waWMYASABKAkSDwoHcGF5bG9hZBgCIAEoDCJrCghEb2NFdmVudBIlCgR0eXBlGAEgASgOMhcueW9ya2llLnYxLkRvY0V2ZW50VHlwZRIRCglwdWJsaXNoZXIYAiABKAkSJQoEYm9keRgDIAEoCzIXLnlvcmtpZS52MS5Eb2NFdmVudEJvZHki1gEKDENoYW5uZWxFdmVudBIqCgR0eXBlGAEgASgOMhwueW9ya2llLnYxLkNoYW5uZWxFdmVudC5UeXBlEhEKCXB1Ymxpc2hlchgCIAEoCRIVCg1zZXNzaW9uX2NvdW50GAMgASgDEgsKA3NlcRgEIAEoAxINCgV0b3BpYxgFIAEoCRIPCgdwYXlsb2FkGAYgASgMIkMKBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEhEKDVRZUEVfUFJFU0VOQ0UQARISCg5UWVBFX0JST0FEQ0FTVBACIiYKCERhdGFTaXplEgwKBGRhdGEYASABKAUSDAoEbWV0YRgCIAEoBSJNCgdEb2NTaXplEiEKBGxpdmUYASABKAsyEy55b3JraWUudjEuRGF0YVNpemUSHwoCZ2MYAiABKAsyEy55b3JraWUudjEuRGF0YVNpemUikQEKBlNjaGVtYRIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEg8KB3ZlcnNpb24YAyABKAUSDAoEYm9keRgEIAEoCRIeCgVydWxlcxgFIAMoCzIPLnlvcmtpZS52MS5SdWxlEi4KCmNyZWF0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIlAKDFRyZWVOb2RlUnVsZRIRCglub2RlX3R5cGUYASABKAkSDwoHY29udGVudBgCIAEoCRINCgVtYXJrcxgDIAEoCRINCgVncm91cBgEIAEoCSJPCgRSdWxlEgwKBHBhdGgYASABKAkSDAoEdHlwZRgCIAEoCRIrCgp0cmVlX25vZGVzGAMgAygLMhcueW9ya2llLnYxLlRyZWVOb2RlUnVsZSKDAQoPUmV2aXNpb25TdW1tYXJ5EgoKAmlkGAEgASgJEg0KBWxhYmVsGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEhAKCHNuYXBzaG90GAQgASgJEi4KCmNyZWF0ZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wKvwCCglWYWx1ZVR5cGUSEwoPVkFMVUVfVFlQRV9OVUxMEAASFgoSVkFMVUVfVFlQRV9CT09MRUFOEAESFgoSVkFMVUVfVFlQRV9JTlRFR0VSEAISEwoPVkFMVUVfVFlQRV9MT05HEAMSFQoRVkFMVUVfVFlQRV9ET1VCTEUQBBIVChFWQUxVRV9UWVBFX1NUUklORxAFEhQKEFZBTFVFX1RZUEVfQllURVMQBhITCg9WQUxVRV9UWVBFX0RBVEUQBxIaChZWQUxVRV9UWVBFX0pTT05fT0JKRUNUEAgSGQoVVkFMVUVfVFlQRV9KU09OX0FSUkFZEAkSEwoPVkFMVUVfVFlQRV9URVhUEAoSGgoWVkFMVUVfVFlQRV9JTlRFR0VSX0NOVBALEhcKE1ZBTFVFX1RZUEVfTE9OR19DTlQQDBITCg9WQUxVRV9UWVBFX1RSRUUQDRIgChxWQUxVRV9UWVBFX0lOVEVHRVJfREVEVVBfQ05UEA4iBAgPEA8qpgEKDERvY0V2ZW50VHlwZRIjCh9ET0NfRVZFTlRfVFlQRV9ET0NVTUVOVF9DSEFOR0VEEAASIwofRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfV0FUQ0hFRBABEiUKIURPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX1VOV0FUQ0hFRBACEiUKIURPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX0JST0FEQ0FTVBADQkUKEWRldi55b3JraWUuYXBpLnYxUAFaLmdpdGh1Yi5jb20veW9ya2llLXRlYW0veW9ya2llL2FwaS95b3JraWUvdjE7djFiBnByb3RvMw", [file_google_protobuf_timestamp, file_google_protobuf_wrappers]);
5795
+ const file_src_api_yorkie_v1_resources = /* @__PURE__ */ fileDesc("CiFzcmMvYXBpL3lvcmtpZS92MS9yZXNvdXJjZXMucHJvdG8SCXlvcmtpZS52MSKuAQoIU25hcHNob3QSJAoEcm9vdBgBIAEoCzIWLnlvcmtpZS52MS5KU09ORWxlbWVudBI1CglwcmVzZW5jZXMYAiADKAsyIi55b3JraWUudjEuU25hcHNob3QuUHJlc2VuY2VzRW50cnkaRQoOUHJlc2VuY2VzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLlByZXNlbmNlOgI4ASL7AQoKQ2hhbmdlUGFjaxIUCgxkb2N1bWVudF9rZXkYASABKAkSKQoKY2hlY2twb2ludBgCIAEoCzIVLnlvcmtpZS52MS5DaGVja3BvaW50EhAKCHNuYXBzaG90GAMgASgMEiIKB2NoYW5nZXMYBCADKAsyES55b3JraWUudjEuQ2hhbmdlEjAKEW1pbl9zeW5jZWRfdGlja2V0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgGIAEoCBIwCg52ZXJzaW9uX3ZlY3RvchgHIAEoCzIYLnlvcmtpZS52MS5WZXJzaW9uVmVjdG9yIpgBCgZDaGFuZ2USHwoCaWQYASABKAsyEy55b3JraWUudjEuQ2hhbmdlSUQSDwoHbWVzc2FnZRgCIAEoCRIoCgpvcGVyYXRpb25zGAMgAygLMhQueW9ya2llLnYxLk9wZXJhdGlvbhIyCg9wcmVzZW5jZV9jaGFuZ2UYBCABKAsyGS55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UihwEKCENoYW5nZUlEEhIKCmNsaWVudF9zZXEYASABKA0SEgoKc2VydmVyX3NlcRgCIAEoAxIPCgdsYW1wb3J0GAMgASgDEhAKCGFjdG9yX2lkGAQgASgMEjAKDnZlcnNpb25fdmVjdG9yGAUgASgLMhgueW9ya2llLnYxLlZlcnNpb25WZWN0b3IidAoNVmVyc2lvblZlY3RvchI0CgZ2ZWN0b3IYASADKAsyJC55b3JraWUudjEuVmVyc2lvblZlY3Rvci5WZWN0b3JFbnRyeRotCgtWZWN0b3JFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAM6AjgBItkaCglPcGVyYXRpb24SJwoDc2V0GAEgASgLMhgueW9ya2llLnYxLk9wZXJhdGlvbi5TZXRIABInCgNhZGQYAiABKAsyGC55b3JraWUudjEuT3BlcmF0aW9uLkFkZEgAEikKBG1vdmUYAyABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLk1vdmVIABItCgZyZW1vdmUYBCABKAsyGy55b3JraWUudjEuT3BlcmF0aW9uLlJlbW92ZUgAEikKBGVkaXQYBSABKAsyGS55b3JraWUudjEuT3BlcmF0aW9uLkVkaXRIABIrCgVzdHlsZRgHIAEoCzIaLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGVIABIxCghpbmNyZWFzZRgIIAEoCzIdLnlvcmtpZS52MS5PcGVyYXRpb24uSW5jcmVhc2VIABIyCgl0cmVlX2VkaXQYCSABKAsyHS55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0SAASNAoKdHJlZV9zdHlsZRgKIAEoCzIeLnlvcmtpZS52MS5PcGVyYXRpb24uVHJlZVN0eWxlSAASMgoJYXJyYXlfc2V0GAsgASgLMh0ueW9ya2llLnYxLk9wZXJhdGlvbi5BcnJheVNldEgAGp0BCgNTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBILCgNrZXkYAiABKAkSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrAAQoDQWRkEjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSLgoPcHJldl9jcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBq/AQoETW92ZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Ei4KD3ByZXZfY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCmNyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIqCgtleGVjdXRlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GpEBCgZSZW1vdmUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLZXhlY3V0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrZAwoERWRpdBIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSUwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyMi55b3JraWUudjEuT3BlcmF0aW9uLkVkaXQuQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5Eg8KB2NvbnRlbnQYBSABKAkSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBI9CgphdHRyaWJ1dGVzGAcgAygLMikueW9ya2llLnYxLk9wZXJhdGlvbi5FZGl0LkF0dHJpYnV0ZXNFbnRyeRpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGjEKD0F0dHJpYnV0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGukDCgVTdHlsZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EiQKBGZyb20YAiABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSIgoCdG8YAyABKAsyFi55b3JraWUudjEuVGV4dE5vZGVQb3MSPgoKYXR0cmlidXRlcxgEIAMoCzIqLnlvcmtpZS52MS5PcGVyYXRpb24uU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSVAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBiADKAsyMy55b3JraWUudjEuT3BlcmF0aW9uLlN0eWxlLkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRIcChRhdHRyaWJ1dGVzX3RvX3JlbW92ZRgHIAMoCRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ARpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGqQBCghJbmNyZWFzZRIwChFwYXJlbnRfY3JlYXRlZF9hdBgBIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EisKBXZhbHVlGAIgASgLMhwueW9ya2llLnYxLkpTT05FbGVtZW50U2ltcGxlEioKC2V4ZWN1dGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDQoFYWN0b3IYBCABKAkakwMKCFRyZWVFZGl0EjAKEXBhcmVudF9jcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIAoEZnJvbRgCIAEoCzISLnlvcmtpZS52MS5UcmVlUG9zEh4KAnRvGAMgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSVwoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYBCADKAsyNi55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVFZGl0LkNyZWF0ZWRBdE1hcEJ5QWN0b3JFbnRyeRImCghjb250ZW50cxgFIAMoCzIULnlvcmtpZS52MS5UcmVlTm9kZXMSEwoLc3BsaXRfbGV2ZWwYByABKAUSKgoLZXhlY3V0ZWRfYXQYBiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBpRChhDcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQ6AjgBGu0DCglUcmVlU3R5bGUSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIgCgRmcm9tGAIgASgLMhIueW9ya2llLnYxLlRyZWVQb3MSHgoCdG8YAyABKAsyEi55b3JraWUudjEuVHJlZVBvcxJCCgphdHRyaWJ1dGVzGAQgAygLMi4ueW9ya2llLnYxLk9wZXJhdGlvbi5UcmVlU3R5bGUuQXR0cmlidXRlc0VudHJ5EioKC2V4ZWN1dGVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSHAoUYXR0cmlidXRlc190b19yZW1vdmUYBiADKAkSWAoXY3JlYXRlZF9hdF9tYXBfYnlfYWN0b3IYByADKAsyNy55b3JraWUudjEuT3BlcmF0aW9uLlRyZWVTdHlsZS5DcmVhdGVkQXRNYXBCeUFjdG9yRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaUQoYQ3JlYXRlZEF0TWFwQnlBY3RvckVudHJ5EgsKA2tleRgBIAEoCRIkCgV2YWx1ZRgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0OgI4ARrAAQoIQXJyYXlTZXQSMAoRcGFyZW50X2NyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKwoFdmFsdWUYAyABKAsyHC55b3JraWUudjEuSlNPTkVsZW1lbnRTaW1wbGUSKgoLZXhlY3V0ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldEIGCgRib2R5IsUBChFKU09ORWxlbWVudFNpbXBsZRIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSIgoEdHlwZRgEIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYBSABKAwinwsKC0pTT05FbGVtZW50EjgKC2pzb25fb2JqZWN0GAEgASgLMiEueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05PYmplY3RIABI2Cgpqc29uX2FycmF5GAIgASgLMiAueW9ya2llLnYxLkpTT05FbGVtZW50LkpTT05BcnJheUgAEjUKCXByaW1pdGl2ZRgDIAEoCzIgLnlvcmtpZS52MS5KU09ORWxlbWVudC5QcmltaXRpdmVIABIrCgR0ZXh0GAUgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRleHRIABIxCgdjb3VudGVyGAYgASgLMh4ueW9ya2llLnYxLkpTT05FbGVtZW50LkNvdW50ZXJIABIrCgR0cmVlGAcgASgLMhsueW9ya2llLnYxLkpTT05FbGVtZW50LlRyZWVIABquAQoKSlNPTk9iamVjdBIhCgVub2RlcxgBIAMoCzISLnlvcmtpZS52MS5SSFROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBqtAQoJSlNPTkFycmF5EiEKBW5vZGVzGAEgAygLMhIueW9ya2llLnYxLlJHQU5vZGUSKQoKY3JlYXRlZF9hdBgCIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0Gr0BCglQcmltaXRpdmUSIgoEdHlwZRgBIAEoDjIULnlvcmtpZS52MS5WYWx1ZVR5cGUSDQoFdmFsdWUYAiABKAwSKQoKY3JlYXRlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EicKCG1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKQoKcmVtb3ZlZF9hdBgFIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0GqkBCgRUZXh0EiIKBW5vZGVzGAEgAygLMhMueW9ya2llLnYxLlRleHROb2RlEikKCmNyZWF0ZWRfYXQYAiABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBInCghtb3ZlZF9hdBgDIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EikKCnJlbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBrYAQoHQ291bnRlchIiCgR0eXBlGAEgASgOMhQueW9ya2llLnYxLlZhbHVlVHlwZRINCgV2YWx1ZRgCIAEoDBIpCgpjcmVhdGVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYBCABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAUgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSFQoNaGxsX3JlZ2lzdGVycxgHIAEoDEoECAYQBxqpAQoEVHJlZRIiCgVub2RlcxgBIAMoCzITLnlvcmtpZS52MS5UcmVlTm9kZRIpCgpjcmVhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSJwoIbW92ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXRCBgoEYm9keSI/CgdSSFROb2RlEgsKA2tleRgBIAEoCRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50Iu4BCgdSR0FOb2RlEiAKBG5leHQYASABKAsyEi55b3JraWUudjEuUkdBTm9kZRInCgdlbGVtZW50GAIgASgLMhYueW9ya2llLnYxLkpTT05FbGVtZW50EjIKE3Bvc2l0aW9uX2NyZWF0ZWRfYXQYAyABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIwChFwb3NpdGlvbl9tb3ZlZF9hdBgEIAEoCzIVLnlvcmtpZS52MS5UaW1lVGlja2V0EjIKE3Bvc2l0aW9uX3JlbW92ZWRfYXQYBSABKAsyFS55b3JraWUudjEuVGltZVRpY2tldCJYCghOb2RlQXR0chINCgV2YWx1ZRgBIAEoCRIpCgp1cGRhdGVkX2F0GAIgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSEgoKaXNfcmVtb3ZlZBgDIAEoCCKUAgoIVGV4dE5vZGUSIQoCaWQYASABKAsyFS55b3JraWUudjEuVGV4dE5vZGVJRBINCgV2YWx1ZRgCIAEoCRIpCgpyZW1vdmVkX2F0GAMgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLaW5zX3ByZXZfaWQYBCABKAsyFS55b3JraWUudjEuVGV4dE5vZGVJRBI3CgphdHRyaWJ1dGVzGAUgAygLMiMueW9ya2llLnYxLlRleHROb2RlLkF0dHJpYnV0ZXNFbnRyeRpGCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEiIKBXZhbHVlGAIgASgLMhMueW9ya2llLnYxLk5vZGVBdHRyOgI4ASJHCgpUZXh0Tm9kZUlEEikKCmNyZWF0ZWRfYXQYASABKAsyFS55b3JraWUudjEuVGltZVRpY2tldBIOCgZvZmZzZXQYAiABKAUiswMKCFRyZWVOb2RlEiEKAmlkGAEgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSDAoEdHlwZRgCIAEoCRINCgV2YWx1ZRgDIAEoCRIpCgpyZW1vdmVkX2F0GAQgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSKgoLaW5zX3ByZXZfaWQYBSABKAsyFS55b3JraWUudjEuVHJlZU5vZGVJRBIqCgtpbnNfbmV4dF9pZBgGIAEoCzIVLnlvcmtpZS52MS5UcmVlTm9kZUlEEg0KBWRlcHRoGAcgASgFEjcKCmF0dHJpYnV0ZXMYCCADKAsyIy55b3JraWUudjEuVHJlZU5vZGUuQXR0cmlidXRlc0VudHJ5EioKC21lcmdlZF9mcm9tGAkgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSKAoJbWVyZ2VkX2F0GAogASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQaRgoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5Ob2RlQXR0cjoCOAEiMQoJVHJlZU5vZGVzEiQKB2NvbnRlbnQYASADKAsyEy55b3JraWUudjEuVHJlZU5vZGUiRwoKVHJlZU5vZGVJRBIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFImMKB1RyZWVQb3MSKAoJcGFyZW50X2lkGAEgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQSLgoPbGVmdF9zaWJsaW5nX2lkGAIgASgLMhUueW9ya2llLnYxLlRyZWVOb2RlSUQiawoEVXNlchIKCgJpZBgBIAEoCRIVCg1hdXRoX3Byb3ZpZGVyGAIgASgJEhAKCHVzZXJuYW1lGAMgASgJEi4KCmNyZWF0ZWRfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIokBCgZNZW1iZXISCgoCaWQYASABKAkSEgoKcHJvamVjdF9pZBgCIAEoCRIPCgd1c2VyX2lkGAMgASgJEhAKCHVzZXJuYW1lGAQgASgJEgwKBHJvbGUYBSABKAkSLgoKaW52aXRlZF9hdBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAi6QYKB1Byb2plY3QSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRISCgpwdWJsaWNfa2V5GAMgASgJEhIKCnNlY3JldF9rZXkYBCABKAkSGAoQYXV0aF93ZWJob29rX3VybBgFIAEoCRIcChRhdXRoX3dlYmhvb2tfbWV0aG9kcxgGIAMoCRIgChhhdXRoX3dlYmhvb2tfbWF4X3JldHJpZXMYESABKAQSJgoeYXV0aF93ZWJob29rX21pbl93YWl0X2ludGVydmFsGBIgASgJEiYKHmF1dGhfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgTIAEoCRIkChxhdXRoX3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBQgASgJEhkKEWV2ZW50X3dlYmhvb2tfdXJsGAcgASgJEhwKFGV2ZW50X3dlYmhvb2tfZXZlbnRzGAggAygJEiEKGWV2ZW50X3dlYmhvb2tfbWF4X3JldHJpZXMYFSABKAQSJwofZXZlbnRfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgWIAEoCRInCh9ldmVudF93ZWJob29rX21heF93YWl0X2ludGVydmFsGBcgASgJEiUKHWV2ZW50X3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBggASgJEiMKG2NsaWVudF9kZWFjdGl2YXRlX3RocmVzaG9sZBgJIAEoCRIaChJzbmFwc2hvdF90aHJlc2hvbGQYGSABKAMSGQoRc25hcHNob3RfaW50ZXJ2YWwYGiABKAMSJAocbWF4X3N1YnNjcmliZXJzX3Blcl9kb2N1bWVudBgKIAEoBRIkChxtYXhfYXR0YWNobWVudHNfcGVyX2RvY3VtZW50GAsgASgFEh0KFW1heF9zaXplX3Blcl9kb2N1bWVudBgPIAEoBRIYChByZW1vdmVfb25fZGV0YWNoGBAgASgIEh0KFWF1dG9fcmV2aXNpb25fZW5hYmxlZBgbIAEoCBIXCg9hbGxvd2VkX29yaWdpbnMYDiADKAkSLgoKY3JlYXRlZF9hdBgMIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKdXBkYXRlZF9hdBgNIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiLwoLTWV0cmljUG9pbnQSEQoJdGltZXN0YW1wGAEgASgDEg0KBXZhbHVlGAIgASgFIqMMChZVcGRhdGFibGVQcm9qZWN0RmllbGRzEioKBG5hbWUYASABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSNgoQYXV0aF93ZWJob29rX3VybBgCIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJSChRhdXRoX3dlYmhvb2tfbWV0aG9kcxgDIAEoCzI0LnlvcmtpZS52MS5VcGRhdGFibGVQcm9qZWN0RmllbGRzLkF1dGhXZWJob29rTWV0aG9kcxI+ChhhdXRoX3dlYmhvb2tfbWF4X3JldHJpZXMYDCABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUSRAoeYXV0aF93ZWJob29rX21pbl93YWl0X2ludGVydmFsGA0gASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkQKHmF1dGhfd2ViaG9va19tYXhfd2FpdF9pbnRlcnZhbBgOIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJCChxhdXRoX3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GA8gASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjcKEWV2ZW50X3dlYmhvb2tfdXJsGAQgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlElIKFGV2ZW50X3dlYmhvb2tfZXZlbnRzGAUgASgLMjQueW9ya2llLnYxLlVwZGF0YWJsZVByb2plY3RGaWVsZHMuRXZlbnRXZWJob29rRXZlbnRzEj8KGWV2ZW50X3dlYmhvb2tfbWF4X3JldHJpZXMYECABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUSRQofZXZlbnRfd2ViaG9va19taW5fd2FpdF9pbnRlcnZhbBgRIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZRJFCh9ldmVudF93ZWJob29rX21heF93YWl0X2ludGVydmFsGBIgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkMKHWV2ZW50X3dlYmhvb2tfcmVxdWVzdF90aW1lb3V0GBMgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjcKEnNuYXBzaG90X3RocmVzaG9sZBgUIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEjYKEXNuYXBzaG90X2ludGVydmFsGBUgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUSQQobY2xpZW50X2RlYWN0aXZhdGVfdGhyZXNob2xkGAYgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEkEKHG1heF9zdWJzY3JpYmVyc19wZXJfZG9jdW1lbnQYByABKAsyGy5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZRJBChxtYXhfYXR0YWNobWVudHNfcGVyX2RvY3VtZW50GAggASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSOgoVbWF4X3NpemVfcGVyX2RvY3VtZW50GAogASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUSNAoQcmVtb3ZlX29uX2RldGFjaBgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSOQoVYXV0b19yZXZpc2lvbl9lbmFibGVkGBYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZRJJCg9hbGxvd2VkX29yaWdpbnMYCSABKAsyMC55b3JraWUudjEuVXBkYXRhYmxlUHJvamVjdEZpZWxkcy5BbGxvd2VkT3JpZ2lucxolChJBdXRoV2ViaG9va01ldGhvZHMSDwoHbWV0aG9kcxgBIAMoCRokChJFdmVudFdlYmhvb2tFdmVudHMSDgoGZXZlbnRzGAEgAygJGiEKDkFsbG93ZWRPcmlnaW5zEg8KB29yaWdpbnMYASADKAkipwMKD0RvY3VtZW50U3VtbWFyeRIKCgJpZBgBIAEoCRILCgNrZXkYAiABKAkSDAoEcm9vdBgDIAEoCRIYChBhdHRhY2hlZF9jbGllbnRzGAcgASgFEikKDWRvY3VtZW50X3NpemUYCCABKAsyEi55b3JraWUudjEuRG9jU2l6ZRISCgpzY2hlbWFfa2V5GAkgASgJEjwKCXByZXNlbmNlcxgKIAMoCzIpLnlvcmtpZS52MS5Eb2N1bWVudFN1bW1hcnkuUHJlc2VuY2VzRW50cnkSLgoKY3JlYXRlZF9hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLwoLYWNjZXNzZWRfYXQYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi4KCnVwZGF0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wGkUKDlByZXNlbmNlc0VudHJ5EgsKA2tleRgBIAEoCRIiCgV2YWx1ZRgCIAEoCzITLnlvcmtpZS52MS5QcmVzZW5jZToCOAEi2gEKDlByZXNlbmNlQ2hhbmdlEjIKBHR5cGUYASABKA4yJC55b3JraWUudjEuUHJlc2VuY2VDaGFuZ2UuQ2hhbmdlVHlwZRIlCghwcmVzZW5jZRgCIAEoCzITLnlvcmtpZS52MS5QcmVzZW5jZSJtCgpDaGFuZ2VUeXBlEhsKF0NIQU5HRV9UWVBFX1VOU1BFQ0lGSUVEEAASEwoPQ0hBTkdFX1RZUEVfUFVUEAESFgoSQ0hBTkdFX1RZUEVfREVMRVRFEAISFQoRQ0hBTkdFX1RZUEVfQ0xFQVIQAyJkCghQcmVzZW5jZRIrCgRkYXRhGAEgAygLMh0ueW9ya2llLnYxLlByZXNlbmNlLkRhdGFFbnRyeRorCglEYXRhRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASI0Cg5DaGFubmVsU3VtbWFyeRILCgNrZXkYASABKAkSFQoNc2Vzc2lvbl9jb3VudBgCIAEoBSI0CgpDaGVja3BvaW50EhIKCnNlcnZlcl9zZXEYASABKAMSEgoKY2xpZW50X3NlcRgCIAEoDSJhCgtUZXh0Tm9kZVBvcxIpCgpjcmVhdGVkX2F0GAEgASgLMhUueW9ya2llLnYxLlRpbWVUaWNrZXQSDgoGb2Zmc2V0GAIgASgFEhcKD3JlbGF0aXZlX29mZnNldBgDIAEoBSJCCgpUaW1lVGlja2V0Eg8KB2xhbXBvcnQYASABKAMSEQoJZGVsaW1pdGVyGAIgASgNEhAKCGFjdG9yX2lkGAMgASgMIi4KDERvY0V2ZW50Qm9keRINCgV0b3BpYxgBIAEoCRIPCgdwYXlsb2FkGAIgASgMImsKCERvY0V2ZW50EiUKBHR5cGUYASABKA4yFy55b3JraWUudjEuRG9jRXZlbnRUeXBlEhEKCXB1Ymxpc2hlchgCIAEoCRIlCgRib2R5GAMgASgLMhcueW9ya2llLnYxLkRvY0V2ZW50Qm9keSLWAQoMQ2hhbm5lbEV2ZW50EioKBHR5cGUYASABKA4yHC55b3JraWUudjEuQ2hhbm5lbEV2ZW50LlR5cGUSEQoJcHVibGlzaGVyGAIgASgJEhUKDXNlc3Npb25fY291bnQYAyABKAMSCwoDc2VxGAQgASgDEg0KBXRvcGljGAUgASgJEg8KB3BheWxvYWQYBiABKAwiQwoEVHlwZRIUChBUWVBFX1VOU1BFQ0lGSUVEEAASEQoNVFlQRV9QUkVTRU5DRRABEhIKDlRZUEVfQlJPQURDQVNUEAIiJgoIRGF0YVNpemUSDAoEZGF0YRgBIAEoBRIMCgRtZXRhGAIgASgFIk0KB0RvY1NpemUSIQoEbGl2ZRgBIAEoCzITLnlvcmtpZS52MS5EYXRhU2l6ZRIfCgJnYxgCIAEoCzITLnlvcmtpZS52MS5EYXRhU2l6ZSKRAQoGU2NoZW1hEgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDwoHdmVyc2lvbhgDIAEoBRIMCgRib2R5GAQgASgJEh4KBXJ1bGVzGAUgAygLMg8ueW9ya2llLnYxLlJ1bGUSLgoKY3JlYXRlZF9hdBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiUAoMVHJlZU5vZGVSdWxlEhEKCW5vZGVfdHlwZRgBIAEoCRIPCgdjb250ZW50GAIgASgJEg0KBW1hcmtzGAMgASgJEg0KBWdyb3VwGAQgASgJIk8KBFJ1bGUSDAoEcGF0aBgBIAEoCRIMCgR0eXBlGAIgASgJEisKCnRyZWVfbm9kZXMYAyADKAsyFy55b3JraWUudjEuVHJlZU5vZGVSdWxlIoMBCg9SZXZpc2lvblN1bW1hcnkSCgoCaWQYASABKAkSDQoFbGFiZWwYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSEAoIc25hcHNob3QYBCABKAkSLgoKY3JlYXRlZF9hdBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAq/AIKCVZhbHVlVHlwZRITCg9WQUxVRV9UWVBFX05VTEwQABIWChJWQUxVRV9UWVBFX0JPT0xFQU4QARIWChJWQUxVRV9UWVBFX0lOVEVHRVIQAhITCg9WQUxVRV9UWVBFX0xPTkcQAxIVChFWQUxVRV9UWVBFX0RPVUJMRRAEEhUKEVZBTFVFX1RZUEVfU1RSSU5HEAUSFAoQVkFMVUVfVFlQRV9CWVRFUxAGEhMKD1ZBTFVFX1RZUEVfREFURRAHEhoKFlZBTFVFX1RZUEVfSlNPTl9PQkpFQ1QQCBIZChVWQUxVRV9UWVBFX0pTT05fQVJSQVkQCRITCg9WQUxVRV9UWVBFX1RFWFQQChIaChZWQUxVRV9UWVBFX0lOVEVHRVJfQ05UEAsSFwoTVkFMVUVfVFlQRV9MT05HX0NOVBAMEhMKD1ZBTFVFX1RZUEVfVFJFRRANEiAKHFZBTFVFX1RZUEVfSU5URUdFUl9ERURVUF9DTlQQDiIECA8QDyqmAQoMRG9jRXZlbnRUeXBlEiMKH0RPQ19FVkVOVF9UWVBFX0RPQ1VNRU5UX0NIQU5HRUQQABIjCh9ET0NfRVZFTlRfVFlQRV9ET0NVTUVOVF9XQVRDSEVEEAESJQohRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfVU5XQVRDSEVEEAISJQohRE9DX0VWRU5UX1RZUEVfRE9DVU1FTlRfQlJPQURDQVNUEANCRQoRZGV2LnlvcmtpZS5hcGkudjFQAVouZ2l0aHViLmNvbS95b3JraWUtdGVhbS95b3JraWUvYXBpL3lvcmtpZS92MTt2MWIGcHJvdG8z", [file_google_protobuf_timestamp, file_google_protobuf_wrappers]);
5796
5796
  const SnapshotSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 0);
5797
5797
  const ChangePackSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 1);
5798
5798
  const ChangeSchema = /* @__PURE__ */ messageDesc(file_src_api_yorkie_v1_resources, 2);
@@ -7141,6 +7141,13 @@
7141
7141
  if (this.valueType === 5) {
7142
7142
  return `"${escapeString(this.value)}"`;
7143
7143
  }
7144
+ if (this.valueType === 6) {
7145
+ const bytes = this.value;
7146
+ return `"${btoa(String.fromCharCode(...bytes))}"`;
7147
+ }
7148
+ if (this.valueType === 7) {
7149
+ return `"${this.value.toISOString()}"`;
7150
+ }
7144
7151
  return `${this.value}`;
7145
7152
  }
7146
7153
  /**
@@ -7283,19 +7290,54 @@
7283
7290
  }
7284
7291
  }
7285
7292
  }
7293
+ class ElementEntry {
7294
+ elem;
7295
+ positionNode;
7296
+ posMovedAt;
7297
+ constructor(elem) {
7298
+ this.elem = elem;
7299
+ }
7300
+ }
7286
7301
  class RGATreeListNode extends SplayNode {
7302
+ _elementEntry;
7303
+ _createdAt;
7304
+ _removedAt;
7287
7305
  prev;
7288
7306
  next;
7289
- movedFrom;
7290
- constructor(value) {
7291
- super(value);
7292
- this.value = value;
7307
+ constructor(elem, createdAt) {
7308
+ super(elem);
7309
+ this._createdAt = createdAt;
7293
7310
  }
7294
7311
  /**
7295
- * `createAfter` creates a new node after the given node.
7312
+ * `createWithElement` creates a new node that owns an element.
7296
7313
  */
7297
- static createAfter(prev, value) {
7298
- const newNode = new RGATreeListNode(value);
7314
+ static createWithElement(elem) {
7315
+ const entry = new ElementEntry(elem);
7316
+ const node = new RGATreeListNode(elem, elem.getCreatedAt());
7317
+ entry.positionNode = node;
7318
+ node._elementEntry = entry;
7319
+ return node;
7320
+ }
7321
+ /**
7322
+ * `createBarePosition` creates a position node without an element
7323
+ * (used for move).
7324
+ */
7325
+ static createBarePosition(createdAt) {
7326
+ return new RGATreeListNode(void 0, createdAt);
7327
+ }
7328
+ /**
7329
+ * `createAfter` creates a new node with the given element after
7330
+ * the given prev node.
7331
+ */
7332
+ static createAfter(prev, elem) {
7333
+ const newNode = RGATreeListNode.createWithElement(elem);
7334
+ RGATreeListNode.insertNodeAfter(prev, newNode);
7335
+ return newNode;
7336
+ }
7337
+ /**
7338
+ * `insertNodeAfter` inserts a node after the given prev node.
7339
+ */
7340
+ static insertNodeAfter(prev, newNode) {
7299
7341
  const prevNext = prev.next;
7300
7342
  prev.next = newNode;
7301
7343
  newNode.prev = prev;
@@ -7303,26 +7345,41 @@
7303
7345
  if (prevNext) {
7304
7346
  prevNext.prev = newNode;
7305
7347
  }
7306
- return newNode;
7307
7348
  }
7308
7349
  /**
7309
- * `remove` removes value based on removing time.
7350
+ * `remove` removes the element based on removing time.
7310
7351
  */
7311
7352
  remove(removedAt) {
7312
- return this.value.remove(removedAt);
7353
+ if (!this._elementEntry) {
7354
+ return false;
7355
+ }
7356
+ return this._elementEntry.elem.remove(removedAt);
7313
7357
  }
7314
7358
  /**
7315
- * `getCreatedAt` returns creation time of this value
7359
+ * `getCreatedAt` returns the creation time. For live nodes with
7360
+ * elements, returns the element's createdAt for backward
7361
+ * compatibility.
7316
7362
  */
7317
7363
  getCreatedAt() {
7318
- return this.value.getCreatedAt();
7364
+ if (this._elementEntry) {
7365
+ return this._elementEntry.elem.getCreatedAt();
7366
+ }
7367
+ return this._createdAt;
7319
7368
  }
7320
7369
  /**
7321
- * `getPositionedAt` returns the time of this element when it was positioned
7322
- * in the array.
7370
+ * `getPositionedAt` returns the time this element was positioned.
7371
+ * For live nodes, the position register (posMovedAt) is the source
7372
+ * of truth. For dead nodes (no element), the position node's own
7373
+ * createdAt is used.
7323
7374
  */
7324
7375
  getPositionedAt() {
7325
- return this.value.getPositionedAt();
7376
+ if (this._elementEntry) {
7377
+ if (this._elementEntry.posMovedAt) {
7378
+ return this._elementEntry.posMovedAt;
7379
+ }
7380
+ return this._elementEntry.elem.getCreatedAt();
7381
+ }
7382
+ return this._createdAt;
7326
7383
  }
7327
7384
  /**
7328
7385
  * `release` releases prev and next node.
@@ -7339,9 +7396,13 @@
7339
7396
  }
7340
7397
  /**
7341
7398
  * `getLength` returns the length of this node.
7399
+ * Dead nodes (no element) return 0, removed elements return 0.
7342
7400
  */
7343
7401
  getLength() {
7344
- return this.value.isRemoved() ? 0 : 1;
7402
+ if (!this._elementEntry || this.isRemoved()) {
7403
+ return 0;
7404
+ }
7405
+ return 1;
7345
7406
  }
7346
7407
  /**
7347
7408
  * `getPrev` returns a previous node.
@@ -7356,28 +7417,87 @@
7356
7417
  return this.next;
7357
7418
  }
7358
7419
  /**
7359
- * `getMovedFrom` returns the previous element before the element moved.
7420
+ * `getValue` returns the element value.
7360
7421
  */
7361
- getMovedFrom() {
7362
- return this.movedFrom;
7422
+ getValue() {
7423
+ if (!this._elementEntry) {
7424
+ return this.value;
7425
+ }
7426
+ return this._elementEntry.elem;
7363
7427
  }
7364
7428
  /**
7365
- * `setMovedFrom` sets the previous element before the element moved.
7429
+ * `getElement` returns the element or undefined if dead position.
7366
7430
  */
7367
- setMovedFrom(movedFrom) {
7368
- this.movedFrom = movedFrom;
7431
+ getElement() {
7432
+ return this._elementEntry?.elem;
7369
7433
  }
7370
7434
  /**
7371
- * `getValue` returns a element value.
7435
+ * `isRemoved` checks if the value was removed.
7372
7436
  */
7373
- getValue() {
7374
- return this.value;
7437
+ isRemoved() {
7438
+ if (!this._elementEntry) {
7439
+ return true;
7440
+ }
7441
+ return this._elementEntry.elem.isRemoved();
7375
7442
  }
7376
7443
  /**
7377
- * `isRemoved` checks if the value was removed.
7444
+ * `getElementEntry` returns the element entry.
7378
7445
  */
7379
- isRemoved() {
7380
- return this.value.isRemoved();
7446
+ getElementEntry() {
7447
+ return this._elementEntry;
7448
+ }
7449
+ /**
7450
+ * `setElementEntry` sets the element entry.
7451
+ */
7452
+ setElementEntry(entry) {
7453
+ this._elementEntry = entry;
7454
+ }
7455
+ /**
7456
+ * `getPositionCreatedAt` returns the position node's own createdAt.
7457
+ */
7458
+ getPositionCreatedAt() {
7459
+ return this._createdAt;
7460
+ }
7461
+ /**
7462
+ * `getPositionMovedAt` returns the LWW timestamp of the element's
7463
+ * move into this position. Undefined for insert-created positions.
7464
+ */
7465
+ getPositionMovedAt() {
7466
+ if (!this._elementEntry) {
7467
+ return void 0;
7468
+ }
7469
+ return this._elementEntry.posMovedAt;
7470
+ }
7471
+ /**
7472
+ * `getRemovedAt` returns the time this dead position node was
7473
+ * removed (for GC).
7474
+ */
7475
+ getRemovedAt() {
7476
+ return this._removedAt;
7477
+ }
7478
+ /**
7479
+ * `setRemovedAt` sets the removal time of this position node.
7480
+ */
7481
+ setRemovedAt(removedAt) {
7482
+ this._removedAt = removedAt;
7483
+ }
7484
+ /**
7485
+ * `toIDString` returns a unique identifier for this position node
7486
+ * (for GC).
7487
+ */
7488
+ toIDString() {
7489
+ return this._createdAt.toIDString();
7490
+ }
7491
+ /**
7492
+ * `getDataSize` returns the data size of this position node
7493
+ * (for GC).
7494
+ */
7495
+ getDataSize() {
7496
+ let meta = TimeTicketSize;
7497
+ if (this._removedAt) {
7498
+ meta += TimeTicketSize;
7499
+ }
7500
+ return { data: 0, meta };
7381
7501
  }
7382
7502
  }
7383
7503
  class RGATreeList {
@@ -7385,13 +7505,15 @@
7385
7505
  last;
7386
7506
  nodeMapByIndex;
7387
7507
  nodeMapByCreatedAt;
7508
+ elementMapByCreatedAt;
7388
7509
  constructor() {
7389
7510
  const dummyValue = Primitive.of(0, InitialTimeTicket);
7390
7511
  dummyValue.setRemovedAt(InitialTimeTicket);
7391
- this.dummyHead = new RGATreeListNode(dummyValue);
7512
+ this.dummyHead = RGATreeListNode.createWithElement(dummyValue);
7392
7513
  this.last = this.dummyHead;
7393
7514
  this.nodeMapByIndex = new SplayTree();
7394
7515
  this.nodeMapByCreatedAt = /* @__PURE__ */ new Map();
7516
+ this.elementMapByCreatedAt = /* @__PURE__ */ new Map();
7395
7517
  this.nodeMapByIndex.insert(this.dummyHead);
7396
7518
  this.nodeMapByCreatedAt.set(
7397
7519
  this.dummyHead.getCreatedAt().toIDString(),
@@ -7411,22 +7533,10 @@
7411
7533
  return this.nodeMapByIndex.length;
7412
7534
  }
7413
7535
  /**
7414
- * `findNextBeforeExecutedAt` returns the node by the given createdAt and
7415
- * executedAt. It passes through nodes created after executedAt from the
7416
- * given node and returns the next node.
7417
- * @returns the next node of the given createdAt and executedAt
7536
+ * `findNextBeforeExecutedAt` walks forward from the given node,
7537
+ * skipping nodes positioned after executedAt (RGA insertion rule).
7418
7538
  */
7419
- findNextBeforeExecutedAt(createdAt, executedAt) {
7420
- let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7421
- if (!node) {
7422
- throw new YorkieError(
7423
- Code.ErrInvalidArgument,
7424
- `cant find the given node: ${createdAt.toIDString()}`
7425
- );
7426
- }
7427
- while (node.getValue().getMovedAt() && node.getValue().getMovedAt().after(executedAt) && node.getMovedFrom()) {
7428
- node = node.getMovedFrom();
7429
- }
7539
+ findNextBeforeExecutedAt(node, executedAt) {
7430
7540
  while (node.getNext() && node.getNext().getPositionedAt().after(executedAt)) {
7431
7541
  node = node.getNext();
7432
7542
  }
@@ -7438,65 +7548,103 @@
7438
7548
  }
7439
7549
  node.release();
7440
7550
  this.nodeMapByIndex.delete(node);
7441
- this.nodeMapByCreatedAt.delete(node.getValue().getCreatedAt().toIDString());
7551
+ this.nodeMapByCreatedAt.delete(node.getPositionCreatedAt().toIDString());
7442
7552
  }
7443
7553
  /**
7444
- * `insertAfter` adds a new node with the value after the given node.
7554
+ * `insertAfter` adds a new node with the value after the given
7555
+ * position. prevCreatedAt is a position node identity. Looks up
7556
+ * nodeMapByCreatedAt first, then elementMapByCreatedAt for backward
7557
+ * compatibility.
7445
7558
  */
7446
7559
  insertAfter(prevCreatedAt, value, executedAt = value.getCreatedAt()) {
7447
- const prevNode = this.findNextBeforeExecutedAt(prevCreatedAt, executedAt);
7560
+ let startNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
7561
+ if (!startNode) {
7562
+ const entry = this.elementMapByCreatedAt.get(prevCreatedAt.toIDString());
7563
+ if (entry) {
7564
+ startNode = entry.positionNode;
7565
+ }
7566
+ }
7567
+ if (!startNode) {
7568
+ throw new YorkieError(
7569
+ Code.ErrInvalidArgument,
7570
+ `cant find the given node: ${prevCreatedAt.toIDString()}`
7571
+ );
7572
+ }
7573
+ const prevNode = this.findNextBeforeExecutedAt(startNode, executedAt);
7448
7574
  const newNode = RGATreeListNode.createAfter(prevNode, value);
7449
7575
  if (prevNode === this.last) {
7450
7576
  this.last = newNode;
7451
7577
  }
7452
7578
  this.nodeMapByIndex.insertAfter(prevNode, newNode);
7453
- this.nodeMapByCreatedAt.set(newNode.getCreatedAt().toIDString(), newNode);
7579
+ this.nodeMapByCreatedAt.set(value.getCreatedAt().toIDString(), newNode);
7580
+ this.elementMapByCreatedAt.set(
7581
+ value.getCreatedAt().toIDString(),
7582
+ newNode.getElementEntry()
7583
+ );
7454
7584
  return newNode;
7455
7585
  }
7456
7586
  /**
7457
- * `moveAfter` moves the given `createdAt` element
7458
- * after the `prevCreatedAt` element.
7587
+ * `insertPositionAfter` creates a bare position node after
7588
+ * resolving position via forward skip (RGA insertion rule).
7589
+ * Used by moveAfter. prevCreatedAt is a POSITION node identity.
7590
+ */
7591
+ insertPositionAfter(prevCreatedAt, executedAt) {
7592
+ const startNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
7593
+ if (!startNode) {
7594
+ throw new YorkieError(
7595
+ Code.ErrInvalidArgument,
7596
+ `cant find the given node: ${prevCreatedAt.toIDString()}`
7597
+ );
7598
+ }
7599
+ const prevNode = this.findNextBeforeExecutedAt(startNode, executedAt);
7600
+ const newNode = RGATreeListNode.createBarePosition(executedAt);
7601
+ RGATreeListNode.insertNodeAfter(prevNode, newNode);
7602
+ if (prevNode === this.last) {
7603
+ this.last = newNode;
7604
+ }
7605
+ this.nodeMapByIndex.insertAfter(prevNode, newNode);
7606
+ this.nodeMapByCreatedAt.set(executedAt.toIDString(), newNode);
7607
+ return newNode;
7608
+ }
7609
+ /**
7610
+ * `moveAfter` moves the given `createdAt` element after the
7611
+ * `prevCreatedAt` element using LWW position register semantics.
7612
+ * Returns the dead position node (if any) for GC registration.
7459
7613
  */
7460
7614
  moveAfter(prevCreatedAt, createdAt, executedAt) {
7461
- let prevNode = this.nodeMapByCreatedAt.get(prevCreatedAt.toIDString());
7462
- if (!prevNode) {
7615
+ if (!this.nodeMapByCreatedAt.has(prevCreatedAt.toIDString())) {
7463
7616
  throw new YorkieError(
7464
7617
  Code.ErrInvalidArgument,
7465
7618
  `cant find the given node: ${prevCreatedAt.toIDString()}`
7466
7619
  );
7467
7620
  }
7468
- let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7469
- if (!node) {
7621
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7622
+ if (!entry) {
7470
7623
  throw new YorkieError(
7471
7624
  Code.ErrInvalidArgument,
7472
7625
  `cant find the given node: ${createdAt.toIDString()}`
7473
7626
  );
7474
7627
  }
7475
- if (prevNode !== node && executedAt.after(node.getPositionedAt())) {
7476
- const movedFrom = node.getPrev();
7477
- let nextNode = node.getNext();
7478
- this.release(node);
7479
- node = this.insertAfter(
7480
- prevNode.getCreatedAt(),
7481
- node.getValue(),
7482
- executedAt
7483
- );
7484
- node.getValue().setMovedAt(executedAt);
7485
- node.setMovedFrom(movedFrom);
7486
- while (nextNode && nextNode.getPositionedAt().after(executedAt)) {
7487
- prevNode = node;
7488
- node = nextNode;
7489
- nextNode = node.getNext();
7490
- this.release(node);
7491
- node = this.insertAfter(
7492
- prevNode.getCreatedAt(),
7493
- node.getValue(),
7494
- executedAt
7495
- );
7496
- node.getValue().setMovedAt(executedAt);
7497
- node.setMovedFrom(movedFrom);
7628
+ if (entry.posMovedAt && !executedAt.after(entry.posMovedAt)) {
7629
+ if (this.nodeMapByCreatedAt.has(executedAt.toIDString())) {
7630
+ return void 0;
7498
7631
  }
7632
+ const deadPosNode = this.insertPositionAfter(prevCreatedAt, executedAt);
7633
+ deadPosNode.setRemovedAt(executedAt);
7634
+ this.nodeMapByIndex.splayNode(deadPosNode);
7635
+ return deadPosNode;
7499
7636
  }
7637
+ const newPosNode = this.insertPositionAfter(prevCreatedAt, executedAt);
7638
+ const oldPosNode = entry.positionNode;
7639
+ oldPosNode.setElementEntry(void 0);
7640
+ oldPosNode.setRemovedAt(executedAt);
7641
+ this.nodeMapByIndex.splayNode(oldPosNode);
7642
+ newPosNode.setElementEntry(entry);
7643
+ entry.positionNode = newPosNode;
7644
+ entry.posMovedAt = executedAt;
7645
+ entry.elem.setMovedAt(executedAt);
7646
+ this.nodeMapByIndex.splayNode(newPosNode);
7647
+ return oldPosNode;
7500
7648
  }
7501
7649
  /**
7502
7650
  * `insert` adds the given element after the last node.
@@ -7505,34 +7653,53 @@
7505
7653
  this.insertAfter(this.last.getCreatedAt(), value);
7506
7654
  }
7507
7655
  /**
7508
- * `getByID` returns the element of the given creation time.
7656
+ * `getByID` returns the node of the given creation time.
7657
+ * Checks elementMapByCreatedAt first (for moved elements whose
7658
+ * position node createdAt differs), then nodeMapByCreatedAt.
7509
7659
  */
7510
7660
  getByID(createdAt) {
7661
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7662
+ if (entry) {
7663
+ return entry.positionNode;
7664
+ }
7511
7665
  return this.nodeMapByCreatedAt.get(createdAt.toIDString());
7512
7666
  }
7513
7667
  /**
7514
7668
  * `subPathOf` returns the sub path of the given element.
7515
7669
  */
7516
7670
  subPathOf(createdAt) {
7517
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7518
- if (!node) {
7519
- return;
7671
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7672
+ if (!entry) {
7673
+ const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7674
+ if (!node) {
7675
+ return;
7676
+ }
7677
+ return String(this.nodeMapByIndex.indexOf(node));
7520
7678
  }
7521
- return String(this.nodeMapByIndex.indexOf(node));
7679
+ return String(this.nodeMapByIndex.indexOf(entry.positionNode));
7522
7680
  }
7523
7681
  /**
7524
- * `purge` physically purges element.
7682
+ * `purge` physically purges the given child. Handles both dead
7683
+ * position nodes (GCChild from GCParent path) and CRDTElements
7684
+ * (from CRDTContainer path).
7525
7685
  */
7526
- purge(element) {
7527
- const node = this.nodeMapByCreatedAt.get(
7686
+ purge(child) {
7687
+ if (child instanceof RGATreeListNode) {
7688
+ this.release(child);
7689
+ return;
7690
+ }
7691
+ const element = child;
7692
+ const entry = this.elementMapByCreatedAt.get(
7528
7693
  element.getCreatedAt().toIDString()
7529
7694
  );
7530
- if (!node) {
7695
+ if (!entry) {
7531
7696
  throw new YorkieError(
7532
7697
  Code.ErrInvalidArgument,
7533
7698
  `fail to find the given createdAt: ${element.getCreatedAt().toIDString()}`
7534
7699
  );
7535
7700
  }
7701
+ const node = entry.positionNode;
7702
+ this.elementMapByCreatedAt.delete(element.getCreatedAt().toIDString());
7536
7703
  this.release(node);
7537
7704
  }
7538
7705
  /**
@@ -7543,42 +7710,69 @@
7543
7710
  return;
7544
7711
  }
7545
7712
  const node = this.nodeMapByIndex.findForArray(idx);
7546
- const rgaNode = node;
7547
- return rgaNode;
7713
+ return node;
7548
7714
  }
7549
7715
  /**
7550
- * `getPrevCreatedAt` returns a creation time of the previous node.
7716
+ * `findPrevCreatedAt` returns the position node's createdAt of the
7717
+ * previous element. This returns a position identity suitable for
7718
+ * use as prevCreatedAt in moveAfter.
7551
7719
  */
7552
- getPrevCreatedAt(createdAt) {
7553
- let node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7720
+ findPrevCreatedAt(createdAt) {
7721
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7722
+ if (!entry) {
7723
+ throw new YorkieError(
7724
+ Code.ErrInvalidArgument,
7725
+ `cant find the given node: ${createdAt.toIDString()}`
7726
+ );
7727
+ }
7728
+ let node = entry.positionNode;
7554
7729
  do {
7555
7730
  node = node.getPrev();
7556
- } while (this.dummyHead !== node && node.isRemoved());
7557
- return node.getValue().getCreatedAt();
7731
+ if (!node.getElementEntry()) {
7732
+ continue;
7733
+ }
7734
+ if (this.dummyHead === node || !node.isRemoved()) {
7735
+ break;
7736
+ }
7737
+ } while (node);
7738
+ return node.getPositionCreatedAt();
7739
+ }
7740
+ /**
7741
+ * `getPrevCreatedAt` returns the position node's createdAt of the
7742
+ * previous element. Delegates to findPrevCreatedAt.
7743
+ */
7744
+ getPrevCreatedAt(createdAt) {
7745
+ return this.findPrevCreatedAt(createdAt);
7558
7746
  }
7559
7747
  /**
7560
7748
  * `delete` deletes the node of the given creation time.
7561
7749
  */
7562
7750
  delete(createdAt, editedAt) {
7563
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7751
+ const entry = this.elementMapByCreatedAt.get(createdAt.toIDString());
7752
+ if (!entry) {
7753
+ throw new YorkieError(
7754
+ Code.ErrInvalidArgument,
7755
+ `cant find the given node: ${createdAt.toIDString()}`
7756
+ );
7757
+ }
7758
+ const node = entry.positionNode;
7564
7759
  const alreadyRemoved = node.isRemoved();
7565
- if (node.remove(editedAt) && !alreadyRemoved) {
7760
+ if (entry.elem.remove(editedAt) && !alreadyRemoved) {
7566
7761
  this.nodeMapByIndex.splayNode(node);
7567
7762
  }
7568
- return node.getValue();
7763
+ return entry.elem;
7569
7764
  }
7570
7765
  /**
7571
7766
  * `set` sets the given element at the given creation time.
7572
7767
  */
7573
7768
  set(createdAt, element, executedAt) {
7574
- const node = this.nodeMapByCreatedAt.get(createdAt.toIDString());
7575
- if (!node) {
7769
+ if (!this.elementMapByCreatedAt.has(createdAt.toIDString())) {
7576
7770
  throw new YorkieError(
7577
7771
  Code.ErrInvalidArgument,
7578
7772
  `cant find the given node: ${createdAt.toIDString()}`
7579
7773
  );
7580
7774
  }
7581
- this.insertAfter(node.getCreatedAt(), element, executedAt);
7775
+ this.insertAfter(createdAt, element, executedAt);
7582
7776
  return this.delete(createdAt, executedAt);
7583
7777
  }
7584
7778
  /**
@@ -7607,18 +7801,80 @@
7607
7801
  return this.last.getValue();
7608
7802
  }
7609
7803
  /**
7610
- * `getLastCreatedAt` returns the creation time of last element.
7804
+ * `getLastCreatedAt` returns the position node's createdAt of the
7805
+ * last node in the linked list. This is a position identity
7806
+ * suitable for use as prevCreatedAt.
7611
7807
  */
7612
7808
  getLastCreatedAt() {
7613
- return this.last.getCreatedAt();
7809
+ return this.last.getPositionCreatedAt();
7614
7810
  }
7615
7811
  /**
7616
- * `toTestString` returns a String containing the meta data of the node id
7617
- * for debugging purpose.
7812
+ * `posCreatedAt` returns the createdAt of the position node
7813
+ * currently holding the element. Used to convert element identity
7814
+ * to position identity.
7815
+ */
7816
+ posCreatedAt(elemCreatedAt) {
7817
+ const entry = this.elementMapByCreatedAt.get(elemCreatedAt.toIDString());
7818
+ if (!entry) {
7819
+ throw new YorkieError(
7820
+ Code.ErrInvalidArgument,
7821
+ `cant find the given node: ${elemCreatedAt.toIDString()}`
7822
+ );
7823
+ }
7824
+ return entry.positionNode.getPositionCreatedAt();
7825
+ }
7826
+ /**
7827
+ * `addDeadPosition` appends a dead position node during snapshot
7828
+ * restoration.
7829
+ */
7830
+ addDeadPosition(posCreatedAt, removedAt) {
7831
+ const node = RGATreeListNode.createBarePosition(posCreatedAt);
7832
+ node.setRemovedAt(removedAt);
7833
+ const prevNode = this.last;
7834
+ RGATreeListNode.insertNodeAfter(prevNode, node);
7835
+ this.last = node;
7836
+ this.nodeMapByIndex.insertAfter(prevNode, node);
7837
+ this.nodeMapByCreatedAt.set(posCreatedAt.toIDString(), node);
7838
+ }
7839
+ /**
7840
+ * `addMovedElement` appends an element with explicit position
7841
+ * identity during snapshot restoration.
7842
+ */
7843
+ addMovedElement(elem, posCreatedAt, posMovedAt) {
7844
+ const entry = new ElementEntry(elem);
7845
+ entry.posMovedAt = posMovedAt;
7846
+ const node = RGATreeListNode.createBarePosition(posCreatedAt);
7847
+ node.setElementEntry(entry);
7848
+ entry.positionNode = node;
7849
+ const prevNode = this.last;
7850
+ RGATreeListNode.insertNodeAfter(prevNode, node);
7851
+ this.last = node;
7852
+ this.nodeMapByIndex.insertAfter(prevNode, node);
7853
+ this.nodeMapByCreatedAt.set(posCreatedAt.toIDString(), node);
7854
+ this.elementMapByCreatedAt.set(elem.getCreatedAt().toIDString(), entry);
7855
+ }
7856
+ /**
7857
+ * `allNodes` returns all nodes including dead position nodes.
7858
+ */
7859
+ allNodes() {
7860
+ const nodes = [];
7861
+ let current = this.dummyHead.getNext();
7862
+ while (current) {
7863
+ nodes.push(current);
7864
+ current = current.getNext();
7865
+ }
7866
+ return nodes;
7867
+ }
7868
+ /**
7869
+ * `toTestString` returns a String containing the meta data of the
7870
+ * node id for debugging purpose.
7618
7871
  */
7619
7872
  toTestString() {
7620
7873
  const json = [];
7621
7874
  for (const node of this) {
7875
+ if (!node.getElementEntry()) {
7876
+ continue;
7877
+ }
7622
7878
  const elem = `${node.getCreatedAt().toIDString()}:${node.getValue().toJSON()}`;
7623
7879
  if (node.isRemoved()) {
7624
7880
  json.push(`{${elem}}`);
@@ -7675,10 +7931,11 @@
7675
7931
  this.elements.insertAfter(prevCreatedAt, value, executedAt);
7676
7932
  }
7677
7933
  /**
7678
- * `moveAfter` moves the given `createdAt` element after the `prevCreatedAt`.
7934
+ * `moveAfter` moves the given `createdAt` element after the
7935
+ * `prevCreatedAt`. Returns the dead position node for GC.
7679
7936
  */
7680
7937
  moveAfter(prevCreatedAt, createdAt, executedAt) {
7681
- this.elements.moveAfter(prevCreatedAt, createdAt, executedAt);
7938
+ return this.elements.moveAfter(prevCreatedAt, createdAt, executedAt);
7682
7939
  }
7683
7940
  /**
7684
7941
  * `get` returns the element of the given index.
@@ -7707,11 +7964,20 @@
7707
7964
  return this.elements.getLast();
7708
7965
  }
7709
7966
  /**
7710
- * `getPrevCreatedAt` returns the creation time of the previous node.
7967
+ * `getPrevCreatedAt` returns the creation time of the previous
7968
+ * node.
7711
7969
  */
7712
7970
  getPrevCreatedAt(createdAt) {
7713
7971
  return this.elements.getPrevCreatedAt(createdAt);
7714
7972
  }
7973
+ /**
7974
+ * `posCreatedAt` returns the createdAt of the position node
7975
+ * currently holding the element. Used to convert element identity
7976
+ * to position identity for moves.
7977
+ */
7978
+ posCreatedAt(elemCreatedAt) {
7979
+ return this.elements.posCreatedAt(elemCreatedAt);
7980
+ }
7715
7981
  /**
7716
7982
  * `delete` deletes the element of the given creation time.
7717
7983
  */
@@ -7725,7 +7991,8 @@
7725
7991
  return this.elements.deleteByIndex(index, editedAt);
7726
7992
  }
7727
7993
  /**
7728
- * `set` sets the given element at the given position of the creation time.
7994
+ * `set` sets the given element at the given position of the
7995
+ * creation time.
7729
7996
  */
7730
7997
  set(createdAt, value, executedAt) {
7731
7998
  return this.elements.set(createdAt, value, executedAt);
@@ -7743,18 +8010,19 @@
7743
8010
  return this.elements.length;
7744
8011
  }
7745
8012
  /**
7746
- * `[Symbol.iterator]` returns an iterator for the elements in this array.
8013
+ * `[Symbol.iterator]` returns an iterator for the elements in
8014
+ * this array.
7747
8015
  */
7748
8016
  *[Symbol.iterator]() {
7749
8017
  for (const node of this.elements) {
7750
- if (!node.isRemoved()) {
8018
+ if (node.getElementEntry() && !node.isRemoved()) {
7751
8019
  yield node.getValue();
7752
8020
  }
7753
8021
  }
7754
8022
  }
7755
8023
  /**
7756
- * `toTestString` returns a String containing the meta data of this value
7757
- * for debugging purpose.
8024
+ * `toTestString` returns a String containing the meta data of
8025
+ * this value for debugging purpose.
7758
8026
  */
7759
8027
  toTestString() {
7760
8028
  return this.elements.toTestString();
@@ -7764,6 +8032,9 @@
7764
8032
  */
7765
8033
  getDescendants(callback) {
7766
8034
  for (const node of this.elements) {
8035
+ if (!node.getElementEntry()) {
8036
+ continue;
8037
+ }
7767
8038
  const element = node.getValue();
7768
8039
  if (callback(element, this)) {
7769
8040
  return;
@@ -7825,21 +8096,52 @@
7825
8096
  return this.toJSON();
7826
8097
  }
7827
8098
  /**
7828
- * `getElements` returns an array of elements contained in this RGATreeList.
8099
+ * `getElements` returns the underlying RGATreeList.
7829
8100
  */
7830
8101
  getElements() {
7831
8102
  return this.elements;
7832
8103
  }
8104
+ /**
8105
+ * `getRGATreeList` returns the underlying RGATreeList (GCParent
8106
+ * for dead positions).
8107
+ */
8108
+ getRGATreeList() {
8109
+ return this.elements;
8110
+ }
8111
+ /**
8112
+ * `getAllRGANodes` returns all RGA nodes including dead position
8113
+ * nodes.
8114
+ */
8115
+ getAllRGANodes() {
8116
+ return this.elements.allNodes();
8117
+ }
7833
8118
  /**
7834
8119
  * `deepcopy` copies itself deeply.
7835
8120
  */
7836
8121
  deepcopy() {
7837
8122
  const clone = CRDTArray.create(this.getCreatedAt());
7838
8123
  for (const node of this.elements) {
7839
- clone.elements.insertAfter(
7840
- clone.getLastCreatedAt(),
7841
- node.getValue().deepcopy()
7842
- );
8124
+ if (!node.getElementEntry()) {
8125
+ const removedAt = node.getRemovedAt();
8126
+ if (removedAt) {
8127
+ clone.elements.addDeadPosition(
8128
+ node.getPositionCreatedAt(),
8129
+ removedAt
8130
+ );
8131
+ }
8132
+ continue;
8133
+ }
8134
+ const value = node.getValue().deepcopy();
8135
+ const posMovedAt = node.getPositionMovedAt();
8136
+ if (posMovedAt) {
8137
+ clone.elements.addMovedElement(
8138
+ value,
8139
+ node.getPositionCreatedAt(),
8140
+ posMovedAt
8141
+ );
8142
+ } else {
8143
+ clone.elements.insertAfter(clone.getLastCreatedAt(), value);
8144
+ }
7843
8145
  }
7844
8146
  clone.setRemovedAt(this.getRemovedAt());
7845
8147
  clone.setMovedAt(this.getMovedAt());
@@ -8096,6 +8398,9 @@
8096
8398
  if (removed) {
8097
8399
  root.registerRemovedElement(removed);
8098
8400
  }
8401
+ if (value.getRemovedAt()) {
8402
+ root.registerRemovedElement(value);
8403
+ }
8099
8404
  return {
8100
8405
  opInfos: [
8101
8406
  {
@@ -8188,7 +8493,17 @@
8188
8493
  const array = parentObject;
8189
8494
  const reverseOp = this.toReverseOperation(array);
8190
8495
  const previousIndex = Number(array.subPathOf(this.createdAt));
8191
- array.moveAfter(this.prevCreatedAt, this.createdAt, this.getExecutedAt());
8496
+ const deadNode = array.moveAfter(
8497
+ this.prevCreatedAt,
8498
+ this.createdAt,
8499
+ this.getExecutedAt()
8500
+ );
8501
+ if (deadNode) {
8502
+ root.registerGCPair({
8503
+ parent: array.getRGATreeList(),
8504
+ child: deadNode
8505
+ });
8506
+ }
8192
8507
  const index = Number(array.subPathOf(this.createdAt));
8193
8508
  return {
8194
8509
  opInfos: [
@@ -8211,7 +8526,8 @@
8211
8526
  );
8212
8527
  }
8213
8528
  /**
8214
- * `getEffectedCreatedAt` returns the creation time of the effected element.
8529
+ * `getEffectedCreatedAt` returns the creation time of the
8530
+ * effected element.
8215
8531
  */
8216
8532
  getEffectedCreatedAt() {
8217
8533
  return this.createdAt;
@@ -8223,7 +8539,8 @@
8223
8539
  return `${this.getParentCreatedAt().toTestString()}.MOVE`;
8224
8540
  }
8225
8541
  /**
8226
- * `getPrevCreatedAt` returns the creation time of previous element.
8542
+ * `getPrevCreatedAt` returns the creation time of previous
8543
+ * element.
8227
8544
  */
8228
8545
  getPrevCreatedAt() {
8229
8546
  return this.prevCreatedAt;
@@ -8235,7 +8552,8 @@
8235
8552
  return this.createdAt;
8236
8553
  }
8237
8554
  /**
8238
- * `setPrevCreatedAt` sets the creation time of the previous element.
8555
+ * `setPrevCreatedAt` sets the creation time of the previous
8556
+ * element.
8239
8557
  */
8240
8558
  setPrevCreatedAt(createdAt) {
8241
8559
  this.prevCreatedAt = createdAt;
@@ -11579,7 +11897,7 @@
11579
11897
  CRDTTreeNodeID.of(issueTimeTicket(), 0),
11580
11898
  this.type,
11581
11899
  void 0,
11582
- void 0,
11900
+ this.attrs?.deepcopy(),
11583
11901
  this.removedAt
11584
11902
  );
11585
11903
  }
@@ -11999,6 +12317,53 @@
11999
12317
  addDataSizes(diff, curr.getDataSize());
12000
12318
  }
12001
12319
  }
12320
+ if (tokenType === TokenType.Start && versionVector !== void 0) {
12321
+ let current = node;
12322
+ while (current.insNextID) {
12323
+ const next = this.findFloorNode(current.insNextID);
12324
+ if (!next || next.isText) {
12325
+ break;
12326
+ }
12327
+ if (ticketKnown(versionVector, next.id.getCreatedAt())) {
12328
+ break;
12329
+ }
12330
+ const siblingPairs = next.setAttrs(attributes, editedAt);
12331
+ const siblingAffectedAttrs = siblingPairs.reduce(
12332
+ (acc, [, curr]) => {
12333
+ if (curr) {
12334
+ acc[curr.getKey()] = attrs[curr.getKey()];
12335
+ }
12336
+ return acc;
12337
+ },
12338
+ {}
12339
+ );
12340
+ if (Object.keys(siblingAffectedAttrs).length > 0) {
12341
+ const parentOfNext = next.parent;
12342
+ const previousNext = next.prevSibling || parentOfNext;
12343
+ changes.push({
12344
+ type: "style",
12345
+ from: this.toIndex(parentOfNext, previousNext),
12346
+ to: this.toIndex(next, next),
12347
+ fromPath: this.toPath(parentOfNext, previousNext),
12348
+ toPath: this.toPath(next, next),
12349
+ actor: editedAt.getActorID(),
12350
+ value: siblingAffectedAttrs
12351
+ });
12352
+ }
12353
+ for (const [prev] of siblingPairs) {
12354
+ if (prev) {
12355
+ pairs.push({ parent: next, child: prev });
12356
+ }
12357
+ }
12358
+ for (const [key] of Object.entries(attrs)) {
12359
+ const curr = next.attrs?.getNodeMapByKey().get(key);
12360
+ if (curr !== void 0) {
12361
+ addDataSizes(diff, curr.getDataSize());
12362
+ }
12363
+ }
12364
+ current = next;
12365
+ }
12366
+ }
12002
12367
  }
12003
12368
  }
12004
12369
  );
@@ -12065,6 +12430,43 @@
12065
12430
  toPath: this.toPath(node, node),
12066
12431
  value: attributesToRemove
12067
12432
  });
12433
+ if (tokenType === TokenType.Start && versionVector !== void 0) {
12434
+ let current = node;
12435
+ while (current.insNextID) {
12436
+ const next = this.findFloorNode(current.insNextID);
12437
+ if (!next || next.isText) {
12438
+ break;
12439
+ }
12440
+ if (ticketKnown(versionVector, next.id.getCreatedAt())) {
12441
+ break;
12442
+ }
12443
+ if (!next.attrs) {
12444
+ next.attrs = new RHT();
12445
+ }
12446
+ let removedAny = false;
12447
+ for (const value of attributesToRemove) {
12448
+ const nodesTobeRemoved = next.attrs.remove(value, editedAt);
12449
+ removedAny = removedAny || nodesTobeRemoved.length > 0;
12450
+ for (const rhtNode of nodesTobeRemoved) {
12451
+ pairs.push({ parent: next, child: rhtNode });
12452
+ }
12453
+ }
12454
+ if (removedAny) {
12455
+ const parentOfNext = next.parent;
12456
+ const previousNext = next.prevSibling || parentOfNext;
12457
+ changes.push({
12458
+ actor: editedAt.getActorID(),
12459
+ type: "removeStyle",
12460
+ from: this.toIndex(parentOfNext, previousNext),
12461
+ to: this.toIndex(next, next),
12462
+ fromPath: this.toPath(parentOfNext, previousNext),
12463
+ toPath: this.toPath(next, next),
12464
+ value: attributesToRemove
12465
+ });
12466
+ }
12467
+ current = next;
12468
+ }
12469
+ }
12068
12470
  }
12069
12471
  }
12070
12472
  );
@@ -14823,14 +15225,26 @@
14823
15225
  }
14824
15226
  return pbRHTNodes;
14825
15227
  }
14826
- function toRGANodes(rgaTreeList) {
15228
+ function toRGANodes(arr) {
14827
15229
  const pbRGANodes = [];
14828
- for (const rgaTreeListNode of rgaTreeList) {
14829
- pbRGANodes.push(
14830
- create(RGANodeSchema, {
14831
- element: toElement(rgaTreeListNode.getValue())
14832
- })
14833
- );
15230
+ for (const rgaNode of arr.getAllRGANodes()) {
15231
+ if (!rgaNode.getElementEntry()) {
15232
+ pbRGANodes.push(
15233
+ create(RGANodeSchema, {
15234
+ positionCreatedAt: toTimeTicket(rgaNode.getPositionCreatedAt()),
15235
+ positionRemovedAt: toTimeTicket(rgaNode.getRemovedAt())
15236
+ })
15237
+ );
15238
+ continue;
15239
+ }
15240
+ const pbNode = create(RGANodeSchema, {
15241
+ element: toElement(rgaNode.getValue())
15242
+ });
15243
+ if (rgaNode.getPositionMovedAt()) {
15244
+ pbNode.positionMovedAt = toTimeTicket(rgaNode.getPositionMovedAt());
15245
+ pbNode.positionCreatedAt = toTimeTicket(rgaNode.getPositionCreatedAt());
15246
+ }
15247
+ pbRGANodes.push(pbNode);
14834
15248
  }
14835
15249
  return pbRGANodes;
14836
15250
  }
@@ -14930,7 +15344,7 @@
14930
15344
  body: {
14931
15345
  case: "jsonArray",
14932
15346
  value: create(JSONElement_JSONArraySchema, {
14933
- nodes: toRGANodes(arr.getElements()),
15347
+ nodes: toRGANodes(arr),
14934
15348
  createdAt: toTimeTicket(arr.getCreatedAt()),
14935
15349
  movedAt: toTimeTicket(arr.getMovedAt()),
14936
15350
  removedAt: toTimeTicket(arr.getRemovedAt())
@@ -15468,7 +15882,32 @@
15468
15882
  function fromArray(pbArray) {
15469
15883
  const rgaTreeList = new RGATreeList();
15470
15884
  for (const pbRGANode of pbArray.nodes) {
15471
- rgaTreeList.insert(fromElement(pbRGANode.element));
15885
+ if (!pbRGANode.element) {
15886
+ if (!pbRGANode.positionCreatedAt || !pbRGANode.positionRemovedAt) {
15887
+ throw new YorkieError(
15888
+ Code.ErrInvalidArgument,
15889
+ "dead RGA position node missing position timestamps"
15890
+ );
15891
+ }
15892
+ const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
15893
+ const posRemovedAt = fromTimeTicket(pbRGANode.positionRemovedAt);
15894
+ rgaTreeList.addDeadPosition(posCreatedAt, posRemovedAt);
15895
+ continue;
15896
+ }
15897
+ const elem = fromElement(pbRGANode.element);
15898
+ const posMovedAt = fromTimeTicket(pbRGANode.positionMovedAt);
15899
+ if (posMovedAt) {
15900
+ if (!pbRGANode.positionCreatedAt) {
15901
+ throw new YorkieError(
15902
+ Code.ErrInvalidArgument,
15903
+ "moved RGA node missing position_created_at"
15904
+ );
15905
+ }
15906
+ const posCreatedAt = fromTimeTicket(pbRGANode.positionCreatedAt);
15907
+ rgaTreeList.addMovedElement(elem, posCreatedAt, posMovedAt);
15908
+ } else {
15909
+ rgaTreeList.insert(elem);
15910
+ }
15472
15911
  }
15473
15912
  const arr = new CRDTArray(fromTimeTicket(pbArray.createdAt), rgaTreeList);
15474
15913
  arr.setMovedAt(fromTimeTicket(pbArray.movedAt));
@@ -16256,10 +16695,16 @@
16256
16695
  };
16257
16696
  } else if (method === "insertAfter") {
16258
16697
  return (prevID, value) => {
16698
+ let posCreatedAt;
16699
+ try {
16700
+ posCreatedAt = target.posCreatedAt(prevID);
16701
+ } catch {
16702
+ posCreatedAt = prevID;
16703
+ }
16259
16704
  const inserted = ArrayProxy.insertAfterInternal(
16260
16705
  context,
16261
16706
  target,
16262
- prevID,
16707
+ posCreatedAt,
16263
16708
  value
16264
16709
  );
16265
16710
  return toWrappedElement(context, inserted);
@@ -16444,7 +16889,7 @@
16444
16889
  static moveBeforeInternal(context, target, nextCreatedAt, createdAt) {
16445
16890
  const ticket = context.issueTimeTicket();
16446
16891
  const prevCreatedAt = target.getPrevCreatedAt(nextCreatedAt);
16447
- target.moveAfter(prevCreatedAt, createdAt, ticket);
16892
+ const deadNode = target.moveAfter(prevCreatedAt, createdAt, ticket);
16448
16893
  context.push(
16449
16894
  MoveOperation.create(
16450
16895
  target.getCreatedAt(),
@@ -16453,26 +16898,45 @@
16453
16898
  ticket
16454
16899
  )
16455
16900
  );
16901
+ if (deadNode) {
16902
+ context.registerGCPair({
16903
+ parent: target.getRGATreeList(),
16904
+ child: deadNode
16905
+ });
16906
+ }
16456
16907
  }
16457
16908
  /**
16458
16909
  * `moveAfterInternal` moves the given `createdAt` element
16459
- * after the specific element.
16910
+ * after the specific element. Converts element identity to
16911
+ * position identity for the prevCreatedAt.
16460
16912
  */
16461
16913
  static moveAfterInternal(context, target, prevCreatedAt, createdAt) {
16462
16914
  const ticket = context.issueTimeTicket();
16915
+ let posCreatedAt;
16916
+ try {
16917
+ posCreatedAt = target.posCreatedAt(prevCreatedAt);
16918
+ } catch {
16919
+ posCreatedAt = prevCreatedAt;
16920
+ }
16921
+ const deadNode = target.moveAfter(posCreatedAt, createdAt, ticket);
16463
16922
  context.push(
16464
16923
  MoveOperation.create(
16465
16924
  target.getCreatedAt(),
16466
- prevCreatedAt,
16925
+ posCreatedAt,
16467
16926
  createdAt,
16468
16927
  ticket
16469
16928
  )
16470
16929
  );
16471
- target.moveAfter(prevCreatedAt, createdAt, ticket);
16930
+ if (deadNode) {
16931
+ context.registerGCPair({
16932
+ parent: target.getRGATreeList(),
16933
+ child: deadNode
16934
+ });
16935
+ }
16472
16936
  }
16473
16937
  /**
16474
- * `moveAfterByIndexInternal` moves the given element to its new position
16475
- * after the given previous element.
16938
+ * `moveAfterByIndexInternal` moves the given element to its new
16939
+ * position after the given previous element.
16476
16940
  */
16477
16941
  static moveAfterByIndexInternal(context, target, prevIndex, targetIndex) {
16478
16942
  const prevElem = target.get(prevIndex);
@@ -16503,7 +16967,7 @@
16503
16967
  static moveFrontInternal(context, target, createdAt) {
16504
16968
  const ticket = context.issueTimeTicket();
16505
16969
  const head = target.getHead();
16506
- target.moveAfter(head.getCreatedAt(), createdAt, ticket);
16970
+ const deadNode = target.moveAfter(head.getCreatedAt(), createdAt, ticket);
16507
16971
  context.push(
16508
16972
  MoveOperation.create(
16509
16973
  target.getCreatedAt(),
@@ -16512,6 +16976,12 @@
16512
16976
  ticket
16513
16977
  )
16514
16978
  );
16979
+ if (deadNode) {
16980
+ context.registerGCPair({
16981
+ parent: target.getRGATreeList(),
16982
+ child: deadNode
16983
+ });
16984
+ }
16515
16985
  }
16516
16986
  /**
16517
16987
  * `moveLastInternal` moves the given `createdAt` element
@@ -16520,13 +16990,20 @@
16520
16990
  static moveLastInternal(context, target, createdAt) {
16521
16991
  const ticket = context.issueTimeTicket();
16522
16992
  const last = target.getLastCreatedAt();
16523
- target.moveAfter(last, createdAt, ticket);
16993
+ const deadNode = target.moveAfter(last, createdAt, ticket);
16524
16994
  context.push(
16525
16995
  MoveOperation.create(target.getCreatedAt(), last, createdAt, ticket)
16526
16996
  );
16997
+ if (deadNode) {
16998
+ context.registerGCPair({
16999
+ parent: target.getRGATreeList(),
17000
+ child: deadNode
17001
+ });
17002
+ }
16527
17003
  }
16528
17004
  /**
16529
- * `insertAfterInternal` inserts the value after the previously created element.
17005
+ * `insertAfterInternal` inserts the value after the previously
17006
+ * created element.
16530
17007
  */
16531
17008
  static insertAfterInternal(context, target, prevCreatedAt, value) {
16532
17009
  const createdAt = context.issueTimeTicket();
@@ -16554,12 +17031,13 @@
16554
17031
  `index out of bounds: ${index}`
16555
17032
  );
16556
17033
  }
16557
- ArrayProxy.insertAfterInternal(
16558
- context,
16559
- target,
16560
- prevElem.getCreatedAt(),
16561
- value
16562
- );
17034
+ let posCreatedAt;
17035
+ try {
17036
+ posCreatedAt = target.posCreatedAt(prevElem.getCreatedAt());
17037
+ } catch {
17038
+ posCreatedAt = prevElem.getCreatedAt();
17039
+ }
17040
+ ArrayProxy.insertAfterInternal(context, target, posCreatedAt, value);
16563
17041
  return target;
16564
17042
  }
16565
17043
  /**
@@ -16658,7 +17136,17 @@
16658
17136
  }
16659
17137
  }
16660
17138
  if (items) {
16661
- let previousID = from === 0 ? target.getHead().getID() : target.get(from - 1).getID();
17139
+ let previousID;
17140
+ if (from === 0) {
17141
+ previousID = target.getHead().getID();
17142
+ } else {
17143
+ const elemID = target.get(from - 1).getID();
17144
+ try {
17145
+ previousID = target.posCreatedAt(elemID);
17146
+ } catch {
17147
+ previousID = elemID;
17148
+ }
17149
+ }
16662
17150
  for (const item of items) {
16663
17151
  const newElem = ArrayProxy.insertAfterInternal(
16664
17152
  context,
@@ -18008,6 +18496,16 @@
18008
18496
  this.registerGCPair(pair);
18009
18497
  }
18010
18498
  }
18499
+ if (elem instanceof CRDTArray) {
18500
+ for (const node of elem.getAllRGANodes()) {
18501
+ if (!node.getElementEntry() && node.getRemovedAt()) {
18502
+ this.registerGCPair({
18503
+ parent: elem.getRGATreeList(),
18504
+ child: node
18505
+ });
18506
+ }
18507
+ }
18508
+ }
18011
18509
  return false;
18012
18510
  });
18013
18511
  }
@@ -19099,6 +19597,11 @@
19099
19597
  if (logger.isEnabled(LogLevel.Trivial)) {
19100
19598
  logger.trivial(`trying to update a local change: ${this.toJSON()}`);
19101
19599
  }
19600
+ const prev = {
19601
+ hadPresence: this.presences.has(actorID),
19602
+ wasOnline: this.status === "attached",
19603
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
19604
+ };
19102
19605
  const change = ctx.toChange();
19103
19606
  const { opInfos, reverseOps } = change.execute(
19104
19607
  this.root,
@@ -19144,14 +19647,14 @@
19144
19647
  });
19145
19648
  }
19146
19649
  if (change.hasPresenceChange()) {
19147
- event.push({
19148
- type: "presence-changed",
19149
- source: OpSource.Local,
19150
- value: {
19151
- clientID: actorID,
19152
- presence: this.getPresence(actorID)
19153
- }
19154
- });
19650
+ const presenceEvent = this.reconcilePresence(
19651
+ actorID,
19652
+ prev,
19653
+ OpSource.Local
19654
+ );
19655
+ if (presenceEvent) {
19656
+ event.push(presenceEvent);
19657
+ }
19155
19658
  }
19156
19659
  this.publish(event);
19157
19660
  if (logger.isEnabled(LogLevel.Trivial)) {
@@ -19635,41 +20138,11 @@
19635
20138
  change.execute(this.clone.root, this.clone.presences, source);
19636
20139
  const events = [];
19637
20140
  const actorID = change.getID().getActorID();
19638
- if (change.hasPresenceChange() && this.onlineClients.has(actorID)) {
19639
- const presenceChange = change.getPresenceChange();
19640
- switch (presenceChange.type) {
19641
- case PresenceChangeType.Put:
19642
- events.push(
19643
- this.presences.has(actorID) ? {
19644
- type: "presence-changed",
19645
- source,
19646
- value: {
19647
- clientID: actorID,
19648
- presence: presenceChange.presence
19649
- }
19650
- } : {
19651
- type: "watched",
19652
- source: OpSource.Remote,
19653
- value: {
19654
- clientID: actorID,
19655
- presence: presenceChange.presence
19656
- }
19657
- }
19658
- );
19659
- break;
19660
- case PresenceChangeType.Clear:
19661
- events.push({
19662
- type: "unwatched",
19663
- source: OpSource.Remote,
19664
- value: {
19665
- clientID: actorID,
19666
- presence: this.getPresence(actorID)
19667
- }
19668
- });
19669
- this.removeOnlineClient(actorID);
19670
- break;
19671
- }
19672
- }
20141
+ const prev = change.hasPresenceChange() ? {
20142
+ hadPresence: this.presences.has(actorID),
20143
+ wasOnline: this.onlineClients.has(actorID),
20144
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20145
+ } : void 0;
19673
20146
  const { opInfos, operations } = change.execute(
19674
20147
  this.root,
19675
20148
  this.presences,
@@ -19724,6 +20197,16 @@
19724
20197
  }
19725
20198
  );
19726
20199
  }
20200
+ if (prev && change.hasPresenceChange()) {
20201
+ const presenceChange = change.getPresenceChange();
20202
+ if (presenceChange.type === PresenceChangeType.Clear) {
20203
+ this.removeOnlineClient(actorID);
20204
+ }
20205
+ const presenceEvent = this.reconcilePresence(actorID, prev, source);
20206
+ if (presenceEvent) {
20207
+ events.push(presenceEvent);
20208
+ }
20209
+ }
19727
20210
  if (events.length) {
19728
20211
  this.publish(events);
19729
20212
  }
@@ -19752,46 +20235,43 @@
19752
20235
  * `applyDocEvent` applies the given doc event into this document.
19753
20236
  */
19754
20237
  applyDocEvent(type, publisher) {
19755
- const events = [];
20238
+ const prev = {
20239
+ hadPresence: this.presences.has(publisher),
20240
+ wasOnline: this.onlineClients.has(publisher),
20241
+ presence: this.presences.has(publisher) ? deepcopy(this.presences.get(publisher)) : void 0
20242
+ };
19756
20243
  if (type === DocEventType$1.DOCUMENT_WATCHED) {
19757
20244
  if (this.onlineClients.has(publisher) && this.hasPresence(publisher)) {
19758
20245
  return;
19759
20246
  }
19760
20247
  this.addOnlineClient(publisher);
19761
- if (this.hasPresence(publisher)) {
19762
- events.push({
19763
- type: "watched",
19764
- source: OpSource.Remote,
19765
- value: {
19766
- clientID: publisher,
19767
- presence: this.getPresence(publisher)
19768
- }
19769
- });
19770
- }
19771
20248
  } else if (type === DocEventType$1.DOCUMENT_UNWATCHED) {
19772
- const presence = this.getPresence(publisher);
19773
20249
  this.removeOnlineClient(publisher);
19774
20250
  this.presences.delete(publisher);
19775
- if (presence) {
19776
- events.push({
19777
- type: "unwatched",
19778
- source: OpSource.Remote,
19779
- value: { clientID: publisher, presence }
19780
- });
19781
- }
19782
20251
  }
19783
- if (events.length) {
19784
- this.publish(events);
20252
+ const event = this.reconcilePresence(publisher, prev, OpSource.Remote);
20253
+ if (event) {
20254
+ this.publish([event]);
19785
20255
  }
19786
20256
  }
19787
20257
  /**
19788
20258
  * `applyStatus` applies the document status into this document.
19789
20259
  */
19790
20260
  applyStatus(status) {
20261
+ const actorID = this.changeID.getActorID();
20262
+ const prev = {
20263
+ hadPresence: this.presences.has(actorID),
20264
+ wasOnline: this.status === "attached",
20265
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20266
+ };
19791
20267
  this.status = status;
19792
20268
  if (status === "detached") {
19793
20269
  this.setActor(InitialActorID);
19794
20270
  }
20271
+ const event = this.reconcilePresence(actorID, prev, OpSource.Local);
20272
+ if (event) {
20273
+ this.publish([event]);
20274
+ }
19795
20275
  this.publish([
19796
20276
  {
19797
20277
  source: status === "removed" ? OpSource.Remote : OpSource.Local,
@@ -19891,6 +20371,57 @@
19891
20371
  removeOnlineClient(clientID) {
19892
20372
  this.onlineClients.delete(clientID);
19893
20373
  }
20374
+ /**
20375
+ * `reconcilePresence` compares the previous and current state of a client's
20376
+ * presence/online status and returns the appropriate event to emit.
20377
+ *
20378
+ * For remote clients, "online" means the client is in onlineClients.
20379
+ * For self, "online" means the document status is Attached.
20380
+ *
20381
+ * State transition table:
20382
+ * (!hadP || !wasOn) → (hasP && isOn) : watched (remote) or presence-changed (self)
20383
+ * (hadP && wasOn) → (hasP && isOn) : presence-changed
20384
+ * (hadP && wasOn) → (!hasP || !isOn): unwatched (remote only)
20385
+ * otherwise : no event (waiting)
20386
+ */
20387
+ reconcilePresence(actorID, prev, source) {
20388
+ const isSelf = actorID === this.changeID.getActorID();
20389
+ const hasPresence = this.presences.has(actorID);
20390
+ const isOnline = isSelf ? this.status === "attached" : this.onlineClients.has(actorID);
20391
+ if (!hasPresence || !isOnline) {
20392
+ if (prev.hadPresence && prev.wasOnline && !isSelf) {
20393
+ return {
20394
+ type: "unwatched",
20395
+ source: OpSource.Remote,
20396
+ value: {
20397
+ clientID: actorID,
20398
+ presence: prev.presence
20399
+ }
20400
+ };
20401
+ }
20402
+ return void 0;
20403
+ }
20404
+ const presence = deepcopy(this.presences.get(actorID));
20405
+ if (!prev.hadPresence || !prev.wasOnline) {
20406
+ if (isSelf) {
20407
+ return {
20408
+ type: "presence-changed",
20409
+ source,
20410
+ value: { clientID: actorID, presence }
20411
+ };
20412
+ }
20413
+ return {
20414
+ type: "watched",
20415
+ source: OpSource.Remote,
20416
+ value: { clientID: actorID, presence }
20417
+ };
20418
+ }
20419
+ return {
20420
+ type: "presence-changed",
20421
+ source,
20422
+ value: { clientID: actorID, presence }
20423
+ };
20424
+ }
19894
20425
  /**
19895
20426
  * `hasPresence` returns whether the given clientID has a presence or not.
19896
20427
  */
@@ -20052,18 +20583,24 @@
20052
20583
  const ticket = ctx.issueTimeTicket();
20053
20584
  op.setExecutedAt(ticket);
20054
20585
  if (op instanceof ArraySetOperation) {
20055
- const prev = op.getCreatedAt();
20586
+ const prev2 = op.getCreatedAt();
20056
20587
  op.getValue().setCreatedAt(ticket);
20057
- this.internalHistory.reconcileCreatedAt(prev, ticket);
20588
+ this.internalHistory.reconcileCreatedAt(prev2, ticket);
20058
20589
  } else if (op instanceof AddOperation) {
20059
- const prev = op.getValue().getCreatedAt();
20590
+ const prev2 = op.getValue().getCreatedAt();
20060
20591
  op.getValue().setCreatedAt(ticket);
20061
- this.internalHistory.reconcileCreatedAt(prev, ticket);
20592
+ this.internalHistory.reconcileCreatedAt(prev2, ticket);
20062
20593
  }
20063
20594
  ctx.push(op);
20064
20595
  }
20065
20596
  const change = ctx.toChange();
20066
20597
  change.execute(this.clone.root, this.clone.presences, OpSource.UndoRedo);
20598
+ const actorID = this.changeID.getActorID();
20599
+ const prev = {
20600
+ hadPresence: this.presences.has(actorID),
20601
+ wasOnline: this.status === "attached",
20602
+ presence: this.presences.has(actorID) ? deepcopy(this.presences.get(actorID)) : void 0
20603
+ };
20067
20604
  const { opInfos, reverseOps } = change.execute(
20068
20605
  this.root,
20069
20606
  this.presences,
@@ -20085,7 +20622,6 @@
20085
20622
  }
20086
20623
  this.localChanges.push(change);
20087
20624
  this.changeID = ctx.getNextID();
20088
- const actorID = this.changeID.getActorID();
20089
20625
  const events = [];
20090
20626
  if (opInfos.length) {
20091
20627
  events.push({
@@ -20102,14 +20638,14 @@
20102
20638
  });
20103
20639
  }
20104
20640
  if (change.hasPresenceChange()) {
20105
- events.push({
20106
- type: "presence-changed",
20107
- source: OpSource.UndoRedo,
20108
- value: {
20109
- clientID: actorID,
20110
- presence: this.getPresence(actorID)
20111
- }
20112
- });
20641
+ const presenceEvent = this.reconcilePresence(
20642
+ actorID,
20643
+ prev,
20644
+ OpSource.UndoRedo
20645
+ );
20646
+ if (presenceEvent) {
20647
+ events.push(presenceEvent);
20648
+ }
20113
20649
  }
20114
20650
  this.publish(events);
20115
20651
  }
@@ -20125,6 +20661,8 @@
20125
20661
  watchStream;
20126
20662
  watchLoopTimerID;
20127
20663
  watchAbortController;
20664
+ syncPromise;
20665
+ _detaching = false;
20128
20666
  constructor(reconnectStreamDelay, resource, resourceID, syncMode) {
20129
20667
  this.reconnectStreamDelay = reconnectStreamDelay;
20130
20668
  this.resource = resource;
@@ -20200,6 +20738,49 @@
20200
20738
  };
20201
20739
  await doLoop();
20202
20740
  }
20741
+ /**
20742
+ * `markDetaching` marks this attachment as being in the process of detaching.
20743
+ * Once marked, the sync loop will skip this attachment.
20744
+ */
20745
+ markDetaching() {
20746
+ this._detaching = true;
20747
+ }
20748
+ /**
20749
+ * `isDetaching` returns whether this attachment is being detached.
20750
+ */
20751
+ isDetaching() {
20752
+ return this._detaching;
20753
+ }
20754
+ /**
20755
+ * `resetDetaching` resets the detaching flag so the attachment can resume
20756
+ * syncing. Used when a detach RPC fails and the document remains attached.
20757
+ */
20758
+ resetDetaching() {
20759
+ this._detaching = false;
20760
+ }
20761
+ /**
20762
+ * `setSyncPromise` sets the in-progress sync promise for this attachment.
20763
+ */
20764
+ setSyncPromise(promise) {
20765
+ this.syncPromise = promise;
20766
+ }
20767
+ /**
20768
+ * `clearSyncPromise` clears the in-progress sync promise.
20769
+ */
20770
+ clearSyncPromise() {
20771
+ this.syncPromise = void 0;
20772
+ }
20773
+ /**
20774
+ * `waitForSyncComplete` waits for any in-progress sync to complete.
20775
+ */
20776
+ async waitForSyncComplete() {
20777
+ if (this.syncPromise) {
20778
+ try {
20779
+ await this.syncPromise;
20780
+ } catch {
20781
+ }
20782
+ }
20783
+ }
20203
20784
  /**
20204
20785
  * `cancelWatchStream` cancels the watch stream.
20205
20786
  */
@@ -20234,7 +20815,7 @@
20234
20815
  };
20235
20816
  }
20236
20817
  const name = "@yorkie-js/sdk";
20237
- const version = "0.7.5";
20818
+ const version = "0.7.6";
20238
20819
  const pkg = {
20239
20820
  name,
20240
20821
  version
@@ -20559,6 +21140,7 @@
20559
21140
  taskQueue;
20560
21141
  processing = false;
20561
21142
  keepalive = false;
21143
+ deactivating = false;
20562
21144
  /**
20563
21145
  * @param rpcAddr - the address of the RPC server.
20564
21146
  * @param opts - the options of the client.
@@ -20628,6 +21210,7 @@
20628
21210
  );
20629
21211
  this.id = res.clientId;
20630
21212
  this.status = "activated";
21213
+ this.deactivating = false;
20631
21214
  this.runSyncLoop();
20632
21215
  logger.info(`[AC] c:"${this.getKey()}" activated, id:"${this.id}"`);
20633
21216
  if (typeof window !== "undefined") {
@@ -20656,6 +21239,7 @@
20656
21239
  if (this.status === "deactivated") {
20657
21240
  return Promise.resolve();
20658
21241
  }
21242
+ this.deactivating = true;
20659
21243
  const task = async () => {
20660
21244
  try {
20661
21245
  await this.rpcClient.deactivateClient(
@@ -20669,6 +21253,7 @@
20669
21253
  logger.info(`[DC] c"${this.getKey()}" deactivated`);
20670
21254
  } catch (err) {
20671
21255
  logger.error(`[DC] c:"${this.getKey()}" err :`, err);
21256
+ this.deactivating = false;
20672
21257
  await this.handleConnectError(err);
20673
21258
  throw err;
20674
21259
  }
@@ -20809,8 +21394,10 @@
20809
21394
  );
20810
21395
  }
20811
21396
  doc.update((_, p) => p.clear());
21397
+ attachment.markDetaching();
20812
21398
  const task = async () => {
20813
21399
  try {
21400
+ await attachment.waitForSyncComplete();
20814
21401
  const res = await this.rpcClient.detachDocument(
20815
21402
  {
20816
21403
  clientId: this.id,
@@ -20829,6 +21416,7 @@
20829
21416
  return doc;
20830
21417
  } catch (err) {
20831
21418
  logger.error(`[DD] c:"${this.getKey()}" err :`, err);
21419
+ attachment.resetDetaching();
20832
21420
  await this.handleConnectError(err);
20833
21421
  throw err;
20834
21422
  }
@@ -21395,7 +21983,7 @@
21395
21983
  */
21396
21984
  runSyncLoop() {
21397
21985
  const doLoop = async () => {
21398
- if (!this.isActive()) {
21986
+ if (!this.isActive() || this.deactivating) {
21399
21987
  logger.debug(`[SL] c:"${this.getKey()}" exit sync loop`);
21400
21988
  this.conditions[
21401
21989
  "SyncLoop"
@@ -21407,43 +21995,62 @@
21407
21995
  await this.enqueueTask(async () => {
21408
21996
  const syncs = [];
21409
21997
  for (const [, attachment] of this.attachmentMap) {
21998
+ if (this.deactivating) {
21999
+ break;
22000
+ }
21410
22001
  if (!attachment.needSync(this.channelHeartbeatInterval)) {
21411
22002
  continue;
21412
22003
  }
22004
+ if (attachment.isDetaching()) {
22005
+ continue;
22006
+ }
21413
22007
  if (attachment.changeEventReceived !== void 0) {
21414
22008
  attachment.changeEventReceived = false;
21415
22009
  }
21416
- syncs.push(
21417
- this.syncInternal(attachment, attachment.syncMode).catch((e) => {
21418
- if (isErrorCode(e, Code.ErrUnauthenticated)) {
21419
- attachment.resource.publish([
21420
- {
21421
- type: DocEventType.AuthError,
21422
- value: {
21423
- reason: errorMetadataOf(e).reason,
21424
- method: "PushPull"
21425
- }
22010
+ const syncPromise = this.syncInternal(
22011
+ attachment,
22012
+ attachment.syncMode
22013
+ ).then(() => {
22014
+ }).catch((e) => {
22015
+ if (isErrorCode(e, Code.ErrUnauthenticated)) {
22016
+ attachment.resource.publish([
22017
+ {
22018
+ type: DocEventType.AuthError,
22019
+ value: {
22020
+ reason: errorMetadataOf(e).reason,
22021
+ method: "PushPull"
21426
22022
  }
21427
- ]);
21428
- }
21429
- if (isErrorCode(e, Code.ErrEpochMismatch)) {
21430
- attachment.resource.publish([
21431
- {
21432
- type: DocEventType.EpochMismatch,
21433
- value: {
21434
- method: "PushPull"
21435
- }
22023
+ }
22024
+ ]);
22025
+ }
22026
+ if (isErrorCode(e, Code.ErrEpochMismatch)) {
22027
+ attachment.resource.publish([
22028
+ {
22029
+ type: DocEventType.EpochMismatch,
22030
+ value: {
22031
+ method: "PushPull"
21436
22032
  }
21437
- ]);
21438
- }
21439
- throw e;
21440
- })
21441
- );
22033
+ }
22034
+ ]);
22035
+ }
22036
+ throw e;
22037
+ }).finally(() => {
22038
+ attachment.clearSyncPromise();
22039
+ });
22040
+ attachment.setSyncPromise(syncPromise);
22041
+ syncs.push(syncPromise);
21442
22042
  }
21443
22043
  await Promise.all(syncs);
21444
22044
  setTimeout(doLoop, this.syncLoopDuration);
21445
22045
  });
21446
22046
  } catch (err) {
22047
+ if (this.deactivating) {
22048
+ this.conditions[
22049
+ "SyncLoop"
22050
+ /* SyncLoop */
22051
+ ] = false;
22052
+ return;
22053
+ }
21447
22054
  logger.error(`[SL] c:"${this.getKey()}" sync failed:`, err);
21448
22055
  if (await this.handleConnectError(err)) {
21449
22056
  setTimeout(doLoop, this.retrySyncLoopDelay);