@mflrevan/ucp 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +1 -1
  2. package/bridge/com.ucp.bridge/CHANGELOG.md +145 -0
  3. package/bridge/com.ucp.bridge/CHANGELOG.md.meta +7 -0
  4. package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs +583 -0
  5. package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs.meta +2 -0
  6. package/bridge/com.ucp.bridge/Editor/Bridge.meta +8 -0
  7. package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs +425 -0
  8. package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs.meta +2 -0
  9. package/bridge/com.ucp.bridge/Editor/Controllers/AssetImportSupport.cs +355 -0
  10. package/bridge/com.ucp.bridge/Editor/Controllers/AssetImportSupport.cs.meta +2 -0
  11. package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs +233 -0
  12. package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs.meta +2 -0
  13. package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs +26 -0
  14. package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs.meta +2 -0
  15. package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs +31 -0
  16. package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs.meta +2 -0
  17. package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs +527 -0
  18. package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs.meta +2 -0
  19. package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs +141 -0
  20. package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs.meta +2 -0
  21. package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs +326 -0
  22. package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs.meta +2 -0
  23. package/bridge/com.ucp.bridge/Editor/Controllers/ImporterController.cs +209 -0
  24. package/bridge/com.ucp.bridge/Editor/Controllers/ImporterController.cs.meta +2 -0
  25. package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs +409 -0
  26. package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs.meta +2 -0
  27. package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs +354 -0
  28. package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs.meta +2 -0
  29. package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs +93 -0
  30. package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs.meta +2 -0
  31. package/bridge/com.ucp.bridge/Editor/Controllers/PackagesController.cs +503 -0
  32. package/bridge/com.ucp.bridge/Editor/Controllers/PackagesController.cs.meta +2 -0
  33. package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs +188 -0
  34. package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs.meta +2 -0
  35. package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs +260 -0
  36. package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs.meta +2 -0
  37. package/bridge/com.ucp.bridge/Editor/Controllers/ProfilerController.cs +1679 -0
  38. package/bridge/com.ucp.bridge/Editor/Controllers/ProfilerController.cs.meta +2 -0
  39. package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs +563 -0
  40. package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs.meta +2 -0
  41. package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs +166 -0
  42. package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs.meta +2 -0
  43. package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs +318 -0
  44. package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs.meta +2 -0
  45. package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs +125 -0
  46. package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs.meta +2 -0
  47. package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs +104 -0
  48. package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs.meta +2 -0
  49. package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs +227 -0
  50. package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs.meta +2 -0
  51. package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs +240 -0
  52. package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs.meta +2 -0
  53. package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs +611 -0
  54. package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs.meta +2 -0
  55. package/bridge/com.ucp.bridge/Editor/Controllers.meta +8 -0
  56. package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs +53 -0
  57. package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs.meta +2 -0
  58. package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs +80 -0
  59. package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs.meta +2 -0
  60. package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs +358 -0
  61. package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs.meta +2 -0
  62. package/bridge/com.ucp.bridge/Editor/Protocol.meta +8 -0
  63. package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs +37 -0
  64. package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs.meta +2 -0
  65. package/bridge/com.ucp.bridge/Editor/Scripts.meta +8 -0
  66. package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef +16 -0
  67. package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef.meta +7 -0
  68. package/bridge/com.ucp.bridge/Editor.meta +8 -0
  69. package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef +14 -0
  70. package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef.meta +7 -0
  71. package/bridge/com.ucp.bridge/Runtime.meta +8 -0
  72. package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs +1085 -0
  73. package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs.meta +2 -0
  74. package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef +12 -0
  75. package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef.meta +7 -0
  76. package/bridge/com.ucp.bridge/Tests/Editor.meta +8 -0
  77. package/bridge/com.ucp.bridge/Tests.meta +8 -0
  78. package/bridge/com.ucp.bridge/package.json +27 -0
  79. package/bridge/com.ucp.bridge/package.json.meta +7 -0
  80. package/package.json +2 -2
  81. package/scripts/install.js +4 -6
@@ -0,0 +1,409 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using System.Linq;
4
+ using System.Text.RegularExpressions;
5
+ using UnityEngine;
6
+
7
+ namespace UCP.Bridge
8
+ {
9
+ public static class LogsController
10
+ {
11
+ private const int MaxHistoryEntries = 2000;
12
+ private const int DefaultSearchWindow = 200;
13
+ private const int MaxPreviewLength = 200;
14
+
15
+ private static readonly object s_historyLock = new object();
16
+ private static readonly List<LogRecord> s_history = new List<LogRecord>();
17
+ private static long s_nextId = 1;
18
+
19
+ public static void Register(CommandRouter router)
20
+ {
21
+ router.Register("logs/subscribe", _ => new Dictionary<string, object> { ["subscribed"] = true });
22
+ router.Register("logs/unsubscribe", _ => new Dictionary<string, object> { ["unsubscribed"] = true });
23
+ router.Register("logs/tail", HandleTail);
24
+ router.Register("logs/search", HandleSearch);
25
+ router.Register("logs/get", HandleGet);
26
+ router.Register("logs/status", HandleStatus);
27
+ }
28
+
29
+ public static Dictionary<string, object> RecordLog(string message, string stackTrace, LogType type)
30
+ {
31
+ return RecordLog(NormalizeLevel(type), message, stackTrace);
32
+ }
33
+
34
+ public static void ClearHistoryForTests()
35
+ {
36
+ lock (s_historyLock)
37
+ {
38
+ s_history.Clear();
39
+ s_nextId = 1;
40
+ }
41
+ }
42
+
43
+ public static Dictionary<string, object> RecordTestLog(string level, string message, string stackTrace = "")
44
+ {
45
+ return RecordLog(level, message, stackTrace);
46
+ }
47
+
48
+ private static object HandleTail(string paramsJson)
49
+ {
50
+ var query = ParseQuery(paramsJson, includePattern: false);
51
+ return BuildListResult(QueryHistory(query));
52
+ }
53
+
54
+ private static object HandleSearch(string paramsJson)
55
+ {
56
+ var query = ParseQuery(paramsJson, includePattern: true);
57
+ return BuildListResult(QueryHistory(query));
58
+ }
59
+
60
+ private static object HandleGet(string paramsJson)
61
+ {
62
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
63
+ if (p == null || !p.TryGetValue("id", out var idObj))
64
+ throw new ArgumentException("Missing 'id' parameter");
65
+
66
+ long id = Convert.ToInt64(idObj);
67
+
68
+ lock (s_historyLock)
69
+ {
70
+ var entry = s_history.FirstOrDefault(record => record.Id == id);
71
+ if (entry == null)
72
+ throw new ArgumentException($"Log entry not found: {id}");
73
+
74
+ return SerializeFull(entry);
75
+ }
76
+ }
77
+
78
+ private static object HandleStatus(string paramsJson)
79
+ {
80
+ lock (s_historyLock)
81
+ {
82
+ var ordered = s_history.OrderBy(entry => entry.Id).ToList();
83
+ var byLevel = new Dictionary<string, object>
84
+ {
85
+ ["info"] = ordered.Count(entry => entry.Level == "info"),
86
+ ["warning"] = ordered.Count(entry => entry.Level == "warning"),
87
+ ["error"] = ordered.Count(entry => entry.Level == "error"),
88
+ ["exception"] = ordered.Count(entry => entry.Level == "exception")
89
+ };
90
+
91
+ var grouped = ordered
92
+ .GroupBy(entry => $"{entry.Level}|{Fingerprint(entry.Message)}")
93
+ .Select(group =>
94
+ {
95
+ var first = group.First();
96
+ var last = group.Last();
97
+ return new Dictionary<string, object>
98
+ {
99
+ ["level"] = first.Level,
100
+ ["fingerprint"] = Fingerprint(first.Message),
101
+ ["sampleMessage"] = Preview(first.Message, MaxPreviewLength),
102
+ ["count"] = group.Count(),
103
+ ["firstTimestamp"] = first.Timestamp,
104
+ ["lastTimestamp"] = last.Timestamp,
105
+ ["latestId"] = last.Id
106
+ };
107
+ })
108
+ .OrderByDescending(entry => Convert.ToInt32(entry["count"]))
109
+ .ThenBy(entry => entry["sampleMessage"].ToString())
110
+ .ToList();
111
+
112
+ var result = new Dictionary<string, object>
113
+ {
114
+ ["total"] = ordered.Count,
115
+ ["byLevel"] = byLevel,
116
+ ["uniqueCount"] = grouped.Count,
117
+ ["topCategories"] = grouped.Take(8).Cast<object>().ToList()
118
+ };
119
+
120
+ if (ordered.Count > 0)
121
+ {
122
+ var first = ordered.First();
123
+ var last = ordered.Last();
124
+ result["firstTimestamp"] = first.Timestamp;
125
+ result["lastTimestamp"] = last.Timestamp;
126
+ result["historyWindowSeconds"] = Math.Max(0d, (last.TimestampUtc - first.TimestampUtc).TotalSeconds);
127
+ result["latestId"] = last.Id;
128
+ }
129
+
130
+ var playSession = PlayModeController.GetSessionSnapshot();
131
+ result["play"] = SerializePlaySession(playSession);
132
+
133
+ if (playSession.LastEnteredPlayAtUtc.HasValue)
134
+ {
135
+ var sessionEnd = playSession.Playing
136
+ ? DateTime.UtcNow
137
+ : (playSession.LastExitedPlayAtUtc ?? DateTime.UtcNow);
138
+ var sessionLogs = ordered
139
+ .Where(entry => entry.TimestampUtc >= playSession.LastEnteredPlayAtUtc.Value
140
+ && entry.TimestampUtc <= sessionEnd)
141
+ .ToList();
142
+
143
+ result["lastPlayWindow"] = new Dictionary<string, object>
144
+ {
145
+ ["startedAt"] = playSession.LastEnteredPlayAtUtc.Value.ToString("o"),
146
+ ["endedAt"] = sessionEnd.ToString("o"),
147
+ ["durationSeconds"] = Math.Max(0d, (sessionEnd - playSession.LastEnteredPlayAtUtc.Value).TotalSeconds),
148
+ ["total"] = sessionLogs.Count,
149
+ ["warnings"] = sessionLogs.Count(entry => entry.Level == "warning"),
150
+ ["errors"] = sessionLogs.Count(entry => entry.Level == "error" || entry.Level == "exception")
151
+ };
152
+ }
153
+
154
+ return result;
155
+ }
156
+ }
157
+
158
+ private static Dictionary<string, object> RecordLog(string level, string message, string stackTrace)
159
+ {
160
+ lock (s_historyLock)
161
+ {
162
+ var entry = new LogRecord
163
+ {
164
+ Id = s_nextId++,
165
+ Level = NormalizeLevel(level),
166
+ Message = message ?? string.Empty,
167
+ StackTrace = stackTrace ?? string.Empty,
168
+ TimestampUtc = DateTime.UtcNow
169
+ };
170
+ entry.Timestamp = entry.TimestampUtc.ToString("o");
171
+
172
+ s_history.Add(entry);
173
+ if (s_history.Count > MaxHistoryEntries)
174
+ s_history.RemoveAt(0);
175
+
176
+ return SerializeFull(entry);
177
+ }
178
+ }
179
+
180
+ private static LogQuery ParseQuery(string paramsJson, bool includePattern)
181
+ {
182
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
183
+ var query = new LogQuery();
184
+
185
+ if (p != null)
186
+ {
187
+ if (p.TryGetValue("level", out var levelObj) && levelObj != null)
188
+ query.Level = NormalizeLevel(levelObj.ToString());
189
+ if (p.TryGetValue("count", out var countObj) && countObj != null)
190
+ query.Count = Math.Max(1, Convert.ToInt32(countObj));
191
+ if (p.TryGetValue("beforeId", out var beforeObj) && beforeObj != null)
192
+ query.BeforeId = Convert.ToInt64(beforeObj);
193
+ if (p.TryGetValue("afterId", out var afterObj) && afterObj != null)
194
+ query.AfterId = Convert.ToInt64(afterObj);
195
+
196
+ if (includePattern && p.TryGetValue("pattern", out var patternObj) && patternObj != null)
197
+ {
198
+ query.Pattern = patternObj.ToString();
199
+ try
200
+ {
201
+ query.Regex = new Regex(query.Pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
202
+ }
203
+ catch (Exception ex)
204
+ {
205
+ throw new ArgumentException($"Invalid regex pattern: {ex.Message}");
206
+ }
207
+ }
208
+ }
209
+
210
+ if (query.Count <= 0)
211
+ query.Count = DefaultSearchWindow;
212
+
213
+ return query;
214
+ }
215
+
216
+ private static LogQueryResult QueryHistory(LogQuery query)
217
+ {
218
+ lock (s_historyLock)
219
+ {
220
+ IEnumerable<LogRecord> candidates = s_history;
221
+
222
+ if (query.BeforeId.HasValue)
223
+ candidates = candidates.Where(entry => entry.Id < query.BeforeId.Value);
224
+ if (query.AfterId.HasValue)
225
+ candidates = candidates.Where(entry => entry.Id > query.AfterId.Value);
226
+ if (!string.IsNullOrEmpty(query.Level))
227
+ candidates = candidates.Where(entry => PassesLevel(entry.Level, query.Level));
228
+
229
+ if (query.Regex != null)
230
+ {
231
+ candidates = candidates.Where(entry =>
232
+ query.Regex.IsMatch(entry.Message)
233
+ || (!string.IsNullOrEmpty(entry.StackTrace) && query.Regex.IsMatch(entry.StackTrace))
234
+ );
235
+ }
236
+
237
+ var allMatches = candidates.OrderByDescending(entry => entry.Id).ToList();
238
+ var returned = allMatches.Take(query.Count).Select(SerializeSummary).ToList();
239
+
240
+ return new LogQueryResult
241
+ {
242
+ Total = allMatches.Count,
243
+ Returned = returned,
244
+ Truncated = allMatches.Count > returned.Count
245
+ };
246
+ }
247
+ }
248
+
249
+ private static Dictionary<string, object> BuildListResult(LogQueryResult queryResult)
250
+ {
251
+ return new Dictionary<string, object>
252
+ {
253
+ ["logs"] = queryResult.Returned.Cast<object>().ToList(),
254
+ ["total"] = queryResult.Total,
255
+ ["returned"] = queryResult.Returned.Count,
256
+ ["truncated"] = queryResult.Truncated
257
+ };
258
+ }
259
+
260
+ private static Dictionary<string, object> SerializeSummary(LogRecord entry)
261
+ {
262
+ return new Dictionary<string, object>
263
+ {
264
+ ["id"] = entry.Id,
265
+ ["level"] = entry.Level,
266
+ ["timestamp"] = entry.Timestamp,
267
+ ["messagePreview"] = Preview(entry.Message, MaxPreviewLength),
268
+ ["hasStackTrace"] = !string.IsNullOrEmpty(entry.StackTrace)
269
+ };
270
+ }
271
+
272
+ private static Dictionary<string, object> SerializeFull(LogRecord entry)
273
+ {
274
+ return new Dictionary<string, object>
275
+ {
276
+ ["id"] = entry.Id,
277
+ ["level"] = entry.Level,
278
+ ["timestamp"] = entry.Timestamp,
279
+ ["message"] = entry.Message,
280
+ ["stackTrace"] = entry.StackTrace
281
+ };
282
+ }
283
+
284
+ private static bool PassesLevel(string value, string threshold)
285
+ {
286
+ return Severity(value) >= Severity(threshold);
287
+ }
288
+
289
+ private static int Severity(string level)
290
+ {
291
+ switch (NormalizeLevel(level))
292
+ {
293
+ case "error":
294
+ case "exception":
295
+ return 2;
296
+ case "warning":
297
+ return 1;
298
+ default:
299
+ return 0;
300
+ }
301
+ }
302
+
303
+ private static string NormalizeLevel(LogType type)
304
+ {
305
+ switch (type)
306
+ {
307
+ case LogType.Error:
308
+ case LogType.Assert:
309
+ return "error";
310
+ case LogType.Exception:
311
+ return "exception";
312
+ case LogType.Warning:
313
+ return "warning";
314
+ default:
315
+ return "info";
316
+ }
317
+ }
318
+
319
+ private static string NormalizeLevel(string level)
320
+ {
321
+ if (string.IsNullOrEmpty(level))
322
+ return "info";
323
+
324
+ var normalized = level.Trim().ToLowerInvariant();
325
+ switch (normalized)
326
+ {
327
+ case "warn":
328
+ return "warning";
329
+ case "err":
330
+ return "error";
331
+ default:
332
+ return normalized;
333
+ }
334
+ }
335
+
336
+ private static string Preview(string value, int maxChars)
337
+ {
338
+ if (string.IsNullOrEmpty(value) || value.Length <= maxChars)
339
+ return value ?? string.Empty;
340
+
341
+ return value.Substring(0, maxChars) + "...";
342
+ }
343
+
344
+ private static string Fingerprint(string message)
345
+ {
346
+ var firstLine = (message ?? string.Empty)
347
+ .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
348
+ .FirstOrDefault() ?? string.Empty;
349
+ var normalized = firstLine.Trim();
350
+ normalized = Regex.Replace(normalized, @"0x[0-9a-fA-F]+", "<hex>");
351
+ normalized = Regex.Replace(normalized, @"\b\d+\b", "<n>");
352
+ normalized = Regex.Replace(normalized, @"\s+", " ");
353
+ return normalized;
354
+ }
355
+
356
+ private static Dictionary<string, object> SerializePlaySession(PlayModeController.SessionSnapshot snapshot)
357
+ {
358
+ var result = new Dictionary<string, object>
359
+ {
360
+ ["playing"] = snapshot.Playing,
361
+ ["paused"] = snapshot.Paused,
362
+ ["willChange"] = snapshot.WillChange,
363
+ ["compiling"] = snapshot.Compiling
364
+ };
365
+
366
+ if (snapshot.LastPlayRequestedAtUtc.HasValue)
367
+ result["lastPlayRequestedAt"] = snapshot.LastPlayRequestedAtUtc.Value.ToString("o");
368
+ if (snapshot.LastEnteredPlayAtUtc.HasValue)
369
+ result["lastEnteredPlayAt"] = snapshot.LastEnteredPlayAtUtc.Value.ToString("o");
370
+ if (snapshot.LastStopRequestedAtUtc.HasValue)
371
+ result["lastStopRequestedAt"] = snapshot.LastStopRequestedAtUtc.Value.ToString("o");
372
+ if (snapshot.LastExitedPlayAtUtc.HasValue)
373
+ result["lastExitedPlayAt"] = snapshot.LastExitedPlayAtUtc.Value.ToString("o");
374
+ if (snapshot.Playing && snapshot.LastEnteredPlayAtUtc.HasValue)
375
+ result["currentPlayDurationSeconds"] = Math.Max(0d, (DateTime.UtcNow - snapshot.LastEnteredPlayAtUtc.Value).TotalSeconds);
376
+ if (snapshot.LastEnteredPlayAtUtc.HasValue && snapshot.LastExitedPlayAtUtc.HasValue)
377
+ result["lastPlayDurationSeconds"] = Math.Max(0d, (snapshot.LastExitedPlayAtUtc.Value - snapshot.LastEnteredPlayAtUtc.Value).TotalSeconds);
378
+
379
+ return result;
380
+ }
381
+
382
+ private sealed class LogRecord
383
+ {
384
+ public long Id;
385
+ public string Level;
386
+ public string Message;
387
+ public string StackTrace;
388
+ public string Timestamp;
389
+ public DateTime TimestampUtc;
390
+ }
391
+
392
+ private sealed class LogQuery
393
+ {
394
+ public string Level;
395
+ public string Pattern;
396
+ public Regex Regex;
397
+ public int Count;
398
+ public long? BeforeId;
399
+ public long? AfterId;
400
+ }
401
+
402
+ private sealed class LogQueryResult
403
+ {
404
+ public int Total;
405
+ public List<Dictionary<string, object>> Returned;
406
+ public bool Truncated;
407
+ }
408
+ }
409
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 76c15fe92f2848f0a69e0b37b4d8c9a1