From 17bbd8946c93b636c37f9ca6539eef1c895f4b56 Mon Sep 17 00:00:00 2001 From: Tim Purdum Date: Thu, 11 Dec 2025 22:01:10 -0600 Subject: [PATCH 1/7] updates --- .../Scripts/geoblazorProto.ts | 431 +++ .../Serialization/JsSyncManager.cs | 519 ++- .../ProtobufSerializationRecords.cs | 2846 +++++++++++++++++ src/dymaptic.GeoBlazor.Core/copyProtobuf.ps1 | 14 + 4 files changed, 3756 insertions(+), 54 deletions(-) create mode 100644 src/dymaptic.GeoBlazor.Core/Scripts/geoblazorProto.ts create mode 100644 src/dymaptic.GeoBlazor.Core/Serialization/ProtobufSerializationRecords.cs create mode 100644 src/dymaptic.GeoBlazor.Core/copyProtobuf.ps1 diff --git a/src/dymaptic.GeoBlazor.Core/Scripts/geoblazorProto.ts b/src/dymaptic.GeoBlazor.Core/Scripts/geoblazorProto.ts new file mode 100644 index 000000000..c708ff541 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Scripts/geoblazorProto.ts @@ -0,0 +1,431 @@ +export let protoTypeDefinitions: string = ` +syntax = "proto3"; +package dymaptic.GeoBlazor.Core.Serialization; +import "google/protobuf/empty.proto"; + +message ActionBase { + string type = 1; + string title = 2; + string className = 3; + bool active = 4; + bool disabled = 5; + bool visible = 6; + string id = 7; + string image = 8; + bool value = 9; + string actionId = 10; + string test = 11; + bool isNull = 1000; +} +message ActionBaseCollection { + repeated ActionBase items = 1; + bool isNull = 1000; +} +message Attribute { + string key = 1; + string value = 2; + string valueType = 3; + bool isNull = 1000; +} +message AttributeCollection { + repeated Attribute items = 1; + bool isNull = 1000; +} +message ChartMediaInfoValueSeries { + string fieldName = 1; + string tooltip = 2; + double value = 3; + string id = 4; + bool isNull = 1000; +} +message ChartMediaInfoValueSeriesCollection { + repeated ChartMediaInfoValueSeries items = 1; + bool isNull = 1000; +} +message ElementExpressionInfo { + string expression = 1; + string title = 2; + bool isNull = 1000; +} +message ElementExpressionInfoCollection { + repeated ElementExpressionInfo items = 1; + bool isNull = 1000; +} +message FieldInfo { + string fieldName = 1; + string label = 2; + string tooltip = 3; + string stringFieldOption = 4; + FieldInfoFormat format = 5; + bool isEditable = 6; + bool visible = 7; + string id = 8; + bool isNull = 1000; +} +message FieldInfoCollection { + repeated FieldInfo items = 1; + bool isNull = 1000; +} +message FieldInfoFormat { + int32 places = 1; + bool digitSeparator = 2; + string dateFormat = 3; + string id = 4; + bool isNull = 1000; +} +message FieldInfoFormatCollection { + repeated FieldInfoFormat items = 1; + bool isNull = 1000; +} +message Geometry { + string type = 1; + Geometry extent = 2; + SpatialReference spatialReference = 3; + double longitude = 4; + double latitude = 5; + double x = 6; + double y = 7; + double z = 8; + repeated MapPath paths = 9; + repeated MapPath rings = 10; + double xmax = 11; + double xmin = 12; + double ymax = 13; + double ymin = 14; + double zmax = 15; + double zmin = 16; + double mmax = 17; + double mmin = 18; + bool hasM = 19; + bool hasZ = 20; + double m = 21; + Geometry centroid = 22; + bool isSelfIntersecting = 23; + Geometry center = 24; + bool geodesic = 25; + int32 numberOfPoints = 26; + double radius = 27; + string radiusUnit = 28; + string id = 29; + repeated MapPoint points = 30; + bool isSimple = 31; + repeated MeshComponent components = 32; + MeshTransform transform = 33; + MeshVertexAttributes vertexAttributes = 34; + MeshVertexSpace vertexSpace = 35; + bool isNull = 1000; +} +message GeometryCollection { + repeated Geometry items = 1; + bool isNull = 1000; +} +message Graphic { + string id = 1; + Geometry geometry = 2; + Symbol symbol = 3; + PopupTemplate popupTemplate = 4; + repeated Attribute attributes = 5; + bool visible = 6; + string aggregateGeometries = 7; + GraphicOrigin origin = 8; + string layerId = 9; + string viewId = 10; + repeated Attribute stackedAttributes = 11; + bool isNull = 1000; +} +message GraphicCollection { + repeated Graphic items = 1; + bool isNull = 1000; +} +message GraphicOrigin { + string layerId = 1; + string arcGISLayerId = 2; + int32 layerIndex = 3; + bool isNull = 1000; +} +message GraphicOriginCollection { + repeated GraphicOrigin items = 1; + bool isNull = 1000; +} +message ImageData { + bytes data = 1; + string colorSpace = 2; + int64 height = 3; + int64 width = 4; + bool isNull = 1000; +} +message ImageDataCollection { + bool isNull = 1000; +} +message MapColor { + repeated double rgbaValues = 1; + string hexOrNameValue = 2; + bool isNull = 1000; +} +message MapColorCollection { + bool isNull = 1000; +} +message MapFont { + double size = 1; + string family = 2; + string fontStyle = 3; + string weight = 4; + string decoration = 5; + string id = 6; + bool isNull = 1000; +} +message MapFontCollection { + repeated MapFont items = 1; + bool isNull = 1000; +} +message MapPath { + repeated MapPoint points = 1; + bool isNull = 1000; +} +message MapPathCollection { + repeated MapPath items = 1; + bool isNull = 1000; +} +message MapPoint { + repeated double coordinates = 1; + bool isNull = 1000; +} +message MapPointCollection { + repeated MapPoint items = 1; + bool isNull = 1000; +} +message MediaInfo { + string type = 1; + string altText = 2; + string caption = 3; + string title = 4; + MediaInfoValue value = 5; + double refreshInterval = 6; + string id = 7; + bool isNull = 1000; +} +message MediaInfoCollection { + repeated MediaInfo items = 1; + bool isNull = 1000; +} +message MediaInfoValue { + repeated string fields = 1; + string normalizeField = 2; + string tooltipField = 3; + repeated ChartMediaInfoValueSeries series = 4; + string linkURL = 5; + string sourceURL = 6; + string id = 7; + bool isNull = 1000; +} +message MediaInfoValueCollection { + repeated MediaInfoValue items = 1; + bool isNull = 1000; +} +message MeshComponent { + bytes faces = 1; + MeshComponentMaterial material = 2; + string name = 3; + string shading = 4; + bool isNull = 1000; +} +message MeshComponentCollection { + repeated MeshComponent items = 1; + bool isNull = 1000; +} +message MeshComponentMaterial { + double alphaCutoff = 1; + string alphaMode = 2; + MapColor color = 3; + MeshTexture colorTexture = 4; + MeshTextureTransform colorTextureTransform = 5; + bool doubleSided = 6; + MeshTexture normalTexture = 7; + MeshTextureTransform normalTextureTransform = 8; + MapColor emissiveColor = 9; + MeshTexture emissiveTexture = 10; + MeshTextureTransform emissiveTextureTransform = 11; + double metallic = 12; + MeshTexture metallicRoughnessTexture = 13; + MeshTexture occlusionTexture = 14; + MeshTextureTransform occlusionTextureTransform = 15; + double roughness = 16; + bool isNull = 1000; +} +message MeshComponentMaterialCollection { + repeated MeshComponentMaterial items = 1; + bool isNull = 1000; +} +message MeshTexture { + ImageData imageData = 1; + repeated string wrap = 2; + bool transparent = 3; + string url = 4; + bool isNull = 1000; +} +message MeshTextureCollection { + repeated MeshTexture items = 1; + bool isNull = 1000; +} +message MeshTextureTransform { + repeated double offset = 1; + double rotation = 2; + repeated double scale = 3; + bool isNull = 1000; +} +message MeshTextureTransformCollection { + repeated MeshTextureTransform items = 1; + bool isNull = 1000; +} +message MeshTransform { + double rotationAngle = 1; + repeated double rotationAxis = 2; + repeated double scale = 3; + repeated double translation = 4; + bool isNull = 1000; +} +message MeshTransformCollection { + repeated MeshTransform items = 1; + bool isNull = 1000; +} +message MeshVertexAttributes { + bytes color = 1; + repeated double normal = 2; + repeated double position = 3; + repeated double tangent = 4; + repeated double uv = 5; + bool isNull = 1000; +} +message MeshVertexAttributesCollection { + repeated MeshVertexAttributes items = 1; + bool isNull = 1000; +} +message MeshVertexSpace { + string type = 1; + repeated double origin = 2; + bool isNull = 1000; +} +message MeshVertexSpaceCollection { + repeated MeshVertexSpace items = 1; + bool isNull = 1000; +} +message PopupContent { + string type = 1; + string description = 2; + string displayType = 3; + string title = 4; + ElementExpressionInfo expressionInfo = 5; + repeated FieldInfo fieldInfos = 6; + int32 activeMediaInfoIndex = 7; + repeated MediaInfo mediaInfos = 8; + int32 displayCount = 9; + repeated RelatedRecordsInfoFieldOrder orderByFields = 10; + int64 relationshipId = 11; + string text = 12; + string id = 13; + repeated string outFields = 14; + bool isNull = 1000; +} +message PopupContentCollection { + repeated PopupContent items = 1; + bool isNull = 1000; +} +message PopupExpressionInfo { + string expression = 1; + string name = 2; + string title = 3; + string returnType = 4; + string id = 5; + bool isNull = 1000; +} +message PopupExpressionInfoCollection { + repeated PopupExpressionInfo items = 1; + bool isNull = 1000; +} +message PopupTemplate { + string title = 1; + string stringContent = 2; + repeated string outFields = 3; + repeated FieldInfo fieldInfos = 4; + repeated PopupContent content = 5; + repeated PopupExpressionInfo expressionInfos = 6; + bool overwriteActions = 7; + bool returnGeometry = 8; + repeated ActionBase actions = 9; + string id = 10; + bool isNull = 1000; +} +message PopupTemplateCollection { + repeated PopupTemplate items = 1; + bool isNull = 1000; +} +message RelatedRecordsInfoFieldOrder { + bool isNull = 1000; +} +message RelatedRecordsInfoFieldOrderCollection { + repeated RelatedRecordsInfoFieldOrder items = 1; + bool isNull = 1000; +} +message SpatialReference { + int32 wkid = 1; + string wkt = 2; + string wkt2 = 3; + bool isNull = 1000; +} +message SpatialReferenceCollection { + repeated SpatialReference items = 1; + bool isNull = 1000; +} +message Symbol { + string type = 1; + MapColor color = 2; + Symbol outline = 3; + double size = 4; + string style = 5; + double angle = 6; + double xoffset = 7; + double yoffset = 8; + double width = 9; + string lineStyle = 10; + string text = 11; + MapColor haloColor = 12; + double haloSize = 13; + MapFont font = 14; + double height = 15; + string url = 16; + MapColor backgroundColor = 17; + double borderLineSize = 18; + MapColor borderLineColor = 19; + string horizontalAlignment = 20; + bool kerning = 21; + double lineHeight = 22; + double lineWidth = 23; + bool rotated = 24; + string verticalAlignment = 25; + double xScale = 26; + double yScale = 27; + string id = 28; + string name = 29; + string portalUrl = 30; + string styleName = 31; + string styleUrl = 32; + bool isNull = 1000; +} +message SymbolCollection { + repeated Symbol items = 1; + bool isNull = 1000; +} +message ViewHit { + string type = 1; + Geometry mapPoint = 2; + Graphic graphic = 3; + string layerId = 4; + double distance = 5; + bool isNull = 1000; +} +message ViewHitCollection { + repeated ViewHit items = 1; + bool isNull = 1000; +} + +`; diff --git a/src/dymaptic.GeoBlazor.Core/Serialization/JsSyncManager.cs b/src/dymaptic.GeoBlazor.Core/Serialization/JsSyncManager.cs index b7856f288..27ca00d0e 100644 --- a/src/dymaptic.GeoBlazor.Core/Serialization/JsSyncManager.cs +++ b/src/dymaptic.GeoBlazor.Core/Serialization/JsSyncManager.cs @@ -1,46 +1,19 @@ -using Microsoft.JSInterop; using ProtoBuf.Meta; using System.Runtime.CompilerServices; + namespace dymaptic.GeoBlazor.Core.Serialization; -/// -/// Manages JavaScript interop with support for Protobuf serialization and streaming. -/// -/// -/// This is the infrastructure class for the Protobuf serialization system. -/// The full implementation with serialization records will be added in a subsequent PR. -/// public static class JsSyncManager { - /// - /// Dictionary of serializable methods keyed by class name. - /// public static Dictionary SerializableMethods { get; set; } = []; - /// - /// Dictionary mapping source types to their Protobuf contract types. - /// public static Dictionary ProtoContractTypes { get; set; } = []; - /// - /// Dictionary mapping collection item types to their Protobuf collection types. - /// public static Dictionary ProtoCollectionTypes { get; set; } = []; - private static Dictionary>? _serializableMethods; - - /// - /// Initializes the JsSyncManager with Protobuf type registrations. - /// - /// - /// This method should be called once at application startup to register all - /// protobuf types with the RuntimeTypeModel and compile the serialization model. - /// public static void Initialize() { - // TODO: ProtoContractTypes and SerializableMethods dictionaries will be populated - // by generated code from ProtobufSourceGenerator in a subsequent PR. foreach (Type protoType in ProtoContractTypes.Values) { RuntimeTypeModel.Default.Add(protoType, true); @@ -53,43 +26,481 @@ public static void Initialize() } /// - /// Wrapper method to invoke a void JS function with serialization support. + /// Wrapper method to invoke a void JS function. /// - /// The IJSObjectReference to invoke the method on. - /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode. - /// The name of the JS function to call. - /// The name of the calling class. - /// A CancellationToken to cancel an asynchronous operation. - /// The collection of parameters to pass to the JS call. + /// + /// The to invoke the method on. + /// + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode + /// + /// + /// The name of the JS function to call. + /// + /// + /// The name of the calling class. + /// + /// + /// A CancellationToken to cancel an asynchronous operation. + /// + /// + /// The collection of parameters to pass to the JS call. + /// public static async Task InvokeVoidJsMethod(this IJSObjectReference js, bool isServer, - [CallerMemberName] string method = "", string className = "", + [CallerMemberName]string method = "", string className = "", CancellationToken cancellationToken = default, params object?[] parameters) { - // TODO: Implement protobuf serialization for Blazor Server mode. - // When isServer is true and the method/parameters support protobuf serialization, - // this should serialize parameters to binary format for more efficient transfer. - await js.InvokeVoidAsync(method, cancellationToken, parameters); + SerializableMethodRecord methodRecord = GetMethodRecord(method, className, true, parameters); + List parameterList = GenerateSerializedParameters(methodRecord, parameters, isServer); + + await js.InvokeVoidAsync("invokeVoidSerializedMethod", cancellationToken, + [methodRecord.MethodName, isServer, ..parameterList]); } /// - /// Wrapper method to invoke a JS function that returns a value with serialization support. + /// Wrapper method to invoke a JS function that returns a value. /// - /// The expected return type. - /// The IJSObjectReference to invoke the method on. - /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode. - /// The name of the JS function to call. - /// The name of the calling class. - /// A CancellationToken to cancel an asynchronous operation. - /// The collection of parameters to pass to the JS call. - /// The result of the JS call. + /// + /// The to invoke the method on. + /// + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode + /// + /// + /// The name of the JS function to call. + /// + /// + /// The name of the calling class. + /// + /// + /// A CancellationToken to cancel an asynchronous operation. + /// + /// + /// The collection of parameters to pass to the JS call. + /// public static async Task InvokeJsMethod(this IJSObjectReference js, bool isServer, - [CallerMemberName] string method = "", string className = "", + [CallerMemberName]string method = "", string className = "", CancellationToken cancellationToken = default, params object?[] parameters) { - // TODO: Implement protobuf deserialization for Blazor Server mode. - // When isServer is true and the return type supports protobuf serialization, - // this should deserialize the binary response for more efficient transfer. - return await js.InvokeAsync(method, cancellationToken, parameters); + SerializableMethodRecord methodRecord = GetMethodRecord(method, className, false, parameters); + + List parameterList = GenerateSerializedParameters(methodRecord, parameters, isServer); + + Type? returnType = methodRecord.ReturnValue?.Type; + bool returnTypeIsProtobuf = returnType is not null && ProtoContractTypes.ContainsKey(returnType); + + if (isServer || returnTypeIsProtobuf || returnType?.IsAssignableTo(typeof(Stream)) == true) + { + string? protoReturnTypeName = null; + if (returnTypeIsProtobuf) + { + Type? protoReturnType; + if (methodRecord.ReturnValue!.SingleType is not null) + { + ProtoCollectionTypes.TryGetValue(methodRecord.ReturnValue.SingleType, + out protoReturnType); + } + else + { + ProtoContractTypes.TryGetValue(returnType!, out protoReturnType); + } + + protoReturnTypeName = protoReturnType?.Name.Replace("SerializationRecord", ""); + } + + IJSStreamReference? streamRef = await js.InvokeAsync( + "invokeSerializedMethod", cancellationToken, + [methodRecord.MethodName, true, returnTypeIsProtobuf, protoReturnTypeName, ..parameterList]); + + if (streamRef is null) + { + return default!; + } + + if (returnTypeIsProtobuf) + { + if (methodRecord.ReturnValue?.SingleType is not null) + { + return await streamRef.ReadJsStreamReferenceAsProtobufCollection(methodRecord.ReturnValue.SingleType) ?? default!; + } + return await streamRef.ReadJsStreamReferenceAsProtobuf(returnType!) ?? default!; + } + + if (returnType?.IsAssignableTo(typeof(Stream)) == true) + { + Stream? result = await streamRef.ReadJsStreamReferenceAsStream(); + + if (result is null) + { + return default!; + } + + // double-cast to force to generic + return (T)(object)result; + } + + return (await streamRef.ReadJsStreamReferenceAsJSON())!; + } + + return await js.InvokeAsync( + "invokeSerializedMethod", cancellationToken, [methodRecord.MethodName, false, false, null, ..parameterList]); } + + private static SerializableMethodRecord GetMethodRecord(string method, string className, bool returnsVoid, + object?[] providedParameters) + { + if (!_serializableMethods.TryGetValue(className, out List? classMethods)) + { + classMethods = new List(); + _serializableMethods[className] = classMethods; + } + + if (classMethods.Where(m => + // same method name + string.Equals(m.MethodName, method, StringComparison.OrdinalIgnoreCase) + // same number of parameters + && m.Parameters.Length == providedParameters.Length + // either both void or both non-void + && ((m.ReturnValue is null && returnsVoid) + || (m.ReturnValue is not null && !returnsVoid))).ToList() + is not { } matchedMethods) + { + // use reflection since we don't have a stored method record + var classType = GeoBlazorMetaData.GeoblazorTypes.First(t => t.Name == className); + var methodInfos = classType.GetMethods(BindingFlags.Instance | BindingFlags.Public) + .Where(m => string.Equals(m.Name, method, StringComparison.OrdinalIgnoreCase) + && m.GetParameters().Length == providedParameters.Length) + .ToArray(); + + matchedMethods = []; + + foreach (MethodInfo methodInfo in methodInfos) + { + List methodParams = []; + var paramInfos = methodInfo.GetParameters(); + + foreach (ParameterInfo paramInfo in paramInfos) + { + NullabilityInfo nullabilityInfo = nullabilityContext.Create(paramInfo); + bool isNullable = nullabilityInfo.ReadState == NullabilityState.Nullable; + Type paramType = paramInfo.ParameterType.IsGenericType && + paramInfo.ParameterType.GetGenericTypeDefinition() == typeof(Nullable<>) + ? Nullable.GetUnderlyingType(paramInfo.ParameterType)! + : paramInfo.ParameterType; + Type? collectionType = paramType.IsArray + ? paramType.GetElementType() + : paramType is { IsGenericType: true, GenericTypeArguments.Length: 1 } + ? paramType.GenericTypeArguments[0] + : null; + methodParams.Add(new SerializableParameterRecord(paramType, isNullable, collectionType)); + } + + SerializableParameterRecord? returnRecord = null; + + if (!returnsVoid && methodInfo.ReturnType != typeof(void)) + { + ParameterInfo returnParamInfo = methodInfo.ReturnParameter; + Type returnType = returnParamInfo.ParameterType; + + if (returnType.Name.StartsWith("Task") || returnType.Name.StartsWith("ValueTask")) + { + returnType = returnType.IsGenericType + ? returnType.GenericTypeArguments[0] + : typeof(void); + } + + bool isNullable = false; + + if (returnType.IsGenericType && + methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + isNullable = true; + returnType = Nullable.GetUnderlyingType(returnType)!; + } + + bool returnIsCollection = returnType.IsArray || + returnType is { IsGenericType: true, GenericTypeArguments.Length: 1 }; + + Type? singleType = null; + + if (returnIsCollection) + { + singleType = returnType.IsArray + ? returnType.GetElementType() + : returnType.GenericTypeArguments[0]; + } + + bool isGenericParameter = returnType.IsGenericParameter; + + if (isGenericParameter) + { + returnType = returnType.GenericTypeArguments[0]; + } + + returnRecord = new SerializableParameterRecord(returnType, isNullable, singleType); + } + + SerializableMethodRecord methodRecord = new(method.ToLowerFirstChar(), methodParams.ToArray(), returnRecord); + matchedMethods.Add(methodRecord); + + if (methodRecord.ReturnValue?.Type.IsGenericType != true) + { + // only add non-generic return typed methods to the dictionary + classMethods.Add(methodRecord); + } + } + } + + if (matchedMethods.Count == 0) + { + // no matching methods, build the record manually + return new SerializableMethodRecord(method.ToLowerFirstChar(), + providedParameters.Select(GetSerializableParameterRecord).ToArray(), + GetSerializableReturnRecord(returnsVoid)); + } + + if (matchedMethods.Count == 1) + { + return matchedMethods[0]; + } + + Type requestedReturnType = typeof(T); + + // find record with potentially matching parameter types including nulls + return matchedMethods.First(m => + { + for (int i = 0; i < m.Parameters.Length; i++) + { + Type? providedParameterType = providedParameters[i]?.GetType(); + if (providedParameterType is not null && + providedParameterType.IsGenericType && + providedParameterType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + providedParameterType = Nullable.GetUnderlyingType(providedParameterType)!; + } + + SerializableParameterRecord methodParam = m.Parameters[i]; + + if (providedParameterType is null) + { + if (!methodParam.IsNullable) + { + return false; + } + } + else if (!providedParameterType.IsAssignableTo(methodParam.Type)) + { + return false; + } + } + + if (!returnsVoid && requestedReturnType != m.ReturnValue?.Type) + { + return false; + } + + return true; + }); + } + + private static List GenerateSerializedParameters(SerializableMethodRecord methodRecord, + object?[] parameters, bool isServer) + { + List serializedParameters = []; + for (int i = 0; i < parameters.Length; i++) + { + object? parameterValue = parameters[i]; + SerializableParameterRecord parameterRecord = methodRecord.Parameters[i]; + serializedParameters.AddRange(ProcessParameter(parameterValue, parameterRecord, isServer)); + } + return serializedParameters; + } + + /// + /// Returns the processed parameter Type and a Serialized or DotNetStreamReference of the serialized parameter value. + /// + /// + /// The original parameter to process. + /// + /// + /// The SerializableParameterRecord for the parameter. + /// + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode + /// + private static object?[] ProcessParameter(object? parameterValue, SerializableParameterRecord parameterRecord, + bool isServer) + { + if (parameterValue is null) + { + return ["null", null]; + } + + Type paramType = parameterRecord.Type; + + if (simpleTypes.Contains(paramType) || paramType.IsPrimitive) + { + return [GetKey(paramType), parameterValue]; + } + + if (paramType.IsAssignableTo(typeof(IJSObjectReference))) + { + return ["JsObject", parameterValue]; + } + + if (paramType.IsEnum) + { + // use the JsonConverter defined EnumToKebabCaseConverters to serialize enums as strings + string stringValue = JsonSerializer.Serialize(parameterValue, GeoBlazorSerialization.JsonSerializerOptions); + // pass as type string so JS can parse correctly + return [nameof(String), stringValue]; + } + + if (paramType.IsGenericType && paramType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + Type underlyingType = Nullable.GetUnderlyingType(paramType)!; + object underlyingValue = Convert.ChangeType(parameterValue, underlyingType); + return ProcessParameter(underlyingValue, parameterRecord with { Type = underlyingType, IsNullable = true }, isServer); + } + + if (parameterValue is IList list && paramType != typeof(MapPath) && paramType != typeof(MapPoint)) + { + Type genericType = parameterRecord.SingleType ?? (paramType.IsArray + ? paramType.GetElementType()! + : paramType.GenericTypeArguments[0]); + string key = $"{GetKey(genericType)}Collection"; + + if (ProtoContractTypes.ContainsKey(genericType)) + { + object protobufParameter = list.ToProtobufCollectionParameter(genericType, isServer); + return [key, protobufParameter]; + } + + return [key, parameterValue.ToJsonParameter(isServer)]; + } + + if (ProtoContractTypes.ContainsKey(paramType)) + { + object protobufParameter = parameterValue.ToProtobufParameter(paramType, isServer); + return [GetKey(paramType), protobufParameter]; + } + + if (parameterValue is AttributesDictionary attributesDictionary) + { + AttributeSerializationRecord[] serializedItems = attributesDictionary.ToProtobufArray(); + AttributeCollectionSerializationRecord collection = new(serializedItems); + MemoryStream memoryStream = new(); + Serializer.Serialize(memoryStream, collection); + memoryStream.Seek(0, SeekOrigin.Begin); + + if (isServer) + { + return [nameof(AttributesDictionary), new DotNetStreamReference(memoryStream)]; + } + + byte[] data = memoryStream.ToArray(); + memoryStream.Dispose(); + return [nameof(AttributesDictionary), data]; + } + + return [GetKey(paramType), parameterValue.ToJsonParameter(isServer)]; + } + + private static object ToJsonParameter(this T obj, bool isServer) + { + if (isServer) + { + MemoryStream memoryStream = new(); + JsonSerializer.Serialize(memoryStream, obj, GeoBlazorSerialization.JsonSerializerOptions); + memoryStream.Seek(0, SeekOrigin.Begin); + return new DotNetStreamReference(memoryStream); + } + + return JsonSerializer.Serialize(obj, GeoBlazorSerialization.JsonSerializerOptions); + } + + private static string GetKey(Type type) + { + Type? matchedType = ProtoContractTypes.Keys.FirstOrDefault(t => t == type); + + if (matchedType is not null) + { + return ProtoContractTypes[type].GetCustomAttribute()!.Name; + } + + return type.Name; + } + + private static SerializableParameterRecord GetSerializableParameterRecord(object? parameter) + { + if (parameter is null) + { + return new SerializableParameterRecord(typeof(object), true, null); + } + + Type paramType = parameter.GetType(); + + if (simpleTypes.Contains(paramType)) + { + return new SerializableParameterRecord(paramType, true, null); + } + + if (paramType.Name.Contains("AnonymousType")) + { + // anonymous object + return new SerializableParameterRecord(typeof(object), true, null); + } + + bool isCollection = paramType.IsAssignableTo(typeof(IEnumerable)); + Type? collectionType = isCollection + ? paramType.IsArray + ? paramType.GetElementType() + : paramType.GetGenericArguments()[0] + : null; + return new SerializableParameterRecord(paramType, true, collectionType); + } + + private static SerializableParameterRecord GetSerializableReturnRecord(bool returnsVoid) + { + if (returnsVoid) + { + return new SerializableParameterRecord(typeof(void), false, null); + } + Type returnType = typeof(T); + + if (simpleTypes.Contains(returnType)) + { + return new SerializableParameterRecord(returnType, true, null); + } + + if (returnType == typeof(AttributesDictionary)) + { + return new SerializableParameterRecord(typeof(AttributesDictionary), true, + typeof(AttributeSerializationRecord)); + } + bool isCollection = returnType.IsAssignableTo(typeof(IEnumerable)) + && !returnType.IsAssignableTo(typeof(IDictionary)); + Type? collectionType = isCollection + ? returnType.IsArray + ? returnType.GetElementType() + : returnType.GetGenericArguments()[0] + : null; + return new SerializableParameterRecord(returnType, true, collectionType); + } + + private static Dictionary> _serializableMethods = []; + private static readonly NullabilityInfoContext nullabilityContext = new(); + + private static readonly Type[] simpleTypes = + [ + typeof(string), typeof(char), typeof(bool), typeof(byte), typeof(sbyte), typeof(short), + typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), + typeof(double), typeof(decimal), typeof(DateTime), typeof(DateTimeOffset), typeof(TimeSpan), + typeof(Guid), typeof(DateOnly), typeof(TimeOnly) + ]; } + +public record SerializableMethodRecord(string MethodName, SerializableParameterRecord[] Parameters, + SerializableParameterRecord? ReturnValue); +public record SerializableParameterRecord(Type Type, bool IsNullable, Type? SingleType); diff --git a/src/dymaptic.GeoBlazor.Core/Serialization/ProtobufSerializationRecords.cs b/src/dymaptic.GeoBlazor.Core/Serialization/ProtobufSerializationRecords.cs new file mode 100644 index 000000000..aa1c502ae --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Serialization/ProtobufSerializationRecords.cs @@ -0,0 +1,2846 @@ +using FieldInfo = dymaptic.GeoBlazor.Core.Components.FieldInfo; + + +namespace dymaptic.GeoBlazor.Core.Serialization; + +/// +/// Base class for all Protobuf serialization records for MapComponents. +/// +[ProtoContract(Name = "MapComponent")] +public abstract record MapComponentSerializationRecord +{ + [ProtoMember(1000)] + public abstract bool IsNull { get; init; } +} + +public abstract record MapComponentSerializationRecord : MapComponentSerializationRecord +{ + public abstract T? FromSerializationRecord(); +} + +[ProtoContract(Name = "MapComponentCollection")] +public abstract record MapComponentBaseCollectionSerializationRecord +{ + [ProtoMember(1000)] + public abstract bool IsNull { get; init; } +} + +public abstract record MapComponentCollectionSerializationRecord : MapComponentBaseCollectionSerializationRecord + where TItem : MapComponentSerializationRecord +{ + public abstract TItem[]? Items { get; set; } +} + +[ProtoContract(Name = "Geometry")] +public record GeometrySerializationRecord : MapComponentSerializationRecord +{ + public GeometrySerializationRecord() + { + } + + public GeometrySerializationRecord(string Id, string Type, GeometrySerializationRecord? Extent, + SpatialReferenceSerializationRecord? SpatialReference) + { + this.Id = Id; + this.Type = Type; + this.Extent = Extent; + this.SpatialReference = SpatialReference; + } + + [ProtoMember(1)] + public string Type { get; set; } = string.Empty; + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public GeometrySerializationRecord? Extent { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public SpatialReferenceSerializationRecord? SpatialReference { get; set; } + + [ProtoMember(4)] + public double? Longitude { get; set; } + + [ProtoMember(5)] + public double? Latitude { get; set; } + + [ProtoMember(6)] + public double? X { get; set; } + + [ProtoMember(7)] + public double? Y { get; set; } + + [ProtoMember(8)] + public double? Z { get; set; } + + [ProtoMember(9)] + public MapPathSerializationRecord[]? Paths { get; set; } + + [ProtoMember(10)] + public MapPathSerializationRecord[]? Rings { get; set; } + + [ProtoMember(11)] + public double? Xmax { get; set; } + + [ProtoMember(12)] + public double? Xmin { get; set; } + + [ProtoMember(13)] + public double? Ymax { get; set; } + + [ProtoMember(14)] + public double? Ymin { get; set; } + + [ProtoMember(15)] + public double? Zmax { get; set; } + + [ProtoMember(16)] + public double? Zmin { get; set; } + + [ProtoMember(17)] + public double? Mmax { get; set; } + + [ProtoMember(18)] + public double? Mmin { get; set; } + + [ProtoMember(19)] + public bool? HasM { get; set; } + + [ProtoMember(20)] + public bool? HasZ { get; set; } + + [ProtoMember(21)] + public double? M { get; set; } + + [ProtoMember(22)] + public GeometrySerializationRecord? Centroid { get; set; } + + [ProtoMember(23)] + public bool? IsSelfIntersecting { get; set; } + + [ProtoMember(24)] + public GeometrySerializationRecord? Center { get; set; } + + [ProtoMember(25)] + public bool? Geodesic { get; set; } + + [ProtoMember(26)] + public int? NumberOfPoints { get; set; } + + [ProtoMember(27)] + public double? Radius { get; set; } + + [ProtoMember(28)] + public string? RadiusUnit { get; set; } + + [ProtoMember(29)] + public string? Id { get; set; } + + /// + /// Multipoint geometry points. + /// + [ProtoMember(30)] + public MapPointSerializationRecord[]? Points { get; set; } + + [ProtoMember(31)] + public bool? IsSimple { get; set; } + + [ProtoMember(32)] + public MeshComponentSerializationRecord[]? Components { get; set; } + + [ProtoMember(33)] + public MeshTransformSerializationRecord? Transform { get; set; } + + [ProtoMember(34)] + public MeshVertexAttributesSerializationRecord? VertexAttributes { get; set; } + + [ProtoMember(35)] + public MeshVertexSpaceSerializationRecord? VertexSpace { get; set; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override Geometry? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var extent = Extent?.FromSerializationRecord() as Extent; + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guidId)) + { + id = guidId; + } + + switch (Type) + { + case "point": + return new Point(Longitude, Latitude, X, Y, Z, SpatialReference?.FromSerializationRecord(), HasM, HasZ, + M) { Extent = extent, Id = id }; + case "polyline": + var paths = Paths?.Any(p => !p.IsNull) == true + ? Paths.Select(x => x.FromSerializationRecord()!).ToArray() + : null; + + if (paths is null) + { + return null; + } + + return new Polyline(paths, + SpatialReference?.FromSerializationRecord(), HasM, HasZ) + { + Extent = extent, Id = id, IsSimple = IsSimple + }; + case "polygon": + var rings = Rings?.Any(p => !p.IsNull) == true + ? Rings.Select(x => x.FromSerializationRecord()!).ToArray() + : null; + + if (rings is null) + { + return null; + } + + return Center is not null && Radius is not null && !Center.IsNull + ? new Circle((Point)Center.FromSerializationRecord()!, Radius.Value, + Centroid?.FromSerializationRecord() as Point, Geodesic, HasM, HasZ, NumberOfPoints, + RadiusUnit is null ? null : Enum.Parse(RadiusUnit), rings, + SpatialReference?.FromSerializationRecord()) { Extent = extent, Id = id, IsSimple = IsSimple } + : new Polygon(rings, + SpatialReference?.FromSerializationRecord(), Centroid?.FromSerializationRecord() as Point, HasM, + HasZ) { Extent = extent, Id = id, IsSimple = IsSimple }; + case "extent": + return new Extent(Xmax!.Value, Xmin!.Value, Ymax!.Value, Ymin!.Value, Zmax, Zmin, Mmax, Mmin, + SpatialReference?.FromSerializationRecord(), HasM, HasZ) { Id = id, IsSimple = IsSimple }; + case "multipoint": + // Multipoint is in GeoBlazor Pro assembly, so we need to use reflection to get the type + var multipointType = System.Type.GetType("dymaptic.GeoBlazor.Pro.Components.Geometries.Multipoint, " + + "dymaptic.GeoBlazor.Pro"); + + if (multipointType is not null && multipointType.IsSubclassOf(typeof(Geometry))) + { + var points = Points?.Any(p => !p.IsNull) == true + ? Points?.Select(p => + { + var mp = p.FromSerializationRecord()!; + + return new Point(x: mp[0], y: mp[1]); + }) + .ToArray() + : null; + + if (Activator.CreateInstance(multipointType, HasM, HasZ, points, + SpatialReference?.FromSerializationRecord()) + is Geometry multipoint) + { + multipoint.Extent = extent; + multipoint.Id = id; + multipoint.IsSimple = IsSimple; + + return multipoint; + } + } + + throw new InvalidOperationException( + "Multipoint could not be created. Ensure the type is correct and the assembly is loaded."); + case "mesh": + // Mesh is in GeoBlazor Pro assembly, so we need to use reflection to get the type + var meshType = System.Type.GetType("dymaptic.GeoBlazor.Pro.Components.Geometries.Mesh, " + + "dymaptic.GeoBlazor.Pro"); + + if (meshType is not null + && meshType.IsSubclassOf(typeof(Geometry)) + && Activator.CreateInstance(meshType, + Components?.Select(c => c.FromSerializationRecord()).ToArray(), + HasM, HasZ, + SpatialReference?.FromSerializationRecord(), + Transform?.FromSerializationRecord(), + VertexAttributes?.FromSerializationRecord(), + VertexSpace?.FromSerializationRecord()) + is Geometry mesh) + { + mesh.Extent = extent; + mesh.Id = id; + mesh.IsSimple = IsSimple; + + return mesh; + } + + throw new InvalidOperationException( + "Mesh could not be created. Ensure the type is correct and the assembly is loaded."); + default: + throw new ArgumentOutOfRangeException(); + } + } +} + +[ProtoContract(Name = "GeometryCollection")] +internal record + GeometryCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public GeometryCollectionSerializationRecord() + { + } + + public GeometryCollectionSerializationRecord(GeometrySerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override GeometrySerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "PopupContent")] +public record PopupContentSerializationRecord : MapComponentSerializationRecord +{ + public PopupContentSerializationRecord() + { + } + + public PopupContentSerializationRecord(string Id, string Type) + { + this.Type = Type; + this.Id = Id; + } + + [ProtoMember(1)] + public string Type { get; init; } = string.Empty; + + [ProtoMember(2)] + public string? Description { get; init; } + + [ProtoMember(3)] + public string? DisplayType { get; init; } + + [ProtoMember(4)] + public string? Title { get; init; } + + [ProtoMember(5)] + public ElementExpressionInfoSerializationRecord? ExpressionInfo { get; init; } + + [ProtoMember(6)] + public FieldInfoSerializationRecord[]? FieldInfos { get; init; } + + [ProtoMember(7)] + public int? ActiveMediaInfoIndex { get; init; } + + [ProtoMember(8)] + public MediaInfoSerializationRecord[]? MediaInfos { get; init; } + + [ProtoMember(9)] + public int? DisplayCount { get; init; } + + [ProtoMember(10)] + public RelatedRecordsInfoFieldOrderSerializationRecord[]? OrderByFields { get; init; } + + [ProtoMember(11)] + public long? RelationshipId { get; init; } + + [ProtoMember(12)] + public string? Text { get; init; } + + [ProtoMember(13)] + public string? Id { get; set; } + + [ProtoMember(14)] + public string[]? OutFields { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override PopupContent? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guidId)) + { + id = guidId; + } + + if (Type == "custom") + { + // CustomPopupContent is in GeoBlazor Pro assembly, so we need to use reflection to get the type + var customType = + System.Type.GetType( + "dymaptic.GeoBlazor.Pro.Components.Popups.CustomPopupContent, dymaptic.GeoBlazor.Pro"); + + if (customType is not null && customType.IsSubclassOf(typeof(PopupContent))) + { + var customContent = Activator.CreateInstance(customType, [null, OutFields]) as PopupContent; + + if (customContent is null) + { + throw new InvalidOperationException( + "CustomPopupContent could not be created. Ensure the type is correct and the assembly is loaded."); + } + + customContent.Id = id; + + return customContent; + } + } + + return Type switch + { + "fields" => new FieldsPopupContent(FieldInfos?.Any(i => !i.IsNull) == true + ? FieldInfos.Select(i => i.FromSerializationRecord()!).ToArray() + : [], + Description, Title) { Id = id }, + "text" => new TextPopupContent(Text) { Id = id }, + "attachments" => new AttachmentsPopupContent(Title, Description, + DisplayType is null ? null : Enum.Parse(DisplayType)) { Id = id }, + "expression" => new ExpressionPopupContent(ExpressionInfo?.FromSerializationRecord()) { Id = id }, + "media" => new MediaPopupContent(Title, Description, MediaInfos?.Any(i => !i.IsNull) == true + ? MediaInfos.Select(i => i.FromSerializationRecord()!).ToArray() + : null, + ActiveMediaInfoIndex) { Id = id }, + "relationship" => new RelationshipPopupContent(Title, Description, DisplayCount, + DisplayType, OrderByFields?.Any(f => !f.IsNull) == true + ? OrderByFields.Select(x => x.FromSerializationRecord()!).ToList() + : null, + RelationshipId) { Id = id }, + _ => throw new NotSupportedException($"PopupContent type {Type} is not supported") + }; + } +} + +[ProtoContract(Name = "PopupContentCollection")] +internal record + PopupContentCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + PopupContentSerializationRecord> +{ + public PopupContentCollectionSerializationRecord() + { + } + + public PopupContentCollectionSerializationRecord(PopupContentSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override PopupContentSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "PopupExpressionInfo")] +public record PopupExpressionInfoSerializationRecord : MapComponentSerializationRecord +{ + public PopupExpressionInfoSerializationRecord() + { + } + + public PopupExpressionInfoSerializationRecord(string Id, string? Expression, string? Name, string? Title, + PopupExpressionInfoReturnType? ReturnType) + { + this.Id = Id; + this.Expression = Expression; + this.Name = Name; + this.Title = Title; + this.ReturnType = ReturnType.ToString(); + } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(1)] + public string? Expression { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public string? Name { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public string? Title { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(4)] + public string? ReturnType { get; init; } + + [ProtoMember(5)] + public string? Id { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override PopupExpressionInfo? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guid)) + { + id = guid; + } + + return new PopupExpressionInfo(Expression, Name, + ReturnType is null ? null : Enum.Parse(ReturnType), + Title) { Id = id }; + } +} + +[ProtoContract(Name = "PopupExpressionInfoCollection")] +internal record + PopupExpressionInfoCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + PopupExpressionInfoSerializationRecord> +{ + public PopupExpressionInfoCollectionSerializationRecord() + { + } + + public PopupExpressionInfoCollectionSerializationRecord(PopupExpressionInfoSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override PopupExpressionInfoSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "PopupTemplate")] +public record PopupTemplateSerializationRecord : MapComponentSerializationRecord +{ + public PopupTemplateSerializationRecord() + { + } + + public PopupTemplateSerializationRecord(string? Title, + string? StringContent = null, + IEnumerable? OutFields = null, + IEnumerable? FieldInfos = null, + IEnumerable? Content = null, + IEnumerable? ExpressionInfos = null, + bool? OverwriteActions = null, + bool? ReturnGeometry = null, + IEnumerable? Actions = null, + string? Id = null) + { + this.Title = Title; + this.StringContent = StringContent; + this.OutFields = OutFields; + this.FieldInfos = FieldInfos; + this.Content = Content; + this.ExpressionInfos = ExpressionInfos; + this.OverwriteActions = OverwriteActions; + this.ReturnGeometry = ReturnGeometry; + this.Actions = Actions; + this.Id = Id; + } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(1)] + public string? Title { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public string? StringContent { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public IEnumerable? OutFields { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(4)] + public IEnumerable? FieldInfos { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(5)] + public IEnumerable? Content { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(6)] + public IEnumerable? ExpressionInfos { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(7)] + public bool? OverwriteActions { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(8)] + public bool? ReturnGeometry { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(9)] + public IEnumerable? Actions { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(10)] + public string? Id { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override PopupTemplate? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new PopupTemplate(Title, StringContent, OutFields?.ToList(), + FieldInfos?.Any(i => !i.IsNull) == true + ? FieldInfos.Select(f => f.FromSerializationRecord()!).ToList() + : null, + Content?.Any(c => !c.IsNull) == true + ? Content.Select(c => c.FromSerializationRecord()!).ToList() + : null, + ExpressionInfos?.Any(i => i.IsNull) == true + ? ExpressionInfos.Select(e => e.FromSerializationRecord()!).ToList() + : null, + OverwriteActions, ReturnGeometry, + Actions?.Any(a => !a.IsNull) == true + ? Actions?.Select(a => a.FromSerializationRecord()!).ToList() + : null); + } +} + +[ProtoContract(Name = "PopupTemplateCollection")] +internal record + PopupTemplateCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + PopupTemplateSerializationRecord> +{ + public PopupTemplateCollectionSerializationRecord() + { + } + + public PopupTemplateCollectionSerializationRecord(PopupTemplateSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override PopupTemplateSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "Symbol")] +public record SymbolSerializationRecord : MapComponentSerializationRecord +{ + public SymbolSerializationRecord() + { + } + + public SymbolSerializationRecord(string Id, + string Type, + MapColorSerializationRecord? Color) + { + this.Id = Id; + this.Type = Type; + this.Color = Color; + } + + [ProtoMember(1)] + public string Type { get; init; } = string.Empty; + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public MapColorSerializationRecord? Color { get; init; } + + [ProtoMember(3)] + public SymbolSerializationRecord? Outline { get; init; } + + [ProtoMember(4)] + public double? Size { get; init; } + + [ProtoMember(5)] + public string? Style { get; init; } + + [ProtoMember(6)] + public double? Angle { get; init; } + + [ProtoMember(7)] + public double? Xoffset { get; init; } + + [ProtoMember(8)] + public double? Yoffset { get; init; } + + [ProtoMember(9)] + public double? Width { get; init; } + + [ProtoMember(10)] + public string? LineStyle { get; init; } + + [ProtoMember(11)] + public string? Text { get; init; } + + [ProtoMember(12)] + public MapColorSerializationRecord? HaloColor { get; init; } + + [ProtoMember(13)] + public double? HaloSize { get; init; } + + [ProtoMember(14)] + public MapFontSerializationRecord? Font { get; init; } + + [ProtoMember(15)] + public double? Height { get; init; } + + [ProtoMember(16)] + public string? Url { get; init; } + + [ProtoMember(17)] + public MapColorSerializationRecord? BackgroundColor { get; init; } + + [ProtoMember(18)] + public double? BorderLineSize { get; init; } + + [ProtoMember(19)] + public MapColorSerializationRecord? BorderLineColor { get; init; } + + [ProtoMember(20)] + public string? HorizontalAlignment { get; init; } + + [ProtoMember(21)] + public bool? Kerning { get; init; } + + [ProtoMember(22)] + public double? LineHeight { get; init; } + + [ProtoMember(23)] + public double? LineWidth { get; init; } + + [ProtoMember(24)] + public bool? Rotated { get; init; } + + [ProtoMember(25)] + public string? VerticalAlignment { get; init; } + + [ProtoMember(26)] + public double? XScale { get; init; } + + [ProtoMember(27)] + public double? YScale { get; init; } + + [ProtoMember(28)] + public string? Id { get; init; } + + [ProtoMember(29)] + public string? Name { get; init; } + + [ProtoMember(30)] + public string? PortalUrl { get; init; } + + [ProtoMember(31)] + public string? StyleName { get; init; } + + [ProtoMember(32)] + public string? StyleUrl { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override Symbol? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return FromSerializationRecord(); + } + + public Symbol FromSerializationRecord(bool isOutline = false) + { + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guidId)) + { + id = guidId; + } + + if (Type == "web-style") + { + // WebStyleSymbol is in GeoBlazor Pro assembly, so we need to use reflection to get the type + var webStyleSymbolType = System.Type + .GetType("dymaptic.GeoBlazor.Pro.Components.Symbols.WebStyleSymbol, dymaptic.GeoBlazor.Pro"); + + if (webStyleSymbolType is not null) + { + var portal = PortalUrl is null ? null : new Portal(url: PortalUrl); + + var webStyleSymbol = Activator.CreateInstance(webStyleSymbolType, Color?.FromSerializationRecord(), + Name, portal, StyleName, StyleUrl) as Symbol + ?? throw new InvalidOperationException("Failed to create WebStyleSymbol instance."); + webStyleSymbol.Id = id; + + return webStyleSymbol; + } + } + + return Type switch + { + "outline" => new Outline(Color?.FromSerializationRecord(), Width, + LineStyle is null ? null : Enum.Parse(LineStyle!, true)) { Id = id }, + "simple-marker" => new SimpleMarkerSymbol(Outline?.FromSerializationRecord(true) as Outline, + Color?.FromSerializationRecord(), Size, + Style is null ? null : Enum.Parse(Style!, true), + Angle, Xoffset, Yoffset) { Id = id }, + "simple-line" => isOutline + ? new Outline(Color?.FromSerializationRecord(), Width, + LineStyle is null ? null : Enum.Parse(LineStyle!, true)) { Id = id } + : new SimpleLineSymbol(Color?.FromSerializationRecord(), Width, + LineStyle is null ? null : Enum.Parse(LineStyle!, true)) { Id = id }, + "simple-fill" => new SimpleFillSymbol(Outline?.FromSerializationRecord(true) as Outline, + Color?.FromSerializationRecord(), + Style is null ? null : Enum.Parse(Style!, true)) { Id = id }, + "picture-marker" => new PictureMarkerSymbol(Url!, Width, Height, Angle, Xoffset, Yoffset) { Id = id }, + "picture-fill" => new PictureFillSymbol(Url!, Width, Height, Xoffset, Yoffset, XScale, YScale, + Outline?.FromSerializationRecord(true) as Outline) { Id = id }, + "text" => new TextSymbol(Text ?? string.Empty, Color?.FromSerializationRecord(), + HaloColor?.FromSerializationRecord(), HaloSize, + Font?.FromSerializationRecord(), Angle, BackgroundColor?.FromSerializationRecord(), + BorderLineColor?.FromSerializationRecord(), + BorderLineSize, + HorizontalAlignment is null ? null : Enum.Parse(HorizontalAlignment!, true), + Kerning, LineHeight, LineWidth, Rotated, + VerticalAlignment is null ? null : Enum.Parse(VerticalAlignment!, true), + Xoffset, Yoffset) { Id = id }, + _ => throw new ArgumentException($"Unknown symbol type: {Type}") + }; + } +} + +[ProtoContract(Name = "SymbolCollection")] +internal record + SymbolCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public SymbolCollectionSerializationRecord() + { + } + + public SymbolCollectionSerializationRecord(SymbolSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override SymbolSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MapColor")] +public record MapColorSerializationRecord : MapComponentSerializationRecord +{ + public MapColorSerializationRecord() + { + } + + public MapColorSerializationRecord(double[]? rgbaValues, string? hexOrNameValue) + { + RgbaValues = rgbaValues; + HexOrNameValue = hexOrNameValue; + } + + [ProtoMember(1)] + public double[]? RgbaValues { get; init; } + + [ProtoMember(2)] + public string? HexOrNameValue { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MapColor? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + if (HexOrNameValue is not null) + { + return new MapColor(HexOrNameValue); + } + + if (RgbaValues is not null) + { + return new MapColor(RgbaValues); + } + + return new MapColor(); + } +} + +[ProtoContract(Name = "MapColorCollection")] +public record MapColorCollectionSerializationRecord + : MapComponentCollectionSerializationRecord +{ + public MapColorCollectionSerializationRecord(MapColorSerializationRecord[] items) + { + Items = items; + } + + public sealed override MapColorSerializationRecord[]? Items { get; set; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "ActionBase")] +public record ActionBaseSerializationRecord : MapComponentSerializationRecord +{ + public ActionBaseSerializationRecord() + { + } + + public ActionBaseSerializationRecord(string Id, + string Type, + string? Title, + string? ClassName, + bool? Active, + bool? Disabled, + bool? Visible, + string? ActionId) + { + this.Id = Id; + this.Type = Type; + this.Title = Title; + this.ClassName = ClassName; + this.Active = Active; + this.Disabled = Disabled; + this.Visible = Visible; + this.ActionId = ActionId; + } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(1)] + public string Type { get; init; } = string.Empty; + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public string? Title { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public string? ClassName { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(4)] + public bool? Active { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(5)] + public bool? Disabled { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(6)] + public bool? Visible { get; init; } + + [ProtoMember(7)] + public string? Id { get; init; } + + [ProtoMember(8)] + public string? Image { get; init; } + + [ProtoMember(9)] + public bool? Value { get; init; } + + [ProtoMember(10)] + public string? ActionId { get; init; } + + [ProtoMember(11)] + public string? Test { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override ActionBase? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guidId)) + { + id = guidId; + } + + return Type switch + { + "button" => new ActionButton(Title, Image, ActionId, null, ClassName, Active, Disabled, Visible) + { + Id = id + }, + "toggle" => new ActionToggle(Title, ActionId, null, Value, Active, Disabled, Visible) { Id = id }, + _ => throw new NotSupportedException() + }; + } +} + +[ProtoContract(Name = "ActionBaseCollection")] +internal record + ActionBaseCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public ActionBaseCollectionSerializationRecord() + { + } + + public ActionBaseCollectionSerializationRecord(ActionBaseSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override ActionBaseSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MediaInfoValue")] +public record MediaInfoValueSerializationRecord : MapComponentSerializationRecord +{ + public MediaInfoValueSerializationRecord() + { + } + + public MediaInfoValueSerializationRecord(string Id, IEnumerable? Fields = null, + string? NormalizeField = null, string? TooltipField = null, + IEnumerable? Series = null, string? LinkURL = null, + string? SourceURL = null) + { + this.Id = Id; + this.Fields = Fields; + this.NormalizeField = NormalizeField; + this.TooltipField = TooltipField; + this.Series = Series; + this.LinkURL = LinkURL; + this.SourceURL = SourceURL; + } + + [ProtoMember(1)] + public IEnumerable? Fields { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public string? NormalizeField { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public string? TooltipField { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(4)] + public IEnumerable? Series { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(5)] + public string? LinkURL { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(6)] + public string? SourceURL { get; init; } + + [ProtoMember(7)] + public string? Id { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override IMediaInfoValue? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guid)) + { + id = guid; + } + + if (LinkURL is not null || SourceURL is not null) + { + return new ImageMediaInfoValue(LinkURL, SourceURL) { Id = id }; + } + + return new ChartMediaInfoValue(Fields?.ToArray(), NormalizeField, TooltipField, + Series?.Any(s => !s.IsNull) == true + ? Series.Select(s => s.FromSerializationRecord()!).ToArray() + : null) { Id = id }; + } +} + +[ProtoContract(Name = "MediaInfoValueCollection")] +internal record + MediaInfoValueCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + MediaInfoValueSerializationRecord> +{ + public MediaInfoValueCollectionSerializationRecord() + { + } + + public MediaInfoValueCollectionSerializationRecord(MediaInfoValueSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MediaInfoValueSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "ChartMediaInfoValueSeries")] +public record ChartMediaInfoValueSeriesSerializationRecord : MapComponentSerializationRecord +{ + public ChartMediaInfoValueSeriesSerializationRecord() + { + } + + public ChartMediaInfoValueSeriesSerializationRecord(string Id, string? FieldName, string? Tooltip, double? Value) + { + this.Id = Id; + this.FieldName = FieldName; + this.Tooltip = Tooltip; + this.Value = Value; + } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(1)] + public string? FieldName { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public string? Tooltip { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public double? Value { get; init; } + + [ProtoMember(4)] + public string? Id { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override ChartMediaInfoValueSeries? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guid)) + { + id = guid; + } + + return new ChartMediaInfoValueSeries(FieldName, Tooltip, Value) { Id = id }; + } +} + +[ProtoContract(Name = "ChartMediaInfoValueSeriesCollection")] +internal record ChartMediaInfoValueSeriesCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + ChartMediaInfoValueSeriesSerializationRecord> +{ + public ChartMediaInfoValueSeriesCollectionSerializationRecord() + { + } + + public ChartMediaInfoValueSeriesCollectionSerializationRecord(ChartMediaInfoValueSeriesSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override ChartMediaInfoValueSeriesSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "ElementExpressionInfo")] +public record ElementExpressionInfoSerializationRecord : MapComponentSerializationRecord +{ + public ElementExpressionInfoSerializationRecord() + { + } + + public ElementExpressionInfoSerializationRecord(string? expression, string? title) + { + Expression = expression; + Title = title; + } + + [ProtoMember(1)] + public string? Expression { get; init; } + + [ProtoMember(2)] + public string? Title { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override ElementExpressionInfo? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new ElementExpressionInfo(Expression, Title); + } +} + +[ProtoContract(Name = "ElementExpressionInfoCollection")] +internal record + ElementExpressionInfoCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + ElementExpressionInfoSerializationRecord> +{ + public ElementExpressionInfoCollectionSerializationRecord() + { + } + + public ElementExpressionInfoCollectionSerializationRecord(ElementExpressionInfoSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override ElementExpressionInfoSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "FieldInfo")] +public record FieldInfoSerializationRecord : MapComponentSerializationRecord +{ + public FieldInfoSerializationRecord() + { + } + + public FieldInfoSerializationRecord(string Id, string? FieldName = null, string? Label = null, + string? Tooltip = null, string? StringFieldOption = null, FieldInfoFormatSerializationRecord? Format = null, + bool? IsEditable = null, bool? Visible = null) + { + this.Id = Id; + this.FieldName = FieldName; + this.Label = Label; + this.Tooltip = Tooltip; + this.StringFieldOption = StringFieldOption; + this.Format = Format; + this.IsEditable = IsEditable; + this.Visible = Visible; + } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(1)] + public string? FieldName { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public string? Label { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public string? Tooltip { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(4)] + public string? StringFieldOption { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(5)] + public FieldInfoFormatSerializationRecord? Format { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(6)] + public bool? IsEditable { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(7)] + public bool? Visible { get; init; } + + [ProtoMember(8)] + public string? Id { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override FieldInfo? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guid)) + { + id = guid; + } + + StringFieldOption? sfo = StringFieldOption switch + { + "rich-text" => Enums.StringFieldOption.RichText, + "text-area" => Enums.StringFieldOption.TextArea, + "text-box" => Enums.StringFieldOption.TextBox, + _ => null + }; + + return new FieldInfo(FieldName, Label, Tooltip, sfo, Format?.FromSerializationRecord(), IsEditable, Visible) + { + Id = id + }; + } +} + +[ProtoContract(Name = "FieldInfoCollection")] +internal record + FieldInfoCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public FieldInfoCollectionSerializationRecord() + { + } + + public FieldInfoCollectionSerializationRecord(FieldInfoSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override FieldInfoSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "FieldInfoFormat")] +public record FieldInfoFormatSerializationRecord : MapComponentSerializationRecord +{ + public FieldInfoFormatSerializationRecord() + { + } + + public FieldInfoFormatSerializationRecord(string Id, + int? Places, + bool? DigitSeparator, + string? DateFormat) + { + this.Id = Id; + this.Places = Places; + this.DigitSeparator = DigitSeparator; + this.DateFormat = DateFormat; + } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(1)] + public int? Places { get; init; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public bool? DigitSeparator { get; init; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public string? DateFormat { get; init; } + + [ProtoMember(4)] + public string? Id { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override FieldInfoFormat? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guidId)) + { + id = guidId; + } + + DateFormat? df = DateFormat switch + { + "short-date" => Enums.DateFormat.ShortDate, + "short-date-short-time.cs" => Enums.DateFormat.ShortDateShortTime, + "short-date-short-time-24" => Enums.DateFormat.ShortDateShortTime24, + "short-date-long-time" => Enums.DateFormat.ShortDateLongTime, + "short-date-long-time-24" => Enums.DateFormat.ShortDateLongTime24, + "short-date-le" => Enums.DateFormat.ShortDateLe, + "short-date-le-short-time" => Enums.DateFormat.ShortDateLeShortTime, + "short-date-le-short-time-24" => Enums.DateFormat.ShortDateLeShortTime24, + "short-date-le-long-time" => Enums.DateFormat.ShortDateLeLongTime, + "short-date-le-long-time-24" => Enums.DateFormat.ShortDateLeLongTime24, + "long-month-day-year" => Enums.DateFormat.LongMonthDayYear, + "long-month-day-year-short-time" => Enums.DateFormat.LongMonthDayYearShortTime, + "long-month-day-year-short-time-24" => Enums.DateFormat.LongMonthDayYearShortTime24, + "long-month-day-year-long-time" => Enums.DateFormat.LongMonthDayYearLongTime, + "long-month-day-year-long-time-24" => Enums.DateFormat.LongMonthDayYearLongTime24, + "day-short-month-year" => Enums.DateFormat.DayShortMonthYear, + "day-short-month-year-short-time" => Enums.DateFormat.DayShortMonthYearShortTime, + "day-short-month-year-short-time-24" => Enums.DateFormat.DayShortMonthYearShortTime24, + "day-short-month-year-long-time" => Enums.DateFormat.DayShortMonthYearLongTime, + "day-short-month-year-long-time-24" => Enums.DateFormat.DayShortMonthYearLongTime24, + "long-date" => Enums.DateFormat.LongDate, + "long-date-short-time" => Enums.DateFormat.LongDateShortTime, + "long-date-short-time-24" => Enums.DateFormat.LongDateShortTime24, + "long-date-long-time" => Enums.DateFormat.LongDateLongTime, + "long-date-long-time-24" => Enums.DateFormat.LongDateLongTime24, + "long-month-year" => Enums.DateFormat.LongMonthYear, + "short-month-year" => Enums.DateFormat.ShortMonthYear, + "year" => Enums.DateFormat.Year, + _ => null + }; + + return new FieldInfoFormat(Places, DigitSeparator, df) { Id = id }; + } +} + +[ProtoContract(Name = "FieldInfoFormatCollection")] +internal record + FieldInfoFormatCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + FieldInfoFormatSerializationRecord> +{ + public FieldInfoFormatCollectionSerializationRecord() + { + } + + public FieldInfoFormatCollectionSerializationRecord(FieldInfoFormatSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override FieldInfoFormatSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "Graphic")] +public record GraphicSerializationRecord : MapComponentSerializationRecord +{ + public GraphicSerializationRecord() + { + } + + public GraphicSerializationRecord(string Id, GeometrySerializationRecord? Geometry, + SymbolSerializationRecord? Symbol, PopupTemplateSerializationRecord? PopupTemplate, + AttributeSerializationRecord[]? Attributes, bool? Visible, string? AggregateGeometries, + GraphicOriginSerializationRecord? Origin, string? LayerId, string? ViewId) + { + this.Id = Id; + this.Geometry = Geometry; + this.Symbol = Symbol; + this.PopupTemplate = PopupTemplate; + this.Attributes = Attributes; + this.Visible = Visible; + this.AggregateGeometries = AggregateGeometries; + this.Origin = Origin; + this.LayerId = LayerId; + this.ViewId = ViewId; + } + + [ProtoMember(1)] + public string? Id { get; set; } = string.Empty; + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public GeometrySerializationRecord? Geometry { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public SymbolSerializationRecord? Symbol { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(4)] + public PopupTemplateSerializationRecord? PopupTemplate { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(5)] + public AttributeSerializationRecord[]? Attributes { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(6)] + public bool? Visible { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(7)] + public string? AggregateGeometries { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(8)] + public GraphicOriginSerializationRecord? Origin { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(9)] + public string? LayerId { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(10)] + public string? ViewId { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(11)] + public AttributeSerializationRecord[]? StackedAttributes { get; set; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override Graphic? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + if (!Guid.TryParse(Id, out var graphicId)) + { + graphicId = Guid.NewGuid(); + } + + Guid? layerId = null; + + if (Guid.TryParse(LayerId, out var existingLayerId)) + { + layerId = existingLayerId; + } + + Guid? viewId = null; + + if (Guid.TryParse(ViewId, out var existingViewId)) + { + viewId = existingViewId; + } + + return new Graphic(Geometry?.FromSerializationRecord(), Symbol?.FromSerializationRecord(), + PopupTemplate?.FromSerializationRecord(), new AttributesDictionary(Attributes), + Visible, null, AggregateGeometries, Origin?.FromSerializationRecord()) + { + Id = graphicId, +#pragma warning disable BL0005 + LayerId = layerId, +#pragma warning restore BL0005 + ViewId = viewId + }; + } +} + +[ProtoContract(Name = "GraphicCollection")] +internal record + GraphicCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public GraphicCollectionSerializationRecord() + { + } + + public GraphicCollectionSerializationRecord(GraphicSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override GraphicSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MapFont")] +public record MapFontSerializationRecord : MapComponentSerializationRecord +{ + public MapFontSerializationRecord() + { + } + + public MapFontSerializationRecord(string Id, double? Size, string? Family, string? FontStyle, string? Weight, + string? Decoration) + { + this.Id = Id; + this.Size = Size; + this.Family = Family; + this.FontStyle = FontStyle; + this.Weight = Weight; + this.Decoration = Decoration; + } + + [ProtoMember(1)] + public double? Size { get; init; } + + [ProtoMember(2)] + public string? Family { get; init; } + + [ProtoMember(3)] + public string? FontStyle { get; init; } + + [ProtoMember(4)] + public string? Weight { get; init; } + + [ProtoMember(5)] + public string? Decoration { get; init; } + + [ProtoMember(6)] + public string? Id { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MapFont? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guid)) + { + id = guid; + } + + return new MapFont(Size, Family, FontStyle is null ? null : Enum.Parse(FontStyle), + Weight is null ? null : Enum.Parse(Weight), + Decoration is null ? null : Enum.Parse(Decoration)) { Id = id }; + } +} + +[ProtoContract(Name = "MapFontCollection")] +internal record + MapFontCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public MapFontCollectionSerializationRecord() + { + } + + public MapFontCollectionSerializationRecord(MapFontSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MapFontSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MediaInfo")] +public record MediaInfoSerializationRecord : MapComponentSerializationRecord +{ + public MediaInfoSerializationRecord() + { + } + + public MediaInfoSerializationRecord(string Id, string Type) + { + this.Id = Id; + this.Type = Type; + } + + [ProtoMember(1)] + public string Type { get; init; } = string.Empty; + + [ProtoMember(2)] + public string? AltText { get; init; } + + [ProtoMember(3)] + public string? Caption { get; init; } + + [ProtoMember(4)] + public string? Title { get; init; } + + [ProtoMember(5)] + public MediaInfoValueSerializationRecord? Value { get; init; } + + [ProtoMember(6)] + public double? RefreshInterval { get; init; } + + [ProtoMember(7)] + public string? Id { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MediaInfo? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guid)) + { + id = guid; + } + + return Type switch + { + "bar-chart" => new BarChartMediaInfo(Title, Caption, AltText, + Value?.FromSerializationRecord() as ChartMediaInfoValue) { Id = id }, + "column-chart" => new ColumnChartMediaInfo(Title, Caption, AltText, + Value?.FromSerializationRecord() as ChartMediaInfoValue) { Id = id }, + "pie-chart" => new PieChartMediaInfo(Title, Caption, AltText, + Value?.FromSerializationRecord() as ChartMediaInfoValue) { Id = id }, + "line-chart" => new LineChartMediaInfo(Title, Caption, AltText, + Value?.FromSerializationRecord() as ChartMediaInfoValue) { Id = id }, + "image-media" => new ImageMediaInfo(Title, Caption, AltText, + Value?.FromSerializationRecord() as ImageMediaInfoValue, + RefreshInterval) { Id = id }, + _ => throw new NotSupportedException($"MediaInfo type {Type} is not supported.") + }; + } +} + +[ProtoContract(Name = "MediaInfoCollection")] +internal record + MediaInfoCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public MediaInfoCollectionSerializationRecord() + { + } + + public MediaInfoCollectionSerializationRecord(MediaInfoSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MediaInfoSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "RelatedRecordsInfoFieldOrder")] +public record RelatedRecordsInfoFieldOrderSerializationRecord( + [property: ProtoMember(1)] string? Field, + [property: ProtoMember(2)] string? Order, + [property: ProtoMember(3)] string Id) : MapComponentSerializationRecord +{ + public RelatedRecordsInfoFieldOrderSerializationRecord() : this(null, null, Guid.NewGuid().ToString()) + { + } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override RelatedRecordsInfoFieldOrder? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + var id = Guid.NewGuid(); + + if (Guid.TryParse(Id, out var guid)) + { + id = guid; + } + + OrderBy? orderBy = Order is null ? null : Enum.Parse(Order!, true); + + return new RelatedRecordsInfoFieldOrder(Field, orderBy) { Id = id }; + } +} + +[ProtoContract(Name = "RelatedRecordsInfoFieldOrderCollection")] +internal record RelatedRecordsInfoFieldOrderCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + RelatedRecordsInfoFieldOrderSerializationRecord> +{ + public RelatedRecordsInfoFieldOrderCollectionSerializationRecord() + { + } + + public RelatedRecordsInfoFieldOrderCollectionSerializationRecord( + RelatedRecordsInfoFieldOrderSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override RelatedRecordsInfoFieldOrderSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "SpatialReference")] +public record SpatialReferenceSerializationRecord : MapComponentSerializationRecord +{ + public SpatialReferenceSerializationRecord() + { + } + + public SpatialReferenceSerializationRecord(int? Wkid, string? Wkt = null, string? Wkt2 = null) + { + this.Wkid = Wkid; + this.Wkt = Wkt; + this.Wkt2 = Wkt2; + } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(1)] + public int? Wkid { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public string? Wkt { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public string? Wkt2 { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override SpatialReference? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new SpatialReference(Wkid ?? 4326, wkt: Wkt, wkt2: Wkt2); + } +} + +[ProtoContract(Name = "SpatialReferenceCollection")] +internal record + SpatialReferenceCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + SpatialReferenceSerializationRecord> +{ + public SpatialReferenceCollectionSerializationRecord() + { + } + + public SpatialReferenceCollectionSerializationRecord(SpatialReferenceSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override SpatialReferenceSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "Attribute")] +public record AttributeSerializationRecord : MapComponentSerializationRecord +{ + public AttributeSerializationRecord() + { + } + + public AttributeSerializationRecord(string Key, + string? Value, + string ValueType) + { + this.Key = Key; + this.Value = Value; + this.ValueType = ValueType; + } + + [ProtoMember(1)] + public string Key { get; init; } = string.Empty; + [ProtoMember(2)] + public string? Value { get; init; } + [ProtoMember(3)] + public string ValueType { get; init; } = string.Empty; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public (string Key, object? Value) FromSerializationRecord() + { + if (Value is null) + { + return (Key, Value); + } + + if (string.Equals("OBJECTID", Key, StringComparison.OrdinalIgnoreCase)) + { + if (long.TryParse(Value, NumberStyles.None, CultureInfo.InvariantCulture, out var numVal)) + { + return (Key, new ObjectId(numVal)); + } + + return (Key, new ObjectId(Value)); + } + + switch (ValueType) + { + case "System.Int32": + case "integer": + return (Key, int.Parse(Value!, CultureInfo.InvariantCulture)); + + case "System.Int16": + case "small-integer": + return (Key, short.Parse(Value!, CultureInfo.InvariantCulture)); + + case "System.Int64": + case "big-integer": + return (Key, long.Parse(Value!, CultureInfo.InvariantCulture)); + + case "System.Single": + case "single": + return (Key, float.Parse(Value!, CultureInfo.InvariantCulture)); + + case "System.Double": + case "double": + return (Key, double.Parse(Value!, CultureInfo.InvariantCulture)); + + case "[object Number]": + if (int.TryParse(Value, NumberStyles.None, CultureInfo.InvariantCulture, out var intVal)) + { + return (Key, intVal); + } + + if (long.TryParse(Value, NumberStyles.None, CultureInfo.InvariantCulture, out var longVal)) + { + return (Key, longVal); + } + + if (double.TryParse(Value, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, + out var doubleVal)) + { + return (Key, doubleVal); + } + + return (Key, Value); + case "System.Boolean": + case "[object Boolean]": + return (Key, bool.Parse(Value!)); + + case "guid": + return (Key, Guid.Parse(Value!)); + + case "System.DateTime": + case "date": + case "timestamp-offset": + case "[object Date]": + // Date is serialized in ArcGIS as a long unix timestamp, so we check for this first. + if (long.TryParse(Value, out var unixTimestamp)) + { + return (Key, DateTimeOffset.FromUnixTimeMilliseconds(unixTimestamp).DateTime); + } + + return (Key, DateTime.Parse(Value!, CultureInfo.InvariantCulture)); + + case "System.DateOnly": + case "date-only": + return (Key, DateOnly.Parse(Value!, CultureInfo.InvariantCulture)); + + case "System.TimeOnly": + case "time-only": + return (Key, TimeOnly.Parse(Value!, CultureInfo.InvariantCulture)); + + default: + if (Guid.TryParse(Value, out var guidValue)) + { + return (Key, guidValue); + } + + if (DateTime.TryParse(Value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateValue)) + { + return (Key, dateValue); + } + + return (Key, Value); + } + } +} + +[ProtoContract(Name = "AttributeCollection")] +public record + AttributeCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public AttributeCollectionSerializationRecord() + { + } + + public AttributeCollectionSerializationRecord(AttributeSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override AttributeSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "GraphicOrigin")] +public record GraphicOriginSerializationRecord : MapComponentSerializationRecord +{ + public GraphicOriginSerializationRecord() + { + } + + public GraphicOriginSerializationRecord(string? LayerId, string? ArcGISLayerId, int? LayerIndex) + { + this.LayerId = LayerId; + this.ArcGISLayerId = ArcGISLayerId; + this.LayerIndex = LayerIndex; + } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(1)] + public string? LayerId { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(2)] + public string? ArcGISLayerId { get; init; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [ProtoMember(3)] + public int? LayerIndex { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override GraphicOrigin? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new GraphicOrigin(LayerId is null ? null : Guid.Parse(LayerId), + ArcGISLayerId, LayerIndex); + } +} + +[ProtoContract(Name = "GraphicOriginCollection")] +internal record + GraphicOriginCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + GraphicOriginSerializationRecord> +{ + public GraphicOriginCollectionSerializationRecord() + { + } + + public GraphicOriginCollectionSerializationRecord(GraphicOriginSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override GraphicOriginSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MapPath")] +public record MapPathSerializationRecord : MapComponentSerializationRecord +{ + public MapPathSerializationRecord() + { + } + + public MapPathSerializationRecord(MapPointSerializationRecord[] Points) + { + this.Points = Points; + } + + [ProtoMember(1)] + public MapPointSerializationRecord[] Points { get; init; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MapPath? FromSerializationRecord() + { + if (IsNull || (Points.Length == 0) || Points.Any(p => p.IsNull)) + { + return null; + } + + return new MapPath(Points.Select(p => p.FromSerializationRecord()!)); + } +} + +[ProtoContract(Name = "MapPathCollection")] +internal record + MapPathCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public MapPathCollectionSerializationRecord() + { + } + + public MapPathCollectionSerializationRecord(MapPathSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MapPathSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MapPoint")] +public record MapPointSerializationRecord : MapComponentSerializationRecord +{ + public MapPointSerializationRecord() + { + } + + public MapPointSerializationRecord(double[] Coordinates) + { + this.Coordinates = Coordinates; + } + + [ProtoMember(1)] + public double[] Coordinates { get; init; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MapPoint? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new MapPoint(Coordinates); + } +} + +[ProtoContract(Name = "MapPointCollection")] +internal record + MapPointCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public MapPointCollectionSerializationRecord() + { + } + + public MapPointCollectionSerializationRecord(MapPointSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MapPointSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MeshComponent")] +public record MeshComponentSerializationRecord : MapComponentSerializationRecord +{ + public MeshComponentSerializationRecord() + { + } + + public MeshComponentSerializationRecord(byte[]? faces, + MeshComponentMaterialSerializationRecord? material, + string? name, + string? shading) + { + Faces = faces; + Material = material; + Name = name; + Shading = shading; + } + + [ProtoMember(1)] + public byte[]? Faces { get; init; } + + [ProtoMember(2)] + public MeshComponentMaterialSerializationRecord? Material { get; init; } + + [ProtoMember(3)] + public string? Name { get; init; } + + [ProtoMember(4)] + public string? Shading { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MeshComponent? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new MeshComponent(Faces, + Material?.FromSerializationRecord(), + Name, + Shading is null ? null : Enum.Parse(Shading)); + } +} + +[ProtoContract(Name = "MeshComponentCollection")] +internal record + MeshComponentCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + MeshComponentSerializationRecord> +{ + public MeshComponentCollectionSerializationRecord(MeshComponentSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MeshComponentSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MeshComponentMaterial")] +public record MeshComponentMaterialSerializationRecord : MapComponentSerializationRecord +{ + public MeshComponentMaterialSerializationRecord() + { + } + + public MeshComponentMaterialSerializationRecord(double? alphaCutoff, + string? alphaMode, + MapColorSerializationRecord? color, + MeshTextureSerializationRecord? colorTexture, + MeshTextureTransformSerializationRecord? colorTextureTransform, + bool? doubleSided, + MeshTextureSerializationRecord? normalTexture, + MeshTextureTransformSerializationRecord? normalTextureTransform, + MapColorSerializationRecord? emissiveColor, + MeshTextureSerializationRecord? emissiveTexture, + MeshTextureTransformSerializationRecord? emissiveTextureTransform, + double? metallic, + MeshTextureSerializationRecord? metallicRoughnessTexture, + MeshTextureSerializationRecord? occlusionTexture, + MeshTextureTransformSerializationRecord? occlusionTextureTransform, + double? roughness) + { + AlphaCutoff = alphaCutoff; + AlphaMode = alphaMode; + Color = color; + ColorTexture = colorTexture; + ColorTextureTransform = colorTextureTransform; + DoubleSided = doubleSided; + NormalTexture = normalTexture; + NormalTextureTransform = normalTextureTransform; + EmissiveColor = emissiveColor; + EmissiveTexture = emissiveTexture; + EmissiveTextureTransform = emissiveTextureTransform; + Metallic = metallic; + MetallicRoughnessTexture = metallicRoughnessTexture; + OcclusionTexture = occlusionTexture; + OcclusionTextureTransform = occlusionTextureTransform; + Roughness = roughness; + } + + [ProtoMember(1)] + public double? AlphaCutoff { get; init; } + + [ProtoMember(2)] + public string? AlphaMode { get; init; } + + [ProtoMember(3)] + public MapColorSerializationRecord? Color { get; init; } + + [ProtoMember(4)] + public MeshTextureSerializationRecord? ColorTexture { get; init; } + + [ProtoMember(5)] + public MeshTextureTransformSerializationRecord? ColorTextureTransform { get; init; } + + [ProtoMember(6)] + public bool? DoubleSided { get; init; } + + [ProtoMember(7)] + public MeshTextureSerializationRecord? NormalTexture { get; init; } + + [ProtoMember(8)] + public MeshTextureTransformSerializationRecord? NormalTextureTransform { get; init; } + + [ProtoMember(9)] + public MapColorSerializationRecord? EmissiveColor { get; init; } + + [ProtoMember(10)] + public MeshTextureSerializationRecord? EmissiveTexture { get; init; } + + [ProtoMember(11)] + public MeshTextureTransformSerializationRecord? EmissiveTextureTransform { get; init; } + + [ProtoMember(12)] + public double? Metallic { get; init; } + + [ProtoMember(13)] + public MeshTextureSerializationRecord? MetallicRoughnessTexture { get; init; } + + [ProtoMember(14)] + public MeshTextureSerializationRecord? OcclusionTexture { get; init; } + + [ProtoMember(15)] + public MeshTextureTransformSerializationRecord? OcclusionTextureTransform { get; init; } + + [ProtoMember(16)] + public double? Roughness { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override IMeshComponentMaterial? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + if ((EmissiveColor != null) || (EmissiveTexture != null) + || (EmissiveTextureTransform != null) || (Metallic != null) + || (MetallicRoughnessTexture != null) || (OcclusionTexture != null) + || (OcclusionTextureTransform != null) || (Roughness != null)) + { + return new MeshMaterialMetallicRoughness(AlphaCutoff, + AlphaMode is null ? null : Enum.Parse(AlphaMode), + Color?.FromSerializationRecord(), + ColorTexture?.FromSerializationRecord(), + ColorTextureTransform?.FromSerializationRecord(), + DoubleSided, + EmissiveColor?.FromSerializationRecord(), + EmissiveTexture?.FromSerializationRecord(), + EmissiveTextureTransform?.FromSerializationRecord(), + Metallic, + MetallicRoughnessTexture?.FromSerializationRecord(), + NormalTexture?.FromSerializationRecord(), + NormalTextureTransform?.FromSerializationRecord(), + OcclusionTexture?.FromSerializationRecord(), + OcclusionTextureTransform?.FromSerializationRecord(), + Roughness); + } + + return new MeshMaterial(AlphaCutoff, + AlphaMode is null ? null : Enum.Parse(AlphaMode), + Color?.FromSerializationRecord(), + ColorTexture?.FromSerializationRecord(), + ColorTextureTransform?.FromSerializationRecord(), + DoubleSided, + NormalTexture?.FromSerializationRecord(), + NormalTextureTransform?.FromSerializationRecord()); + } +} + +[ProtoContract(Name = "MeshComponentMaterialCollection")] +internal record + MeshComponentMaterialCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + MeshComponentMaterialSerializationRecord> +{ + public MeshComponentMaterialCollectionSerializationRecord(MeshComponentMaterialSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MeshComponentMaterialSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MeshTexture")] +public record MeshTextureSerializationRecord : MapComponentSerializationRecord +{ + public MeshTextureSerializationRecord() + { + } + + public MeshTextureSerializationRecord(ImageDataSerializationRecord? imageData, + string?[]? wrap, + bool? transparent, + string? url) + { + ImageData = imageData; + Wrap = wrap; + Transparent = transparent; + Url = url; + } + + [ProtoMember(1)] + public ImageDataSerializationRecord? ImageData { get; init; } + + [ProtoMember(2)] + public string?[]? Wrap { get; init; } + + [ProtoMember(3)] + public bool? Transparent { get; init; } + + [ProtoMember(4)] + public string? Url { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MeshTexture? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + SeparableWrapModes? wrapModes = null; + + if (Wrap != null) + { + if (Wrap.Length == 2) + { + var first = Wrap[0]; + var second = Wrap[1]; + + wrapModes = new SeparableWrapModes(first is null ? null : Enum.Parse(first), + second is null ? null : Enum.Parse(second)); + } + else if (Wrap.Length == 1) + { + var value = Wrap[0]; + WrapMode? wrapVal = value is null ? null : Enum.Parse(value); + wrapModes = new SeparableWrapModes(wrapVal, wrapVal); + } + } + + return new MeshTexture(null, ImageData?.FromSerializationRecord(), wrapModes, Transparent, Url); + } +} + +[ProtoContract(Name = "MeshTextureCollection")] +internal record + MeshTextureCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public MeshTextureCollectionSerializationRecord(MeshTextureSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MeshTextureSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "ImageData")] +public record ImageDataSerializationRecord : MapComponentSerializationRecord +{ + public ImageDataSerializationRecord() + { + } + + public ImageDataSerializationRecord(byte[] data, + string colorSpace, + long height, + long width) + { + Data = data; + ColorSpace = colorSpace; + Height = height; + Width = width; + } + + [ProtoMember(1)] + public byte[]? Data { get; init; } + + [ProtoMember(2)] + public string? ColorSpace { get; init; } + + [ProtoMember(3)] + public long Height { get; init; } + + [ProtoMember(4)] + public long Width { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override ImageData? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new ImageData(Data ?? [], ColorSpace ?? string.Empty, Height, Width); + } +} + +[ProtoContract(Name = "ImageDataCollection")] +public record ImageDataCollectionSerializationRecord + : MapComponentCollectionSerializationRecord +{ + public ImageDataCollectionSerializationRecord(ImageDataSerializationRecord[] items) + { + Items = items; + } + + public sealed override ImageDataSerializationRecord[]? Items { get; set; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MeshTextureTransform")] +public record MeshTextureTransformSerializationRecord : MapComponentSerializationRecord +{ + public MeshTextureTransformSerializationRecord() + { + } + + public MeshTextureTransformSerializationRecord(double[]? offset, + double? rotation, + double[]? scale) + { + Offset = offset; + Rotation = rotation; + Scale = scale; + } + + [ProtoMember(1)] + public double[]? Offset { get; init; } + + [ProtoMember(2)] + public double? Rotation { get; init; } + + [ProtoMember(3)] + public double[]? Scale { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MeshTextureTransform? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new MeshTextureTransform(Offset, Rotation, Scale); + } +} + +[ProtoContract(Name = "MeshTextureTransformCollection")] +internal record + MeshTextureTransformCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + MeshTextureTransformSerializationRecord> +{ + public MeshTextureTransformCollectionSerializationRecord(MeshTextureTransformSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MeshTextureTransformSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MeshTransform")] +public record MeshTransformSerializationRecord : MapComponentSerializationRecord +{ + public MeshTransformSerializationRecord() + { + } + + public MeshTransformSerializationRecord(double? rotationAngle, + double[]? rotationAxis, + double[]? scale, + double[]? translation) + { + RotationAngle = rotationAngle; + RotationAxis = rotationAxis; + Scale = scale; + Translation = translation; + } + + [ProtoMember(1)] + public double? RotationAngle { get; init; } + + [ProtoMember(2)] + public double[]? RotationAxis { get; init; } + + [ProtoMember(3)] + public double[]? Scale { get; init; } + + [ProtoMember(4)] + public double[]? Translation { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MeshTransform? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new MeshTransform(RotationAngle, RotationAxis, Scale, Translation); + } +} + +[ProtoContract(Name = "MeshTransformCollection")] +internal record + MeshTransformCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + MeshTransformSerializationRecord> +{ + public MeshTransformCollectionSerializationRecord(MeshTransformSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MeshTransformSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MeshVertexAttributes")] +public record MeshVertexAttributesSerializationRecord : MapComponentSerializationRecord +{ + public MeshVertexAttributesSerializationRecord() + { + } + + public MeshVertexAttributesSerializationRecord(byte[]? color, + double[]? normal, + double[]? position, + double[]? tangent, + double[]? uv) + { + Color = color; + Normal = normal; + Position = position; + Tangent = tangent; + Uv = uv; + } + + [ProtoMember(1)] + public byte[]? Color { get; init; } + + [ProtoMember(2)] + public double[]? Normal { get; init; } + + [ProtoMember(3)] + public double[]? Position { get; init; } + + [ProtoMember(4)] + public double[]? Tangent { get; init; } + + [ProtoMember(5)] + public double[]? Uv { get; init; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override MeshVertexAttributes? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return new MeshVertexAttributes(Color, Normal, Position, Tangent, Uv); + } +} + +[ProtoContract(Name = "MeshVertexAttributesCollection")] +internal record + MeshVertexAttributesCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + MeshVertexAttributesSerializationRecord> +{ + public MeshVertexAttributesCollectionSerializationRecord(MeshVertexAttributesSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MeshVertexAttributesSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "MeshVertexSpace")] +public record MeshVertexSpaceSerializationRecord : MapComponentSerializationRecord +{ + public MeshVertexSpaceSerializationRecord() + { + } + + public MeshVertexSpaceSerializationRecord(string? type, + double[]? origin) + { + Type = type; + Origin = origin; + } + + [ProtoMember(1)] + public string? Type { get; set; } + + [ProtoMember(2)] + public double[]? Origin { get; set; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override IMeshVertexSpace? FromSerializationRecord() + { + if (IsNull) + { + return null; + } + + return Type switch + { + "local" => new MeshLocalVertexSpace(Origin), + "georeferenced" => new MeshGeoreferencedVertexSpace(Origin), + _ => throw new NotSupportedException($"MeshVertexSpace type {Type} is not supported.") + }; + } +} + +[ProtoContract(Name = "MeshVertexSpaceCollection")] +internal record + MeshVertexSpaceCollectionSerializationRecord : MapComponentCollectionSerializationRecord< + MeshVertexSpaceSerializationRecord> +{ + public MeshVertexSpaceCollectionSerializationRecord(MeshVertexSpaceSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override MeshVertexSpaceSerializationRecord[]? Items { get; set; } = []; + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "ViewHitCollection")] +internal record + ViewHitCollectionSerializationRecord : MapComponentCollectionSerializationRecord +{ + public ViewHitCollectionSerializationRecord() + { + } + + public ViewHitCollectionSerializationRecord(ViewHitSerializationRecord[] items) + { + Items = items; + } + + [ProtoMember(1)] + public sealed override ViewHitSerializationRecord[]? Items { get; set; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } +} + +[ProtoContract(Name = "ViewHit")] +public record ViewHitSerializationRecord : MapComponentSerializationRecord +{ + public ViewHitSerializationRecord() + { + } + + public ViewHitSerializationRecord(string? Type, + GeometrySerializationRecord? MapPoint, + GraphicSerializationRecord? Graphic, + string? LayerId, + double? Distance) + { + this.Type = Type; + this.MapPoint = MapPoint; + this.Graphic = Graphic; + this.LayerId = LayerId; + this.Distance = Distance; + } + + [ProtoMember(1)] + public string? Type { get; set; } + + [ProtoMember(2)] + public GeometrySerializationRecord? MapPoint { get; set; } + + [ProtoMember(3)] + public GraphicSerializationRecord? Graphic { get; set; } + + [ProtoMember(4)] + public string? LayerId { get; set; } + + [ProtoMember(5)] + public double? Distance { get; set; } + + [ProtoMember(1000)] + public override bool IsNull { get; init; } + + public override ViewHit? FromSerializationRecord() + { + if (IsNull || MapPoint is null || MapPoint.IsNull) + { + return null; + } + + if (Type == "graphic") + { + if (Graphic is null || Graphic.IsNull) + { + return null; + } + + Guid? layerId = null; + + if (Guid.TryParse(LayerId, out var layerGuid)) + { + layerId = layerGuid; + } + + return new GraphicHit(Graphic!.FromSerializationRecord()!, layerId, + (Point)MapPoint!.FromSerializationRecord()!, Distance); + } + + return new ViewHit(Type!, (Point)MapPoint!.FromSerializationRecord()!); + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/copyProtobuf.ps1 b/src/dymaptic.GeoBlazor.Core/copyProtobuf.ps1 new file mode 100644 index 000000000..08c69d676 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/copyProtobuf.ps1 @@ -0,0 +1,14 @@ +param ([string]$Content) + +if ($null -eq $Content -or $Content -eq "") { + Write-Error "Content parameter is required." + exit 1 +} + +# Define the destination path +$destinationPath = Join-Path $PSScriptRoot "Scripts" "geoblazorProto.ts" + +# Unescape any escaped characters in the content +$Content = $Content -replace '\\"', '"' -replace '\\r\\n', "`r`n" -replace '\\n', "`n" + +Set-Content -Path $destinationPath -Value $Content -Encoding UTF8 \ No newline at end of file From 4ebeb7b23e71c9596cf81d7f4759deb552a696f6 Mon Sep 17 00:00:00 2001 From: Tim Purdum Date: Mon, 15 Dec 2025 21:03:49 -0600 Subject: [PATCH 2/7] Update protobuf implementation, samples and tests --- Directory.Build.targets | 6 + esBuildWaitForCompletion.ps1 | 27 +- ....GeoBlazor.Core.Sample.OAuth.Client.csproj | 3 - .../Components/App.razor | 13 - .../Program.cs | 5 +- ...ymaptic.GeoBlazor.Core.Sample.OAuth.csproj | 2 - .../Pages/HitTests.razor | 2 +- .../Pages/ManyGraphics.razor | 3 +- .../Pages/ServerSideQueries.razor | 70 +- .../Pages/Tests.razor | 24 +- .../Pages/WFSLayers.razor | 18 +- .../Shared/NavMenu.razor.cs | 24 +- .../wwwroot/functions.js | 31 +- ...zor.Core.Sample.TokenRefresh.Client.csproj | 2 - ....GeoBlazor.Core.Sample.TokenRefresh.csproj | 2 - src/.editorconfig | 2 +- .../Properties/launchSettings.json | 9 + .../ProtobufSourceGenerator.cs | 43 +- src/dymaptic.GeoBlazor.Core.sln | 14 + .../Components/ActionBase.cs | 91 +- .../Components/ActionButton.cs | 6 +- .../Components/ActionToggle.cs | 6 +- .../Components/BarChartMediaInfo.cs | 9 +- .../Components/BookmarksViewModel.cs | 2 +- .../Components/ChartMediaInfoValue.cs | 83 +- .../Components/ChartMediaInfoValueSeries.cs | 50 +- .../Components/Circle.cs | 16 +- .../Components/ColumnChartMediaInfo.cs | 9 +- .../Components/CompassViewModel.cs | 2 +- .../Components/ElementExpressionInfo.cs | 33 +- .../Components/FeaturesViewModel.cs | 2 +- .../Components/FeaturesViewModel.gb.cs | 2 +- .../Components/FieldInfo.cs | 86 +- .../Components/FieldInfoFormat.cs | 82 +- .../Components/Geometries/Extent.cs | 6 +- .../Components/Geometries/Geometry.cs | 207 +--- .../Components/Geometries/OldPolyLine.cs | 1 + .../Components/Geometries/Point.cs | 10 +- .../Components/Geometries/Polygon.cs | 12 +- .../Components/Geometries/Polyline.cs | 12 +- .../Components/Graphic.cs | 124 +-- .../Components/HomeViewModel.cs | 2 +- .../Components/HomeViewModel.gb.cs | 2 +- .../Components/ImageMediaInfo.cs | 10 +- .../Components/ImageMediaInfoValue.cs | 12 +- .../Components/JoinTableDataSource.cs | 2 - .../Components/Label.cs | 2 +- .../Components/LayerListViewModel.gb.cs | 2 +- .../Components/Layers/BaseTileLayer.gb.cs | 2 +- .../Components/Layers/CSVLayer.gb.cs | 2 +- .../Components/Layers/FeatureLayer.gb.cs | 4 +- .../Components/Layers/GeoJSONLayer.gb.cs | 4 +- .../Components/Layers/GeoRSSLayer.gb.cs | 2 +- .../Components/Layers/ImageryLayer.gb.cs | 2 +- .../Components/Layers/Layer.cs | 2 +- .../Components/Layers/Layer.gb.cs | 6 +- .../Components/Layers/MapImageLayer.gb.cs | 2 +- .../Components/Layers/TileLayer.gb.cs | 2 +- .../Components/Layers/VectorTileLayer.gb.cs | 2 +- .../Components/Layers/WFSLayer.gb.cs | 2 +- .../Components/Layers/WMSLayer.gb.cs | 2 +- .../Components/Layers/WebTileLayer.gb.cs | 2 +- .../Components/LineChartMediaInfo.cs | 9 +- .../Components/LocateViewModel.cs | 4 +- .../Components/LocateViewModel.gb.cs | 2 +- .../Components/LocationService.cs | 4 +- .../Components/MapComponent.razor.cs | 52 +- .../Components/MapFont.cs | 57 +- .../Components/MediaInfo.cs | 65 +- .../Components/MeshComponent.cs | 59 ++ .../Components/MeshComponent.gb.cs | 417 +++++++++ .../MeshGeoreferencedVertexSpace.cs | 24 + .../Components/MeshLocalVertexSpace.cs | 20 + .../Components/MeshMaterial.cs | 23 + .../Components/MeshMaterial.gb.cs | 823 ++++++++++++++++ .../MeshMaterialMetallicRoughness.cs | 28 + .../MeshMaterialMetallicRoughness.gb.cs | 883 ++++++++++++++++++ .../Components/MeshTexture.cs | 518 ++++++++++ .../Components/MeshTextureTransform.cs | 14 + .../Components/MeshTextureTransform.gb.cs | 396 ++++++++ .../Components/MeshTransform.cs | 16 + .../Components/MeshTransform.gb.cs | 519 ++++++++++ .../Components/MeshVertexAttributes.cs | 60 ++ .../Components/MeshVertexAttributes.gb.cs | 624 +++++++++++++ .../Components/PieChartMediaInfo.cs | 8 +- .../Popups/AttachmentsPopupContent.cs | 6 +- .../Popups/ExpressionPopupContent.cs | 8 +- .../Components/Popups/FieldsPopupContent.cs | 8 +- .../Components/Popups/MediaPopupContent.cs | 8 +- .../Components/Popups/PopupContent.cs | 112 +-- .../Components/Popups/PopupExpressionInfo.cs | 57 +- .../Components/Popups/PopupTemplate.cs | 95 +- .../Popups/RelationshipPopupContent.cs | 8 +- .../Components/Popups/TextPopupContent.cs | 6 +- .../RelatedRecordsInfoFieldOrder.cs | 28 +- .../Components/Renderers/SimpleRenderer.cs | 2 +- .../Components/SearchViewModel.cs | 2 +- .../Components/SearchViewModel.gb.cs | 12 +- .../Components/SpatialReference.cs | 36 +- .../Components/Symbols/FillSymbol.cs | 2 +- .../Components/Symbols/LineSymbol.cs | 1 + .../Components/Symbols/MarkerSymbol.cs | 1 + .../Components/Symbols/Outline.cs | 1 + .../Components/Symbols/PictureFillSymbol.cs | 8 +- .../Components/Symbols/PictureMarkerSymbol.cs | 6 +- .../Components/Symbols/SimpleFillSymbol.cs | 10 +- .../Components/Symbols/SimpleLineSymbol.cs | 8 +- .../Components/Symbols/SimpleMarkerSymbol.cs | 10 +- .../Components/Symbols/Symbol.cs | 182 +--- .../Components/Symbols/TextSymbol.cs | 17 +- .../Components/UniqueValueInfo.cs | 2 +- .../Components/Views/MapView.razor | 4 +- .../Components/Views/MapView.razor.cs | 253 +++-- .../Components/Views/SceneView.cs | 2 +- .../Widgets/BasemapLayerListWidget.cs | 2 +- .../Components/Widgets/BookmarksWidget.cs | 4 +- .../Components/Widgets/BookmarksWidget.gb.cs | 2 +- .../Components/Widgets/CompassWidget.cs | 2 +- .../Components/Widgets/HomeWidget.cs | 4 +- .../Components/Widgets/LayerListWidget.cs | 2 +- .../Components/Widgets/LocateWidget.cs | 2 +- .../Components/Widgets/LocateWidget.gb.cs | 4 +- .../Components/Widgets/PopupWidget.cs | 6 +- .../Components/Widgets/SearchWidget.cs | 22 +- .../Components/Widgets/SearchWidget.gb.cs | 10 +- .../Components/Widgets/SliderWidget.gb.cs | 22 +- .../DependencyExtension.cs | 37 +- .../Enums/{Shading.cs => MeshShading.cs} | 4 +- .../Enums/{Horizontal.cs => WrapMode.cs} | 7 +- .../Interfaces/IInteractiveRecord.cs | 2 + .../Interfaces/IMediaInfoValue.cs | 9 + .../Model/AttributesDictionary.cs | 32 +- .../Model/FieldsIndex.gb.cs | 5 + .../Model/GraphicHit.cs | 14 +- .../Model/GraphicOrigin.cs | 40 +- .../Model/Ground.gb.cs | 5 + .../Model/ImageData.cs | 12 +- src/dymaptic.GeoBlazor.Core/Model/MapColor.cs | 11 +- src/dymaptic.GeoBlazor.Core/Model/MapPath.cs | 57 +- .../Model/PortalGroup.gb.cs | 5 + .../Model/PortalItemResource.gb.cs | 5 + .../Model/SeparableWrapModes.cs | 32 +- .../Model/SeparableWrapModes.gb.cs | 22 - .../Results/HitTestResult.cs | 41 +- .../Scripts/geoblazorProto.ts | 3 + .../Serialization/EnumJsonConverters.cs | 38 + .../Serialization/IJSStreamReferenceHelper.cs | 17 +- .../Serialization/JsSyncManager.cs | 96 +- .../ProtobufSerializationBase.cs | 77 -- .../dymaptic.GeoBlazor.Core.csproj | 16 +- .../ArcGISVersionInfoSourceGeneratorTests.cs | 10 +- .../CoreSourceGeneratorTests.cs | 208 +++++ .../ESBuildLauncherTests.cs | 180 ---- .../Utils/RoslynUtility.cs | 55 ++ ...eoBlazor.Core.SourceGenerator.Tests.csproj | 25 +- .../Components/FeatureLayerViewTests.razor | 4 +- .../Components/GeometryEngineTests.cs | 400 +++++--- .../MapComponentTests.cs | 8 +- .../SerializationUnitTests.cs | 15 +- .../Components/App.razor | 16 +- .../Program.cs | 14 +- .../Properties/launchSettings.json | 2 +- 162 files changed, 5927 insertions(+), 2418 deletions(-) create mode 100644 Directory.Build.targets create mode 100644 src/dymaptic.GeoBlazor.Core.SourceGenerator/Properties/launchSettings.json create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshComponent.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshComponent.gb.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshGeoreferencedVertexSpace.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshLocalVertexSpace.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshMaterial.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshMaterial.gb.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshMaterialMetallicRoughness.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshMaterialMetallicRoughness.gb.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshTexture.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshTextureTransform.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshTextureTransform.gb.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshTransform.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshTransform.gb.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshVertexAttributes.cs create mode 100644 src/dymaptic.GeoBlazor.Core/Components/MeshVertexAttributes.gb.cs rename src/dymaptic.GeoBlazor.Core/Enums/{Shading.cs => MeshShading.cs} (88%) rename src/dymaptic.GeoBlazor.Core/Enums/{Horizontal.cs => WrapMode.cs} (74%) create mode 100644 src/dymaptic.GeoBlazor.Core/Interfaces/IMediaInfoValue.cs delete mode 100644 src/dymaptic.GeoBlazor.Core/Model/SeparableWrapModes.gb.cs delete mode 100644 src/dymaptic.GeoBlazor.Core/Serialization/ProtobufSerializationBase.cs create mode 100644 test/dymaptic.GeoBlazor.Core.SourceGenerator.Tests/CoreSourceGeneratorTests.cs delete mode 100644 test/dymaptic.GeoBlazor.Core.SourceGenerator.Tests/ESBuildLauncherTests.cs create mode 100644 test/dymaptic.GeoBlazor.Core.SourceGenerator.Tests/Utils/RoslynUtility.cs diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 000000000..e87e93a45 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/esBuildWaitForCompletion.ps1 b/esBuildWaitForCompletion.ps1 index 370398507..c782fe43e 100644 --- a/esBuildWaitForCompletion.ps1 +++ b/esBuildWaitForCompletion.ps1 @@ -1,30 +1,21 @@ # PowerShell -param([string][Alias("c")]$Configuration = "Debug", - [switch]$Pro) +param([string][Alias("c")]$Configuration = "Debug") -if ($Pro) { - $RootDir = Join-Path -Path $PSScriptRoot "..\src\dymaptic.GeoBlazor.Pro" -} else { - $RootDir = Join-Path -Path $PSScriptRoot "src\dymaptic.GeoBlazor.Core" -} - -$LockFilePath = Join-Path -Path $RootDir "esBuild.$Configuration.lock" +$CoreRootDir = Join-Path -Path $PSScriptRoot "src\dymaptic.GeoBlazor.Core" +$ProRootDir = Join-Path -Path $PSScriptRoot "..\src\dymaptic.GeoBlazor.Pro" +$CoreLockFilePath = Join-Path -Path $CoreRootDir "esBuild.$Configuration.lock" +$ProLockFilePath = Join-Path -Path $ProRootDir "esBuild.$Configuration.lock" Write-Host "Waiting for lock file:" $LockFilePath -if (Test-Path -Path $LockFilePath) { +if ((Test-Path -Path $CoreLockFilePath) -or (Test-Path -Path $ProLockFilePath)) { Write-Host "Lock file found. Waiting for release." } else { - Start-Sleep -Seconds 1 - if (Test-Path -Path $LockFilePath) { - Write-Host "Lock file found. Waiting for release." - } else { - Write-Host "No lock file found. Exiting." - return 0 - } + Write-Host "No lock file found. Exiting." + return 0 } -while (Test-Path -Path $LockFilePath) { +while ((Test-Path -Path $CoreLockFilePath) -or (Test-Path -Path $ProLockFilePath)) { Start-Sleep -Seconds 1 Write-Host -NoNewline "." } diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth.Client/dymaptic.GeoBlazor.Core.Sample.OAuth.Client.csproj b/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth.Client/dymaptic.GeoBlazor.Core.Sample.OAuth.Client.csproj index 3069e457d..b975e17ec 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth.Client/dymaptic.GeoBlazor.Core.Sample.OAuth.Client.csproj +++ b/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth.Client/dymaptic.GeoBlazor.Core.Sample.OAuth.Client.csproj @@ -2,11 +2,8 @@ net9.0 - enable - enable true Default - true diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/Components/App.razor b/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/Components/App.razor index 7e62d9074..0ac0ea974 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/Components/App.razor +++ b/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/Components/App.razor @@ -5,24 +5,11 @@ - @{ -#if ENABLE_COMPRESSION - } - @{ -#else - } - - - - - @{ -#endif - } diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/Program.cs b/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/Program.cs index f4ef327f0..376a37a91 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/Program.cs +++ b/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/Program.cs @@ -30,11 +30,8 @@ app.UseAntiforgery(); -#if ENABLE_COMPRESSION -app.MapStaticAssets(); -#else app.UseStaticFiles(); -#endif +app.MapStaticAssets(); app.MapRazorComponents() .AddInteractiveServerRenderMode() diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth.csproj b/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth.csproj index 7c841b53f..3ff1fc065 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth.csproj +++ b/samples/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth/dymaptic.GeoBlazor.Core.Sample.OAuth.csproj @@ -2,8 +2,6 @@ net9.0 - enable - enable aspnet-dymaptic.GeoBlazor.Core.Sample.OAuth-881b5a42-0b71-4c8c-9901-8d12693bd109 diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/HitTests.razor b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/HitTests.razor index 4187d614a..d82effc2e 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/HitTests.razor +++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/HitTests.razor @@ -64,7 +64,7 @@ { HitTestOptions options = new() { - IncludeByGeoBlazorId = new[] { _hurricaneLayer!.Id } + IncludeByGeoBlazorId = [_hurricaneLayer!.Id] }; HitTestResult result = await _mapView!.HitTest(pointerEvent, options); Graphic? graphic = result.Results.OfType().FirstOrDefault()?.Graphic; diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ManyGraphics.razor b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ManyGraphics.razor index 1caf501aa..4784210d9 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ManyGraphics.razor +++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ManyGraphics.razor @@ -52,7 +52,7 @@ { if (firstRender) { - _chunkSize = _view?.IsMaui == true ? 100 : 200; + _chunkSize = IsMaui ? 100 : 200; } } @@ -178,4 +178,5 @@ private string _geometryType = "Point"; private readonly List _graphics = new(); private bool _generating; + private bool IsMaui => _view?.JsRuntime!.GetType().Name.Contains("WebView") ?? false; } \ No newline at end of file diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ServerSideQueries.razor b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ServerSideQueries.razor index c1c7751c6..8f5dfad64 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ServerSideQueries.razor +++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ServerSideQueries.razor @@ -11,10 +11,9 @@

+ OnLayerViewCreate="OnLayerViewCreate" + Class="map-view"> @@ -29,7 +28,7 @@ Ymin="4536523.6511999965"> - + @@ -50,68 +49,55 @@ - @code { + + [Inject] + public required IJSRuntime JsRuntime { get; set; } private async Task OnLayerViewCreate(LayerViewCreateEvent createEvent) { if (createEvent.Layer?.Id == _featureLayer?.Id) { - PopupTemplate popupTemplate = await _featureLayer!.CreatePopupTemplate(); - await _featureLayer!.SetPopupTemplate(popupTemplate); await _mapView!.SetExtent(_featureLayer!.FullExtent!); } } private async Task OnClick(ClickEvent clickEvent) { - var query = new Query - { - Geometry = clickEvent.MapPoint, - Distance = Distance, - Units = Unit, - SpatialRelationship = SpatialRelationship.Intersects, - ReturnGeometry = false, - ReturnQueryGeometry = true, - OutFields = new HashSet { "*" } - }; + Query query = await _featureLayer!.CreateQuery(); + query.Geometry = clickEvent.MapPoint; + query.Distance = Distance; + query.Units = Unit; + query.SpatialRelationship = SpatialRelationship.Intersects; + query.ReturnGeometry = true; + query.ReturnQueryGeometry = true; + query.OutFields = ["*"]; + FeatureSet result = (await _featureLayer!.QueryFeatures(query))!; - await _pointGraphic.SetGeometry(clickEvent.MapPoint); - if (!_mapView!.Graphics.Contains(_pointGraphic)) - { - await _mapView.AddGraphic(_pointGraphic); - } + await _mapView!.ClearGraphics(); + Graphic pointGraphic = new(clickEvent.MapPoint, _markerSymbol); - if (result.QueryGeometry is not null) + if (_queryType == "distance") { - await _bufferGraphic.SetGeometry(result.QueryGeometry); - if (!_mapView.Graphics.Contains(_bufferGraphic)) - { - await _mapView.AddGraphic(_bufferGraphic); - } + Graphic buffer = new(result.QueryGeometry, _bufferSymbol); + await _mapView.AddGraphics([pointGraphic, buffer]); } - else if (_mapView.Graphics.Contains(_bufferGraphic)) + else { - await _mapView.RemoveGraphic(_bufferGraphic); + await _mapView.AddGraphic(pointGraphic); } - await _mapView.OpenPopup(new PopupOpenOptions - { - Location = clickEvent.MapPoint, - Features = result.Features, - FeatureMenuOpen = true - }); + await _popup!.SetFeatures(result.Features); } private double? Distance => _queryType == "distance" ? 0.5 : null; private QueryUnits? Unit => _queryType == "distance" ? QueryUnits.Miles : null; private MapView? _mapView; + private PopupWidget? _popup; private FeatureLayer? _featureLayer; - private readonly Graphic _pointGraphic = new(symbol: new SimpleMarkerSymbol( - new Outline(new MapColor(255, 255, 255), 1), - new MapColor(0, 0, 139))); - private readonly Graphic _bufferGraphic = new(symbol: new SimpleFillSymbol( - new Outline(new MapColor(255, 255, 255), 1.5), - new MapColor(173, 216, 230, 0.2))); + private readonly SimpleMarkerSymbol _markerSymbol = new(new Outline(new MapColor(255, 255, 255), 1), + new MapColor(0, 0, 139)); + private readonly SimpleFillSymbol _bufferSymbol = new(new Outline(new MapColor(255, 255, 255), 1.5), + new MapColor(173, 216, 230, 0.2)); private string? _queryType; } \ No newline at end of file diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/Tests.razor b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/Tests.razor index 4690fc13a..083e1309a 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/Tests.razor +++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/Tests.razor @@ -148,29 +148,27 @@ } private MapView? _view; - private readonly FeatureLayer _localFeatureLayer = new(source: new[] - { - new Graphic(new Point(11.967162, 49.201448), + private readonly FeatureLayer _localFeatureLayer = new(source: + [ + new Graphic(new Point(11.967162, 49.201448), new SimpleMarkerSymbol(new Outline(new MapColor("white")), new MapColor("red"), 6)) - }, + ], objectIdField: "OBJECTID"); private readonly FeatureLayer _remoteFeatureLayer = new("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/weather_stations_010417/FeatureServer/0"); - private readonly GraphicsLayer _graphicsLayer = new(new[] - { + private readonly GraphicsLayer _graphicsLayer = new([ new Graphic(new Point(11.888650, 52.451825), new SimpleMarkerSymbol(new Outline(new MapColor("white")), new MapColor("green"), 6)), - new Graphic(new Polyline(new[] - { - new MapPath(new MapPoint(11, 52), + new Graphic(new Polyline([ + new MapPath(new MapPoint(11, 52), new MapPoint(11.5, 53), new MapPoint(12, 55), new MapPoint(10, 55), new MapPoint(10.5, 51), new MapPoint(11, 56)) - }), + ]), new SimpleLineSymbol(new MapColor("blue"), 2)), new Graphic(new Point(7.274721, 59.614991), new PictureMarkerSymbol("https://static.arcgis.com/images/Symbols/Shapes/BluePin1LargeB.png", @@ -178,7 +176,7 @@ new Graphic(new Point(29.437639, 55.469513), new TextSymbol("Hello World", new MapColor("red"), new MapColor("yellow"), 12)) - }); + ]); private async void On3Click(ClickEvent clickEvent) { @@ -206,8 +204,8 @@ private bool _map3Rendered; private bool _showGraphicsMarkupLayer; private readonly Random _random = new(); - private readonly List _lats = new() { 49.201448, 52.451825, 59.614991, 55.469513 }; - private readonly List _longs = new() { 11.967162, 11.888650, 7.274721, 29.437639 }; + private readonly List _lats = [49.201448, 52.451825, 59.614991, 55.469513]; + private readonly List _longs = [11.967162, 11.888650, 7.274721, 29.437639]; private MapView? _view3; private int _graphicsCount = 1; } \ No newline at end of file diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/WFSLayers.razor b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/WFSLayers.razor index bcf3d1ca6..8a6faf149 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/WFSLayers.razor +++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/WFSLayers.razor @@ -4,22 +4,28 @@

To create a WFSLayer, all you need is the URL to a WFS service that supports WFS 2.0.0 and has GeoJSON output format enabled. Optionally, you can set the name to the FeatureType you want to access in the service. If no name is provided, the layer will default to the first FeatureType in the service.

+

+ Source: Office for National Statistics licensed under the Open Government Licence v.3.0 +

+

+ Contains OS data © Crown copyright and database right @DateTime.Now.Year +

+ Longitude="-2" + Latitude="53" + Zoom="5"> - diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Shared/NavMenu.razor.cs b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Shared/NavMenu.razor.cs index 99f584103..b9a85f5e4 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Shared/NavMenu.razor.cs +++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Shared/NavMenu.razor.cs @@ -4,7 +4,7 @@ namespace dymaptic.GeoBlazor.Core.Sample.Shared.Shared; -public partial class NavMenu: IDisposable +public partial class NavMenu { [Inject] public required IJSRuntime JsRuntime { get; set; } @@ -21,17 +21,6 @@ public partial class NavMenu: IDisposable protected IEnumerable FilteredPages => string.IsNullOrWhiteSpace(SearchText) ? Pages : Pages.Where(p => p.Title.Contains(SearchText, StringComparison.OrdinalIgnoreCase)); - - public void Dispose() - { - _dotNetRef?.Dispose(); - } - - [JSInvokable] - public void OnScroll(double scrollTop) - { - _scrollTop = scrollTop; - } protected override async Task OnAfterRenderAsync(bool firstRender) { @@ -47,9 +36,12 @@ protected override async Task OnAfterRenderAsync(bool firstRender) string currentPage = NavigationManager .ToBaseRelativePath(NavigationManager.Uri) .Replace("source-code/", ""); - await JsRuntime.InvokeVoidAsync("scrollToNav", currentPage); - _dotNetRef = DotNetObjectReference.Create(this); - await JsRuntime.InvokeVoidAsync("trackScrollPosition", Navbar, _dotNetRef); + + if (currentPage != string.Empty) + { + await JsRuntime.InvokeVoidAsync("scrollToNav", currentPage); + } + StateHasChanged(); } @@ -89,8 +81,6 @@ await InvokeAsync(async () => protected virtual bool CollapseNavMenu { get; set; } = true; protected ElementReference? Navbar; - private DotNetObjectReference? _dotNetRef; - private double _scrollTop; public virtual PageLink[] Pages => [ new("", "Home", "oi-home"), diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/wwwroot/functions.js b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/wwwroot/functions.js index ee6861ed6..6615257b5 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/wwwroot/functions.js +++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/wwwroot/functions.js @@ -1,33 +1,4 @@ -let navbarRef; -let navbar; - -window.trackScrollPosition = (navbarElem, dotNetRef) => { - navbar = navbarElem; - navbarRef = dotNetRef; - navbar.addEventListener('scroll', onScroll); - // Initial call to set the position - _ = onScroll(); -} - -window.removeScrollTracking = () => { - if (navbar) { - navbar.removeEventListener('scroll', onScroll); - navbar = null; - } - navbarRef = null; -} - -window.scrollToPosition = (position) => { - if (navbar) { - navbar.scrollTop = position; - } -} - -async function onScroll() { - await navbarRef.invokeMethodAsync('OnScroll', navbar.scrollTop); -} - -window.scrollToNav = (page) => { +window.scrollToNav = (page) => { let navItems = document.getElementsByTagName('a'); let navItem = Array.from(navItems).find(i => i.href.endsWith(page)); if (navigator.userAgent.indexOf('Firefox') === -1) { diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.Client/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.Client.csproj b/samples/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.Client/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.Client.csproj index 2a264af04..30734100f 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.Client/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.Client.csproj +++ b/samples/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.Client/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.Client.csproj @@ -2,8 +2,6 @@ net9.0 - enable - enable true Default diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.csproj b/samples/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.csproj index bcc4c0109..7823798f2 100644 --- a/samples/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.csproj +++ b/samples/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh/dymaptic.GeoBlazor.Core.Sample.TokenRefresh.csproj @@ -2,8 +2,6 @@ net9.0 - enable - enable 09852c49-58ad-4029-956b-1e18661fd6b3 diff --git a/src/.editorconfig b/src/.editorconfig index b499c6efd..16ef9aec1 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -130,7 +130,7 @@ csharp_style_prefer_readonly_struct_member = true csharp_prefer_braces = true csharp_prefer_simple_using_statement = true csharp_prefer_system_threading_lock = true -csharp_style_namespace_declarations = block_scoped +csharp_style_namespace_declarations = file_scoped csharp_style_prefer_method_group_conversion = true csharp_style_prefer_primary_constructors = true csharp_style_prefer_simple_property_accessors = true diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator/Properties/launchSettings.json b/src/dymaptic.GeoBlazor.Core.SourceGenerator/Properties/launchSettings.json new file mode 100644 index 000000000..bfb3c206b --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator/Properties/launchSettings.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "Generators": { + "commandName": "DebugRoslynComponent", + "targetProject": "../../test/dymaptic.GeoBlazor.Core.SourceGenerator.Tests/dymaptic.GeoBlazor.Core.SourceGenerator.Tests.csproj" + } + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator/ProtobufSourceGenerator.cs b/src/dymaptic.GeoBlazor.Core.SourceGenerator/ProtobufSourceGenerator.cs index 40abeecf1..fbdf13f9f 100644 --- a/src/dymaptic.GeoBlazor.Core.SourceGenerator/ProtobufSourceGenerator.cs +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator/ProtobufSourceGenerator.cs @@ -51,39 +51,40 @@ private void FilesChanged(SourceProductionContext context, ((ImmutableArray Types, string? ProjectDirectory) Data, Compilation Compilation) pipeline) { - // Skip if not running from the Core project if (pipeline.Compilation.AssemblyName != "dymaptic.GeoBlazor.Core") - { - return; - } - - // Skip source generation if the project path is not available - if (string.IsNullOrEmpty(pipeline.Data.ProjectDirectory)) { ProcessHelper.Log(nameof(ProtobufSourceGenerator), - "CoreProjectPath not set. Skipping protobuf source generation.", - DiagnosticSeverity.Warning, + $"Run from project {pipeline.Compilation.AssemblyName}.", + DiagnosticSeverity.Info, context); - return; + + _isTest = true; } - // Log that protobuf types were found (infrastructure ready for future implementation) + _corePath = pipeline.Data.ProjectDirectory; + + ProcessHelper.Log(nameof(ProtobufSourceGenerator), + "Source Generation triggered.", + DiagnosticSeverity.Info, + context); + if (pipeline.Data.Types.Length > 0) { - ProcessHelper.Log(nameof(ProtobufSourceGenerator), - $"Found {pipeline.Data.Types.Length} protobuf-serializable types.", - DiagnosticSeverity.Info, - context); + var protoDefinitions = ProtobufDefinitionsGenerator + .UpdateProtobufDefinitions(context, pipeline.Data.Types, _corePath!); + + context.CancellationToken.ThrowIfCancellationRequested(); - // TODO: Generate protobuf serialization records and registration code. - // This will include: - // 1. Generating *SerializationRecord classes for each protobuf-attributed type - // 2. Generating ToProtobuf()/FromProtobuf() extension methods - // 3. Generating JsSyncManager registration code for ProtoContractTypes dictionary - // 4. Copying .proto definitions to TypeScript for JS-side deserialization + SerializationGenerator.GenerateSerializationDataClass(context, + pipeline.Data.Types, protoDefinitions, false, + _isTest); + + context.CancellationToken.ThrowIfCancellationRequested(); } } + private static string? _corePath; + private static bool _isTest; private const string ProtoContractAttribute = "ProtoContract"; private const string ProtoSerializableAttribute = "ProtobufSerializable"; private const string SerializedMethodAttributeName = "SerializedMethod"; diff --git a/src/dymaptic.GeoBlazor.Core.sln b/src/dymaptic.GeoBlazor.Core.sln index 94fea22b8..d6770235b 100644 --- a/src/dymaptic.GeoBlazor.Core.sln +++ b/src/dymaptic.GeoBlazor.Core.sln @@ -42,6 +42,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dymaptic.GeoBlazor.Core.Sam EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dymaptic.GeoBlazor.Core.Analyzers", "dymaptic.GeoBlazor.Core.Analyzers\dymaptic.GeoBlazor.Core.Analyzers.csproj", "{468F9CE4-A24F-4EE0-9C5B-2AF88A369C30}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dymaptic.GeoBlazor.Core.SourceGenerator.Shared", "dymaptic.GeoBlazor.Core.SourceGenerator.Shared\dymaptic.GeoBlazor.Core.SourceGenerator.Shared.csproj", "{8FDFC824-2365-4467-9326-DFDFF6D6B775}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -258,6 +260,18 @@ Global {468F9CE4-A24F-4EE0-9C5B-2AF88A369C30}.Release|x64.Build.0 = Release|Any CPU {468F9CE4-A24F-4EE0-9C5B-2AF88A369C30}.Release|x86.ActiveCfg = Release|Any CPU {468F9CE4-A24F-4EE0-9C5B-2AF88A369C30}.Release|x86.Build.0 = Release|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Debug|x64.ActiveCfg = Debug|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Debug|x64.Build.0 = Debug|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Debug|x86.ActiveCfg = Debug|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Debug|x86.Build.0 = Debug|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Release|Any CPU.Build.0 = Release|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Release|x64.ActiveCfg = Release|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Release|x64.Build.0 = Release|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Release|x86.ActiveCfg = Release|Any CPU + {8FDFC824-2365-4467-9326-DFDFF6D6B775}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/dymaptic.GeoBlazor.Core/Components/ActionBase.cs b/src/dymaptic.GeoBlazor.Core/Components/ActionBase.cs index 01b7613e5..8bdff5798 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/ActionBase.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/ActionBase.cs @@ -2,7 +2,8 @@ namespace dymaptic.GeoBlazor.Core.Components; [JsonConverter(typeof(ActionBaseConverter))] [CodeGenerationIgnore] -public abstract partial class ActionBase : MapComponent +[ProtobufSerializable] +public abstract partial class ActionBase : MapComponent, IProtobufSerializable { /// /// The title of the action. @@ -65,92 +66,8 @@ public async Task OnJsTriggerAction(PopupTriggerActionEvent triggerActionEvent) /// public abstract string Type { get; } - internal abstract ActionBaseSerializationRecord ToSerializationRecord(); -} - -[ProtoContract(Name = "Action")] -internal record ActionBaseSerializationRecord : MapComponentSerializationRecord -{ - public ActionBaseSerializationRecord() - { - } - - public ActionBaseSerializationRecord(string Id, - string Type, - string? Title, - string? ClassName, - bool? Active, - bool? Disabled, - bool? Visible, - string? ActionId) - { - this.Id = Id; - this.Type = Type; - this.Title = Title; - this.ClassName = ClassName; - this.Active = Active; - this.Disabled = Disabled; - this.Visible = Visible; - this.ActionId = ActionId; - } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(1)] - public string Type { get; init; } = string.Empty; - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public string? Title { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public string? ClassName { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(4)] - public bool? Active { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(5)] - public bool? Disabled { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(6)] - public bool? Visible { get; init; } - - [ProtoMember(7)] - public string? Id { get; init; } - - [ProtoMember(8)] - public string? Image { get; init; } - - [ProtoMember(9)] - public bool? Value { get; init; } - - [ProtoMember(10)] - public string? ActionId { get; init; } - - public ActionBase FromSerializationRecord() - { - Guid id = Guid.NewGuid(); - if (Guid.TryParse(Id, out Guid guidId)) - { - id = guidId; - } - - return Type switch - { - "button" => new ActionButton(Title, Image, ActionId, null, ClassName, Active, Disabled, Visible) - { - Id = id - }, - "toggle" => new ActionToggle(Title, ActionId, null, Value, Active, Disabled, Visible) - { - Id = id - }, - _ => throw new NotSupportedException() - }; - } + /// + public abstract ActionBaseSerializationRecord ToProtobuf(); } internal class ActionBaseConverter : JsonConverter diff --git a/src/dymaptic.GeoBlazor.Core/Components/ActionButton.cs b/src/dymaptic.GeoBlazor.Core/Components/ActionButton.cs index 3e67715c3..ac748e136 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/ActionButton.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/ActionButton.cs @@ -1,10 +1,9 @@ namespace dymaptic.GeoBlazor.Core.Components; [CodeGenerationIgnore] +[ProtobufSerializable] public partial class ActionButton : ActionBase { - - /// public override string Type => "button"; @@ -15,7 +14,8 @@ public partial class ActionButton : ActionBase [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Image { get; set; } - internal override ActionBaseSerializationRecord ToSerializationRecord() + /// + public override ActionBaseSerializationRecord ToProtobuf() { return new ActionBaseSerializationRecord(Id.ToString(), Type, Title, ClassName, Active, Disabled, Visible, ActionId) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/ActionToggle.cs b/src/dymaptic.GeoBlazor.Core/Components/ActionToggle.cs index 1d3314604..a3b94f848 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/ActionToggle.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/ActionToggle.cs @@ -1,10 +1,9 @@ namespace dymaptic.GeoBlazor.Core.Components; [CodeGenerationIgnore] +[ProtobufSerializable] public partial class ActionToggle : ActionBase { - - /// public override string Type => "toggle"; @@ -15,7 +14,8 @@ public partial class ActionToggle : ActionBase [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public bool? Value { get; set; } - internal override ActionBaseSerializationRecord ToSerializationRecord() + /// + public override ActionBaseSerializationRecord ToProtobuf() { return new ActionBaseSerializationRecord(Id.ToString(), Type, Title, null, Active, Disabled, Visible, ActionId) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/BarChartMediaInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/BarChartMediaInfo.cs index 94f144631..a1222d8fc 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/BarChartMediaInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/BarChartMediaInfo.cs @@ -1,21 +1,20 @@ namespace dymaptic.GeoBlazor.Core.Components; +[ProtobufSerializable] public partial class BarChartMediaInfo : MediaInfo { - - /// public override string Type => "bar-chart"; - - internal override MediaInfoSerializationRecord ToSerializationRecord() + /// + public override MediaInfoSerializationRecord ToProtobuf() { return new MediaInfoSerializationRecord(Id.ToString(), "bar-chart") { AltText = AltText, Caption = Caption, Title = Title, - Value = Value?.ToSerializationRecord() + Value = Value?.ToProtobuf() }; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/BookmarksViewModel.cs b/src/dymaptic.GeoBlazor.Core/Components/BookmarksViewModel.cs index 0c0f142b9..b7826fb6e 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/BookmarksViewModel.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/BookmarksViewModel.cs @@ -22,7 +22,7 @@ public partial class BookmarksViewModel : MapComponent, IViewModel [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters != null) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/ChartMediaInfoValue.cs b/src/dymaptic.GeoBlazor.Core/Components/ChartMediaInfoValue.cs index 41c5014bc..f4993d96e 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/ChartMediaInfoValue.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/ChartMediaInfoValue.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components; -public partial class ChartMediaInfoValue : MapComponent +[ProtobufSerializable] +public partial class ChartMediaInfoValue : MapComponent, IMediaInfoValue { - - /// /// A string containing the name of a field. The values of all fields in the chart will be normalized (divided) by the value of this field. /// @@ -17,79 +16,11 @@ public partial class ChartMediaInfoValue : MapComponent [Parameter] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? TooltipField { get; set; } - - - internal ChartMediaInfoValueSerializationRecord ToSerializationRecord() - { - return new ChartMediaInfoValueSerializationRecord(Id.ToString(), Fields, NormalizeField, TooltipField, - Series?.Select(s => s.ToSerializationRecord())); - } -} - -[ProtoContract(Name = "ChartMediaInfoValue")] -internal record ChartMediaInfoValueSerializationRecord : MapComponentSerializationRecord -{ - public ChartMediaInfoValueSerializationRecord() - { - } - - public ChartMediaInfoValueSerializationRecord(string Id, IEnumerable? Fields = null, - string? NormalizeField = null, string? TooltipField = null, - IEnumerable? Series = null, string? LinkURL = null, - string? SourceURL = null) - { - this.Id = Id; - this.Fields = Fields; - this.NormalizeField = NormalizeField; - this.TooltipField = TooltipField; - this.Series = Series; - this.LinkURL = LinkURL; - this.SourceURL = SourceURL; - } - - public object FromSerializationRecord() + + /// + public MediaInfoValueSerializationRecord ToProtobuf() { - Guid id = Guid.NewGuid(); - if (Guid.TryParse(Id, out Guid guid)) - { - id = guid; - } - - if (LinkURL is not null || SourceURL is not null) - { - return new ImageMediaInfoValue(LinkURL, SourceURL) { Id = id }; - } - - return new ChartMediaInfoValue(Fields?.ToArray(), NormalizeField, TooltipField, - Series?.Select(s => s.FromSerializationRecord()).ToArray()) - { - Id = id - }; + return new MediaInfoValueSerializationRecord(Id.ToString(), Fields, NormalizeField, TooltipField, + Series?.Select(s => s.ToProtobuf())); } - - [ProtoMember(1)] - public IEnumerable? Fields { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public string? NormalizeField { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public string? TooltipField { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(4)] - public IEnumerable? Series { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(5)] - public string? LinkURL { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(6)] - public string? SourceURL { get; init; } - - [ProtoMember(7)] - public string? Id { get; init; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/ChartMediaInfoValueSeries.cs b/src/dymaptic.GeoBlazor.Core/Components/ChartMediaInfoValueSeries.cs index 791b8543c..a57ddab4c 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/ChartMediaInfoValueSeries.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/ChartMediaInfoValueSeries.cs @@ -1,6 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components; -public partial class ChartMediaInfoValueSeries : MapComponent +[ProtobufSerializable] +public partial class ChartMediaInfoValueSeries : MapComponent, + IProtobufSerializable { @@ -24,50 +26,10 @@ public partial class ChartMediaInfoValueSeries : MapComponent [Parameter] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public double? Value { get; set; } - - internal ChartMediaInfoValueSeriesSerializationRecord ToSerializationRecord() + + /// + public ChartMediaInfoValueSeriesSerializationRecord ToProtobuf() { return new ChartMediaInfoValueSeriesSerializationRecord(Id.ToString(), FieldName, Tooltip, Value); } -} - -[ProtoContract(Name = "ChartMediaInfoValueSeries")] -internal record ChartMediaInfoValueSeriesSerializationRecord : MapComponentSerializationRecord -{ - public ChartMediaInfoValueSeriesSerializationRecord() - { - } - - public ChartMediaInfoValueSeriesSerializationRecord(string Id, string? FieldName, string? Tooltip, double? Value) - { - this.Id = Id; - this.FieldName = FieldName; - this.Tooltip = Tooltip; - this.Value = Value; - } - - public ChartMediaInfoValueSeries FromSerializationRecord() - { - Guid id = Guid.NewGuid(); - if (Guid.TryParse(Id, out Guid guid)) - { - id = guid; - } - return new ChartMediaInfoValueSeries(FieldName, Tooltip, Value) { Id = id }; - } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(1)] - public string? FieldName { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public string? Tooltip { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public double? Value { get; init; } - - [ProtoMember(4)] - public string? Id { get; init; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Circle.cs b/src/dymaptic.GeoBlazor.Core/Components/Circle.cs index ca78ef636..90c0e9116 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Circle.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Circle.cs @@ -1,5 +1,6 @@ namespace dymaptic.GeoBlazor.Core.Components; +[ProtobufSerializable] public partial class Circle { // Add custom code to this file to override generated code @@ -116,18 +117,19 @@ public Circle( [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [CodeGenerationIgnore] public int? NumberOfPoints { get; set; } - - internal override GeometrySerializationRecord ToSerializationRecord() + + /// + public override GeometrySerializationRecord ToProtobuf() { return new GeometrySerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), - Extent?.ToSerializationRecord(), - SpatialReference?.ToSerializationRecord()) + Extent?.ToProtobuf(), + SpatialReference?.ToProtobuf()) { - Rings = Rings.Select(p => p.ToSerializationRecord()).ToArray(), + Rings = Rings.Select(p => p.ToProtobuf()).ToArray(), HasM = HasM, HasZ = HasZ, - Centroid = Centroid?.ToSerializationRecord(), - Center = Center?.ToSerializationRecord(), + Centroid = Centroid?.ToProtobuf(), + Center = Center?.ToProtobuf(), Geodesic = Geodesic, NumberOfPoints = NumberOfPoints, Radius = Radius, diff --git a/src/dymaptic.GeoBlazor.Core/Components/ColumnChartMediaInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/ColumnChartMediaInfo.cs index d5c34d31e..e9b9a5c15 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/ColumnChartMediaInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/ColumnChartMediaInfo.cs @@ -1,21 +1,20 @@ namespace dymaptic.GeoBlazor.Core.Components; +[ProtobufSerializable] public partial class ColumnChartMediaInfo : MediaInfo { - - /// public override string Type => "column-chart"; - - internal override MediaInfoSerializationRecord ToSerializationRecord() + /// + public override MediaInfoSerializationRecord ToProtobuf() { return new MediaInfoSerializationRecord(Id.ToString(), "column-chart") { AltText = AltText, Caption = Caption, Title = Title, - Value = Value?.ToSerializationRecord() + Value = Value?.ToProtobuf() }; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/CompassViewModel.cs b/src/dymaptic.GeoBlazor.Core/Components/CompassViewModel.cs index 935cd78ba..ed9094d71 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/CompassViewModel.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/CompassViewModel.cs @@ -22,7 +22,7 @@ public partial class CompassViewModel: IViewModel [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); diff --git a/src/dymaptic.GeoBlazor.Core/Components/ElementExpressionInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/ElementExpressionInfo.cs index c2f78e6fb..e34913e9f 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/ElementExpressionInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/ElementExpressionInfo.cs @@ -1,36 +1,13 @@ namespace dymaptic.GeoBlazor.Core.Components; -public partial class ElementExpressionInfo +[ProtobufSerializable] +public partial class ElementExpressionInfo: IProtobufSerializable { // Add custom code to this file to override generated code - internal ElementExpressionInfoSerializationRecord ToSerializationRecord() + /// + public ElementExpressionInfoSerializationRecord ToProtobuf() { - return new ElementExpressionInfoSerializationRecord(Expression, Title); + return new ElementExpressionInfoSerializationRecord(Expression, Title); } -} - -[ProtoContract(Name = "ElementExpressionInfo")] -internal record ElementExpressionInfoSerializationRecord: MapComponentSerializationRecord -{ - public ElementExpressionInfoSerializationRecord() - { - } - - public ElementExpressionInfoSerializationRecord(string? expression, string? title) - { - Expression = expression; - Title = title; - } - - [ProtoMember(1)] - public string? Expression { get; init; } - - [ProtoMember(2)] - public string? Title { get; init; } - - public ElementExpressionInfo FromSerializationRecord() - { - return new ElementExpressionInfo(Expression, Title); - } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/FeaturesViewModel.cs b/src/dymaptic.GeoBlazor.Core/Components/FeaturesViewModel.cs index dd34cdba1..ab91acf82 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/FeaturesViewModel.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/FeaturesViewModel.cs @@ -21,7 +21,7 @@ public partial class FeaturesViewModel : IViewModel [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/FeaturesViewModel.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/FeaturesViewModel.gb.cs index be012c8fd..30c75926d 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/FeaturesViewModel.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/FeaturesViewModel.gb.cs @@ -3338,7 +3338,7 @@ public async Task OnJsTriggerAction(IJSStreamReference jsStreamRef) return; } - FeaturesViewModelTriggerActionEvent? triggerActionEvent = await jsStreamRef.ReadJsStreamReference(); + FeaturesViewModelTriggerActionEvent? triggerActionEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (triggerActionEvent is not null) { await OnTriggerAction.InvokeAsync(triggerActionEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/FieldInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/FieldInfo.cs index 013c1e716..4d06e1f6e 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/FieldInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/FieldInfo.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components; -public partial class FieldInfo : MapComponent +[ProtobufSerializable] +public partial class FieldInfo : MapComponent, IProtobufSerializable { - - /// /// The field name as defined by the service or the name of an Arcade expression. /// @@ -38,84 +37,11 @@ public partial class FieldInfo : MapComponent [Parameter] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public StringFieldOption? StringFieldOption { get; set; } - - - internal FieldInfoSerializationRecord ToSerializationRecord() + + /// + public FieldInfoSerializationRecord ToProtobuf() { return new FieldInfoSerializationRecord(Id.ToString(), FieldName, Label, Tooltip, - StringFieldOption?.ToString().ToKebabCase(), Format?.ToSerializationRecord(), IsEditable, Visible); - } -} - -[ProtoContract(Name = "FieldInfo")] -internal record FieldInfoSerializationRecord : MapComponentSerializationRecord -{ - public FieldInfoSerializationRecord() - { + StringFieldOption?.ToString().ToKebabCase(), Format?.ToProtobuf(), IsEditable, Visible); } - - public FieldInfoSerializationRecord(string Id, string? FieldName = null, string? Label = null, - string? Tooltip = null, string? StringFieldOption = null, FieldInfoFormatSerializationRecord? Format = null, - bool? IsEditable = null, bool? Visible = null) - { - this.Id = Id; - this.FieldName = FieldName; - this.Label = Label; - this.Tooltip = Tooltip; - this.StringFieldOption = StringFieldOption; - this.Format = Format; - this.IsEditable = IsEditable; - this.Visible = Visible; - } - - public FieldInfo FromSerializationRecord() - { - Guid id = Guid.NewGuid(); - if (Guid.TryParse(Id, out Guid guid)) - { - id = guid; - } - StringFieldOption? sfo = StringFieldOption switch - { - "rich-text" => Enums.StringFieldOption.RichText, - "text-area" => Enums.StringFieldOption.TextArea, - "text-box" => Enums.StringFieldOption.TextBox, - _ => null - }; - return new FieldInfo(FieldName, Label, Tooltip, sfo, Format?.FromSerializationRecord(), IsEditable, Visible) - { - Id = id - }; - } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(1)] - public string? FieldName { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public string? Label { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public string? Tooltip { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(4)] - public string? StringFieldOption { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(5)] - public FieldInfoFormatSerializationRecord? Format { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(6)] - public bool? IsEditable { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(7)] - public bool? Visible { get; init; } - - [ProtoMember(8)] - public string? Id { get; init; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/FieldInfoFormat.cs b/src/dymaptic.GeoBlazor.Core/Components/FieldInfoFormat.cs index bc7cdba41..b99bb59c3 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/FieldInfoFormat.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/FieldInfoFormat.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components; -public partial class FieldInfoFormat : MapComponent +[ProtobufSerializable] +public partial class FieldInfoFormat : MapComponent, IProtobufSerializable { - - /// /// Used only with Number fields to specify the number of supported decimal places that should appear in popups. /// @@ -25,7 +24,8 @@ public partial class FieldInfoFormat : MapComponent [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public DateFormat? DateFormat { get; set; } - internal FieldInfoFormatSerializationRecord ToSerializationRecord() + /// + public FieldInfoFormatSerializationRecord ToProtobuf() { string? dateFormat = DateFormat switch { @@ -61,78 +61,4 @@ internal FieldInfoFormatSerializationRecord ToSerializationRecord() }; return new FieldInfoFormatSerializationRecord(Id.ToString(), Places, DigitSeparator, dateFormat); } -} - -[ProtoContract(Name = "FieldInfoFormat")] -internal record FieldInfoFormatSerializationRecord : MapComponentSerializationRecord -{ - public FieldInfoFormatSerializationRecord() - { - } - - public FieldInfoFormatSerializationRecord(string Id, - int? Places, - bool? DigitSeparator, - string? DateFormat) - { - this.Id = Id; - this.Places = Places; - this.DigitSeparator = DigitSeparator; - this.DateFormat = DateFormat; - } - - public FieldInfoFormat FromSerializationRecord() - { - Guid id = Guid.NewGuid(); - if (Guid.TryParse(Id, out Guid guidId)) - { - id = guidId; - } - DateFormat? df = DateFormat switch - { - "short-date" => Enums.DateFormat.ShortDate, - "short-date-short-time.cs" => Enums.DateFormat.ShortDateShortTime, - "short-date-short-time-24" => Enums.DateFormat.ShortDateShortTime24, - "short-date-long-time" => Enums.DateFormat.ShortDateLongTime, - "short-date-long-time-24" => Enums.DateFormat.ShortDateLongTime24, - "short-date-le" => Enums.DateFormat.ShortDateLe, - "short-date-le-short-time" => Enums.DateFormat.ShortDateLeShortTime, - "short-date-le-short-time-24" => Enums.DateFormat.ShortDateLeShortTime24, - "short-date-le-long-time" => Enums.DateFormat.ShortDateLeLongTime, - "short-date-le-long-time-24" => Enums.DateFormat.ShortDateLeLongTime24, - "long-month-day-year" => Enums.DateFormat.LongMonthDayYear, - "long-month-day-year-short-time" => Enums.DateFormat.LongMonthDayYearShortTime, - "long-month-day-year-short-time-24" => Enums.DateFormat.LongMonthDayYearShortTime24, - "long-month-day-year-long-time" => Enums.DateFormat.LongMonthDayYearLongTime, - "long-month-day-year-long-time-24" => Enums.DateFormat.LongMonthDayYearLongTime24, - "day-short-month-year" => Enums.DateFormat.DayShortMonthYear, - "day-short-month-year-short-time" => Enums.DateFormat.DayShortMonthYearShortTime, - "day-short-month-year-short-time-24" => Enums.DateFormat.DayShortMonthYearShortTime24, - "day-short-month-year-long-time" => Enums.DateFormat.DayShortMonthYearLongTime, - "day-short-month-year-long-time-24" => Enums.DateFormat.DayShortMonthYearLongTime24, - "long-date" => Enums.DateFormat.LongDate, - "long-date-short-time" => Enums.DateFormat.LongDateShortTime, - "long-date-short-time-24" => Enums.DateFormat.LongDateShortTime24, - "long-date-long-time" => Enums.DateFormat.LongDateLongTime, - "long-date-long-time-24" => Enums.DateFormat.LongDateLongTime24, - "long-month-year" => Enums.DateFormat.LongMonthYear, - "short-month-year" => Enums.DateFormat.ShortMonthYear, - "year" => Enums.DateFormat.Year, - _ => null - }; - return new FieldInfoFormat(Places, DigitSeparator, df) { Id = id }; - } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(1)] - public int? Places { get; init; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public bool? DigitSeparator { get; init; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public string? DateFormat { get; init; } - - [ProtoMember(4)] - public string? Id { get; init; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Extent.cs b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Extent.cs index a3b5a7ba1..974b72fc9 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Extent.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Extent.cs @@ -1,5 +1,6 @@ namespace dymaptic.GeoBlazor.Core.Components.Geometries; +[ProtobufSerializable] public partial class Extent : Geometry { /// @@ -131,10 +132,11 @@ public Extent Clone() return new Extent(Xmax, Xmin, Ymax, Ymin, Zmax, Zmin, Mmax, Mmin, SpatialReference?.Clone()); } - internal override GeometrySerializationRecord ToSerializationRecord() + /// + public override GeometrySerializationRecord ToProtobuf() { return new GeometrySerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), null, - SpatialReference?.ToSerializationRecord()) + SpatialReference?.ToProtobuf()) { Xmax = Xmax, Xmin = Xmin, diff --git a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Geometry.cs b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Geometry.cs index 5425cde14..4de14fa63 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Geometry.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Geometry.cs @@ -1,7 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Geometries; [JsonConverter(typeof(GeometryConverter))] -public abstract partial class Geometry : MapComponent +[ProtobufSerializable] +public abstract partial class Geometry : MapComponent, IProtobufSerializable { /// /// The of the geometry. @@ -128,207 +129,7 @@ public override void ValidateRequiredChildren() #pragma warning restore BL0005 return Extent; } - - internal abstract GeometrySerializationRecord ToSerializationRecord(); -} - -[ProtoContract(Name = "Geometry")] -internal record GeometrySerializationRecord : MapComponentSerializationRecord -{ - public GeometrySerializationRecord() - { - } - - public GeometrySerializationRecord(string Id, string Type, GeometrySerializationRecord? Extent, - SpatialReferenceSerializationRecord? SpatialReference) - { - this.Id = Id; - this.Type = Type; - this.Extent = Extent; - this.SpatialReference = SpatialReference; - } - - [ProtoMember(1)] - public string Type { get; set; } = string.Empty; - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public GeometrySerializationRecord? Extent { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public SpatialReferenceSerializationRecord? SpatialReference { get; set; } - - [ProtoMember(4)] - public double? Longitude { get; set; } - - [ProtoMember(5)] - public double? Latitude { get; set; } - - [ProtoMember(6)] - public double? X { get; set; } - - [ProtoMember(7)] - public double? Y { get; set; } - - [ProtoMember(8)] - public double? Z { get; set; } - - [ProtoMember(9)] - public MapPathSerializationRecord[]? Paths { get; set; } - - [ProtoMember(10)] - public MapPathSerializationRecord[]? Rings { get; set; } - - [ProtoMember(11)] - public double? Xmax { get; set; } - - [ProtoMember(12)] - public double? Xmin { get; set; } - - [ProtoMember(13)] - public double? Ymax { get; set; } - - [ProtoMember(14)] - public double? Ymin { get; set; } - - [ProtoMember(15)] - public double? Zmax { get; set; } - - [ProtoMember(16)] - public double? Zmin { get; set; } - - [ProtoMember(17)] - public double? Mmax { get; set; } - - [ProtoMember(18)] - public double? Mmin { get; set; } - - [ProtoMember(19)] - public bool? HasM { get; set; } - - [ProtoMember(20)] - public bool? HasZ { get; set; } - - [ProtoMember(21)] - public double? M { get; set; } - - [ProtoMember(22)] - public GeometrySerializationRecord? Centroid { get; set; } - - [ProtoMember(23)] - public bool? IsSelfIntersecting { get; set; } - - [ProtoMember(24)] - public GeometrySerializationRecord? Center { get; set; } - - [ProtoMember(25)] - public bool? Geodesic { get; set; } - - [ProtoMember(26)] - public int? NumberOfPoints { get; set; } - - [ProtoMember(27)] - public double? Radius { get; set; } - [ProtoMember(28)] - public string? RadiusUnit { get; set; } - - [ProtoMember(29)] - public string? Id { get; set; } - - /// - /// Multipoint geometry points. - /// - [ProtoMember(30)] - public MapPointSerializationRecord[]? Points { get; set; } - - [ProtoMember(31)] - public bool? IsSimple { get; set; } - - public Geometry FromSerializationRecord() - { - Extent? extent = Extent?.FromSerializationRecord() as Extent; - Guid id = Guid.NewGuid(); - - if (Guid.TryParse(Id, out Guid guidId)) - { - id = guidId; - } - - if (Type == "multipoint") - { - // Multipoint is in GeoBlazor Pro assembly, so we need to use reflection to get the type - Type? multipointType = System.Type.GetType("dymaptic.GeoBlazor.Pro.Components.Geometries.Multipoint, " + - "dymaptic.GeoBlazor.Pro"); - - if (multipointType is not null && multipointType.IsSubclassOf(typeof(Geometry))) - { - Point[]? points = Points?.Select(p => - { - MapPoint mp = p.FromSerializationRecord(); - - return new Point(x: mp[0], y: mp[1]); - }) - .ToArray(); - - if (Activator.CreateInstance(multipointType, - args: [HasM, HasZ, points, SpatialReference?.FromSerializationRecord()]) - is not Geometry multipoint) - { - throw new InvalidOperationException( - "Multipoint could not be created. Ensure the type is correct and the assembly is loaded."); - } - multipoint.Extent = extent; - multipoint.Id = id; - multipoint.IsSimple = IsSimple; - - return multipoint; - } - } - - return Type switch - { - "point" => new Point(Longitude, Latitude, X, Y, Z, SpatialReference?.FromSerializationRecord(), HasM, HasZ, M) - { - Extent = extent, - Id = id - }, - "polyline" => new Polyline(Paths!.Select(x => x.FromSerializationRecord()).ToArray(), - SpatialReference?.FromSerializationRecord(), HasM, HasZ) - { - Extent = extent, - Id = id, - IsSimple = IsSimple - }, - "polygon" => Center is not null && Radius is not null - ? new Circle((Point)Center.FromSerializationRecord(), Radius.Value, - Centroid?.FromSerializationRecord() as Point, - Geodesic, HasM, HasZ, NumberOfPoints, - RadiusUnit is null ? null : Enum.Parse(RadiusUnit), - Rings!.Select(x => x.FromSerializationRecord()).ToArray(), - SpatialReference?.FromSerializationRecord()) - { - Extent = extent, - Id = id, - IsSimple = IsSimple - } - : new Polygon(Rings!.Select(x => x.FromSerializationRecord()).ToArray(), - SpatialReference?.FromSerializationRecord(), - Centroid?.FromSerializationRecord() as Point, - HasM, HasZ) - { - Extent = extent, - Id = id, - IsSimple = IsSimple - }, - "extent" => new Extent(Xmax!.Value, Xmin!.Value, Ymax!.Value, Ymin!.Value, Zmax, - Zmin, Mmax, Mmin, SpatialReference?.FromSerializationRecord(), HasM, HasZ) - { - Id = id, - IsSimple = IsSimple - }, - _ => throw new ArgumentOutOfRangeException() - }; - } + /// + public abstract GeometrySerializationRecord ToProtobuf(); } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Geometries/OldPolyLine.cs b/src/dymaptic.GeoBlazor.Core/Components/Geometries/OldPolyLine.cs index 076356f7b..1c4732506 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Geometries/OldPolyLine.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Geometries/OldPolyLine.cs @@ -5,6 +5,7 @@ namespace dymaptic.GeoBlazor.Core.Components.Geometries; /// /// [Obsolete("Renamed to Polyline (lowercase 'l') to match the JavaScript API")] +[ProtobufSerializable] public class PolyLine : Polyline { /// diff --git a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Point.cs b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Point.cs index 560b534c5..3d5870811 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Point.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Point.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Geometries; +[ProtobufSerializable] public partial class Point : Geometry { - - /// /// The latitude of the point. /// @@ -64,11 +63,12 @@ public Point Clone() return new Point(Longitude, Latitude, X, Y, Z, SpatialReference?.Clone(), HasM, HasZ, M); } - internal override GeometrySerializationRecord ToSerializationRecord() + /// + public override GeometrySerializationRecord ToProtobuf() { return new GeometrySerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), - Extent?.ToSerializationRecord(), - SpatialReference?.ToSerializationRecord()) + Extent?.ToProtobuf(), + SpatialReference?.ToProtobuf()) { Longitude = Longitude, Latitude = Latitude, diff --git a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Polygon.cs b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Polygon.cs index 418b8b3fc..1b94b989b 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Polygon.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Polygon.cs @@ -1,5 +1,6 @@ namespace dymaptic.GeoBlazor.Core.Components.Geometries; +[ProtobufSerializable] public partial class Polygon : Geometry { /// @@ -116,16 +117,17 @@ public Polygon Clone() Centroid, HasM, HasZ); } - internal override GeometrySerializationRecord ToSerializationRecord() + /// + public override GeometrySerializationRecord ToProtobuf() { return new GeometrySerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), - Extent?.ToSerializationRecord(), - SpatialReference?.ToSerializationRecord()) + Extent?.ToProtobuf(), + SpatialReference?.ToProtobuf()) { - Rings = Rings.Select(p => p.ToSerializationRecord()).ToArray(), + Rings = Rings.Select(p => p.ToProtobuf()).ToArray(), HasM = HasM, HasZ = HasZ, - Centroid = Centroid?.ToSerializationRecord(), + Centroid = Centroid?.ToProtobuf(), #pragma warning disable CS0618 // Type or member is obsolete IsSelfIntersecting = IsSelfIntersecting #pragma warning restore CS0618 // Type or member is obsolete diff --git a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Polyline.cs b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Polyline.cs index d6d656e86..6ff2ea79b 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Geometries/Polyline.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Geometries/Polyline.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Geometries; +[ProtobufSerializable] public partial class Polyline : Geometry { - - /// /// An array of paths, or line segments, that make up the polyline. /// @@ -32,13 +31,14 @@ public Polyline Clone() HasM, HasZ); } - internal override GeometrySerializationRecord ToSerializationRecord() + /// + public override GeometrySerializationRecord ToProtobuf() { return new GeometrySerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), - Extent?.ToSerializationRecord(), - SpatialReference?.ToSerializationRecord()) + Extent?.ToProtobuf(), + SpatialReference?.ToProtobuf()) { - Paths = Paths.Select(p => p.ToSerializationRecord()).ToArray(), + Paths = Paths.Select(p => p.ToProtobuf()).ToArray(), HasM = HasM, HasZ = HasZ }; diff --git a/src/dymaptic.GeoBlazor.Core/Components/Graphic.cs b/src/dymaptic.GeoBlazor.Core/Components/Graphic.cs index a48d2bfd3..bbf88eaad 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Graphic.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Graphic.cs @@ -2,7 +2,8 @@ namespace dymaptic.GeoBlazor.Core.Components; -public partial class Graphic: MapComponent, IEquatable +[ProtobufSerializable] +public partial class Graphic: MapComponent, IEquatable, IProtobufSerializable { /// /// Parameterless constructor for use as a Razor Component. @@ -320,7 +321,7 @@ public async Task SetGeometry(Geometry geometry) if (CoreJsModule is not null) { await CoreJsModule.InvokeVoidAsync("setGraphicGeometry", Id, LayerId, View?.Id, - Geometry.ToSerializationRecord()); + Geometry.ToProtobuf()); } else { @@ -343,7 +344,7 @@ public async Task SetSymbol(Symbol symbol) Symbol = symbol; if (CoreJsModule is not null) { - await CoreJsModule.InvokeVoidAsync("setGraphicSymbol", Id, Symbol.ToSerializationRecord(), + await CoreJsModule.InvokeVoidAsync("setGraphicSymbol", Id, Symbol.ToProtobuf(), LayerId, View?.Id); } else @@ -378,7 +379,7 @@ public async Task SetPopupTemplate(PopupTemplate popupTemplate) if (CoreJsModule is not null) { await CoreJsModule.InvokeVoidAsync("setGraphicPopupTemplate", Id, - PopupTemplate.ToSerializationRecord(), PopupTemplate.DotNetComponentReference, LayerId, View?.Id); + PopupTemplate.ToProtobuf(), PopupTemplate.DotNetComponentReference, LayerId, View?.Id); } else { @@ -676,13 +677,21 @@ internal GraphicSerializationRecord ToSerializationRecord(bool refresh = false) { if (_serializationRecord is null || refresh) { - _serializationRecord = new GraphicSerializationRecord(Id.ToString(), Geometry?.ToSerializationRecord(), - Symbol?.ToSerializationRecord(), PopupTemplate?.ToSerializationRecord(), - Attributes.ToSerializationRecord(), Visible, - AggregateGeometries is null ? null : JsonSerializer.Serialize(AggregateGeometries), - Origin?.ToSerializationRecord(), LayerId?.ToString(), ViewId?.ToString()); + return ToProtobuf(); } + + return _serializationRecord; + } + /// + public virtual GraphicSerializationRecord ToProtobuf() + { + _serializationRecord = new GraphicSerializationRecord(Id.ToString(), Geometry?.ToProtobuf(), + Symbol?.ToProtobuf(), PopupTemplate?.ToProtobuf(), + Attributes.ToProtobufArray(), Visible, + AggregateGeometries is null ? null : JsonSerializer.Serialize(AggregateGeometries), + Origin?.ToProtobuf(), LayerId?.ToString(), ViewId?.ToString()); + return _serializationRecord; } @@ -784,101 +793,4 @@ public override int GetHashCode() { return !Equals(left, right); } -} - -[ProtoContract(Name = "Graphic")] -internal record GraphicSerializationRecord : MapComponentSerializationRecord -{ - public GraphicSerializationRecord() - { - } - - public GraphicSerializationRecord(string Id, GeometrySerializationRecord? Geometry, - SymbolSerializationRecord? Symbol, PopupTemplateSerializationRecord? PopupTemplate, - AttributeSerializationRecord[]? Attributes, bool? Visible, string? AggregateGeometries, - GraphicOriginSerializationRecord? Origin, string? LayerId, string? ViewId) - { - this.Id = Id; - this.Geometry = Geometry; - this.Symbol = Symbol; - this.PopupTemplate = PopupTemplate; - this.Attributes = Attributes; - this.Visible = Visible; - this.AggregateGeometries = AggregateGeometries; - this.Origin = Origin; - this.LayerId = LayerId; - this.ViewId = ViewId; - } - - public Graphic FromSerializationRecord() - { - if (!Guid.TryParse(Id, out Guid graphicId)) - { - graphicId = Guid.NewGuid(); - } - - Guid? layerId = null; - - if (Guid.TryParse(LayerId, out Guid existingLayerId)) - { - layerId = existingLayerId; - } - - Guid? viewId = null; - - if (Guid.TryParse(ViewId, out Guid existingViewId)) - { - viewId = existingViewId; - } - - return new Graphic(Geometry?.FromSerializationRecord(), Symbol?.FromSerializationRecord(), - PopupTemplate?.FromSerializationRecord(), new AttributesDictionary(Attributes), - Visible, null, AggregateGeometries, Origin?.FromSerializationRecord()) - { - Id = graphicId, -#pragma warning disable BL0005 - LayerId = layerId, -#pragma warning restore BL0005 - ViewId = viewId - }; - } - - [ProtoMember(1)] - public string? Id { get; set; } = string.Empty; - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public GeometrySerializationRecord? Geometry { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public SymbolSerializationRecord? Symbol { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(4)] - public PopupTemplateSerializationRecord? PopupTemplate { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(5)] - public AttributeSerializationRecord[]? Attributes { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(6)] - public bool? Visible { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(7)] - public string? AggregateGeometries { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(8)] - public GraphicOriginSerializationRecord? Origin { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(9)] - public string? LayerId { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(10)] - public string? ViewId { get; set; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/HomeViewModel.cs b/src/dymaptic.GeoBlazor.Core/Components/HomeViewModel.cs index 862ebbcea..bcdbb415a 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/HomeViewModel.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/HomeViewModel.cs @@ -21,7 +21,7 @@ public partial class HomeViewModel : MapComponent, IViewModel [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); diff --git a/src/dymaptic.GeoBlazor.Core/Components/HomeViewModel.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/HomeViewModel.gb.cs index 3f7a02ab5..4531044d3 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/HomeViewModel.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/HomeViewModel.gb.cs @@ -290,7 +290,7 @@ public async Task OnJsGo(IJSStreamReference jsStreamRef) return; } - HomeViewModelGoEvent? goEvent = await jsStreamRef.ReadJsStreamReference(); + HomeViewModelGoEvent? goEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (goEvent is not null) { await OnGo.InvokeAsync(goEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/ImageMediaInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/ImageMediaInfo.cs index 1630aafdb..d23ca1044 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/ImageMediaInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/ImageMediaInfo.cs @@ -1,13 +1,11 @@ namespace dymaptic.GeoBlazor.Core.Components; +[ProtobufSerializable] public partial class ImageMediaInfo : MediaInfo { - - /// public override string Type => "image-media"; - /// /// Refresh interval of the layer in minutes. Non-zero value indicates automatic layer refresh at the specified interval. Value of 0 indicates auto refresh is not enabled. If the property does not exist, it is equivalent to having a value of 0. /// @@ -15,15 +13,15 @@ public partial class ImageMediaInfo : MediaInfo [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public double? RefreshInterval { get; set; } - - internal override MediaInfoSerializationRecord ToSerializationRecord() + /// + public override MediaInfoSerializationRecord ToProtobuf() { return new MediaInfoSerializationRecord(Id.ToString(), "image-media") { AltText = AltText, Caption = Caption, Title = Title, - Value = Value?.ToSerializationRecord(), + Value = Value?.ToProtobuf(), RefreshInterval = RefreshInterval }; } diff --git a/src/dymaptic.GeoBlazor.Core/Components/ImageMediaInfoValue.cs b/src/dymaptic.GeoBlazor.Core/Components/ImageMediaInfoValue.cs index 523f06a3c..9350210bf 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/ImageMediaInfoValue.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/ImageMediaInfoValue.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components; -public partial class ImageMediaInfoValue : MapComponent +[ProtobufSerializable] +public partial class ImageMediaInfoValue : MapComponent, IMediaInfoValue { - - /// /// A string containing a URL to be launched in a browser when a user clicks the image. /// @@ -17,9 +16,10 @@ public partial class ImageMediaInfoValue : MapComponent [Parameter] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? SourceURL { get; set; } - - internal ChartMediaInfoValueSerializationRecord ToSerializationRecord() + + /// + public MediaInfoValueSerializationRecord ToProtobuf() { - return new ChartMediaInfoValueSerializationRecord(Id.ToString(), LinkURL: LinkURL, SourceURL: SourceURL); + return new MediaInfoValueSerializationRecord(Id.ToString(), LinkURL: LinkURL, SourceURL: SourceURL); } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/JoinTableDataSource.cs b/src/dymaptic.GeoBlazor.Core/Components/JoinTableDataSource.cs index 140024966..021aa651c 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/JoinTableDataSource.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/JoinTableDataSource.cs @@ -2,8 +2,6 @@ namespace dymaptic.GeoBlazor.Core.Components; public partial class JoinTableDataSource : DynamicDataSource { - - /// public override DynamicDataSourceType Type => DynamicDataSourceType.JoinTable; diff --git a/src/dymaptic.GeoBlazor.Core/Components/Label.cs b/src/dymaptic.GeoBlazor.Core/Components/Label.cs index c7d151f49..fe1a210d6 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Label.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Label.cs @@ -114,7 +114,7 @@ public virtual async Task SetSymbol(Symbol symbol) Symbol = symbol; if (CoreJsModule is not null) { - await CoreJsModule.InvokeVoidAsync("setGraphicSymbol", Id, Symbol.ToSerializationRecord()); + await CoreJsModule.InvokeVoidAsync("setGraphicSymbol", Id, Symbol.ToProtobuf()); } else { diff --git a/src/dymaptic.GeoBlazor.Core/Components/LayerListViewModel.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/LayerListViewModel.gb.cs index 2a106ee68..51232f8a1 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/LayerListViewModel.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/LayerListViewModel.gb.cs @@ -421,7 +421,7 @@ public async Task OnJsTriggerAction(IJSStreamReference jsStreamRef) return; } - LayerListViewModelTriggerActionEvent? triggerActionEvent = await jsStreamRef.ReadJsStreamReference(); + LayerListViewModelTriggerActionEvent? triggerActionEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (triggerActionEvent is not null) { await OnTriggerAction.InvokeAsync(triggerActionEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/BaseTileLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/BaseTileLayer.gb.cs index da5ca219e..468f4c563 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/BaseTileLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/BaseTileLayer.gb.cs @@ -694,7 +694,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/CSVLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/CSVLayer.gb.cs index b8bc5370a..1dadc9ac4 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/CSVLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/CSVLayer.gb.cs @@ -4098,7 +4098,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/FeatureLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/FeatureLayer.gb.cs index ea5ebc1a2..38ebfb5e4 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/FeatureLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/FeatureLayer.gb.cs @@ -6266,7 +6266,7 @@ public async Task OnJsEdits(IJSStreamReference jsStreamRef) return; } - FeatureLayerEditsEvent? editsEvent = await jsStreamRef.ReadJsStreamReference(); + FeatureLayerEditsEvent? editsEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (editsEvent is not null) { await OnEdits.InvokeAsync(editsEvent); @@ -6300,7 +6300,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/GeoJSONLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/GeoJSONLayer.gb.cs index aa4510050..f4ef65f90 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/GeoJSONLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/GeoJSONLayer.gb.cs @@ -4040,7 +4040,7 @@ public async Task OnJsEdits(IJSStreamReference jsStreamRef) return; } - GeoJSONLayerEditsEvent? editsEvent = await jsStreamRef.ReadJsStreamReference(); + GeoJSONLayerEditsEvent? editsEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (editsEvent is not null) { await OnEdits.InvokeAsync(editsEvent); @@ -4073,7 +4073,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/GeoRSSLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/GeoRSSLayer.gb.cs index b0780b8ff..e76f696f5 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/GeoRSSLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/GeoRSSLayer.gb.cs @@ -1144,7 +1144,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/ImageryLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/ImageryLayer.gb.cs index 493f4b81b..483b80152 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/ImageryLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/ImageryLayer.gb.cs @@ -3978,7 +3978,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/Layer.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/Layer.cs index 5edce7e0f..c60becd34 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/Layer.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/Layer.cs @@ -340,7 +340,7 @@ await CoreJsModule.InvokeAsync("buildJsLayer", IJSStreamReference streamRef = await JsComponentReference!.InvokeAsync("load", cancellationToken, abortSignal); Type type = GetType(); - Layer? deserializedLayer = await streamRef.ReadJsStreamReference(type) as Layer; + Layer? deserializedLayer = await streamRef.ReadJsStreamReferenceAsJSON(type) as Layer; if (deserializedLayer is null) { throw new InvalidOperationException($"Could not load layer of type {type.Name}"); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/Layer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/Layer.gb.cs index b19d8b7cb..d856dc179 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/Layer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/Layer.gb.cs @@ -410,7 +410,7 @@ public async Task OnJsCreate(IJSStreamReference jsStreamRef) return; } - LayerViewCreateEvent? createEvent = await jsStreamRef.ReadJsStreamReference(); + LayerViewCreateEvent? createEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (createEvent is not null) { await OnCreate.InvokeAsync(createEvent); @@ -442,7 +442,7 @@ public async Task OnJsCreateError(IJSStreamReference jsStreamRef) return; } - LayerViewCreateErrorEvent? createErrorEvent = await jsStreamRef.ReadJsStreamReference(); + LayerViewCreateErrorEvent? createErrorEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (createErrorEvent is not null) { await OnCreateError.InvokeAsync(createErrorEvent); @@ -475,7 +475,7 @@ public async Task OnJsDestroy(IJSStreamReference jsStreamRef) return; } - LayerViewDestroyEvent? destroyEvent = await jsStreamRef.ReadJsStreamReference(); + LayerViewDestroyEvent? destroyEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (destroyEvent is not null) { await OnDestroy.InvokeAsync(destroyEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/MapImageLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/MapImageLayer.gb.cs index 155431bc8..7e11f7d0f 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/MapImageLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/MapImageLayer.gb.cs @@ -2635,7 +2635,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/TileLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/TileLayer.gb.cs index 164ae5bcf..59993c728 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/TileLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/TileLayer.gb.cs @@ -1978,7 +1978,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/VectorTileLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/VectorTileLayer.gb.cs index b7e8b0081..68abf794d 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/VectorTileLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/VectorTileLayer.gb.cs @@ -1394,7 +1394,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/WFSLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/WFSLayer.gb.cs index 2afb69fac..0d3425c3c 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/WFSLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/WFSLayer.gb.cs @@ -3791,7 +3791,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/WMSLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/WMSLayer.gb.cs index 8f6c3b9cd..17c7b185d 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/WMSLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/WMSLayer.gb.cs @@ -3085,7 +3085,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Layers/WebTileLayer.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Layers/WebTileLayer.gb.cs index bc2ff6570..f9a3fd4e4 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Layers/WebTileLayer.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Layers/WebTileLayer.gb.cs @@ -1213,7 +1213,7 @@ public async Task OnJsRefresh(IJSStreamReference jsStreamRef) return; } - RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReference(); + RefreshEvent? refreshEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (refreshEvent is not null) { await OnRefresh.InvokeAsync(refreshEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/LineChartMediaInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/LineChartMediaInfo.cs index 5f08207d2..c2320d521 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/LineChartMediaInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/LineChartMediaInfo.cs @@ -1,21 +1,20 @@ namespace dymaptic.GeoBlazor.Core.Components; +[ProtobufSerializable] public partial class LineChartMediaInfo : MediaInfo { - - /// public override string Type => "line-chart"; - - internal override MediaInfoSerializationRecord ToSerializationRecord() + /// + public override MediaInfoSerializationRecord ToProtobuf() { return new MediaInfoSerializationRecord(Id.ToString(), "line-chart") { AltText = AltText, Caption = Caption, Title = Title, - Value = Value?.ToSerializationRecord() + Value = Value?.ToProtobuf() }; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/LocateViewModel.cs b/src/dymaptic.GeoBlazor.Core/Components/LocateViewModel.cs index 5e93def85..ba16b9b1e 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/LocateViewModel.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/LocateViewModel.cs @@ -21,7 +21,7 @@ public partial class LocateViewModel : MapComponent [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); @@ -41,7 +41,7 @@ public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) [CodeGenerationIgnore] public async Task OnJsLocate(IJSStreamReference jsStreamRef) { - LocateViewModelLocateEvent? locateEvent = await jsStreamRef.ReadJsStreamReference(); + LocateViewModelLocateEvent? locateEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); View!.ExtentChangedInJs = true; await OnLocate.InvokeAsync(locateEvent); } diff --git a/src/dymaptic.GeoBlazor.Core/Components/LocateViewModel.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/LocateViewModel.gb.cs index e8885d6d1..c05b5fddf 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/LocateViewModel.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/LocateViewModel.gb.cs @@ -857,7 +857,7 @@ public async Task OnJsLocateError(IJSStreamReference jsStreamRef) return; } - LocateViewModelLocateErrorEvent? locateErrorEvent = await jsStreamRef.ReadJsStreamReference(); + LocateViewModelLocateErrorEvent? locateErrorEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (locateErrorEvent is not null) { await OnLocateError.InvokeAsync(locateErrorEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/LocationService.cs b/src/dymaptic.GeoBlazor.Core/Components/LocationService.cs index d3176ffe0..5d2b681f9 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/LocationService.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/LocationService.cs @@ -2179,7 +2179,7 @@ private async Task> AddressToLocations(string url, object categories, countryCode, forStorage, location, locationType, magicKey, maxLocations, outFields, outSpatialReference, searchExtent, requestOptions, addressSearchStringParameterName); - return await streamRef.ReadJsStreamReference>() ?? []; + return await streamRef.ReadJsStreamReferenceAsJSON>() ?? []; } /// @@ -2218,7 +2218,7 @@ public async Task> AddressesToLocations(string url, objec addresses, countryCode, categories, locationType, outSpatialReference, requestOptions, addressSearchStringParameterName); - return await streamRef.ReadJsStreamReference>() ?? []; + return await streamRef.ReadJsStreamReferenceAsJSON>() ?? []; } private const string ESRIGeoLocationUrl = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer"; diff --git a/src/dymaptic.GeoBlazor.Core/Components/MapComponent.razor.cs b/src/dymaptic.GeoBlazor.Core/Components/MapComponent.razor.cs index 6b63fa749..e34dae179 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/MapComponent.razor.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/MapComponent.razor.cs @@ -11,14 +11,38 @@ public abstract partial class MapComponent : ComponentBase, IAsyncDisposable, IM /// [Inject] [JsonIgnore] - public IJSRuntime? JsRuntime { get; set; } + public IJSRuntime? JsRuntime + { + get + { + if (field is null && Parent?.JsRuntime is not null) + { + field = Parent.JsRuntime; + } + + return field; + } + set; + } /// /// Manages references to JavaScript modules. /// [Inject] [JsonIgnore] - public JsModuleManager? JsModuleManager { get; set; } + public JsModuleManager? JsModuleManager + { + get + { + if (field is null && Parent?.JsModuleManager is not null) + { + field = Parent.JsModuleManager; + } + + return field; + } + set; + } /// /// ChildContent defines the ability to add other components within this component in the razor syntax. @@ -131,6 +155,21 @@ public Guid? ViewId /// [JsonIgnore] public bool IsDisposed { get; private set; } + + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode + /// + protected internal bool IsServer => JsRuntime?.GetType().Name.Contains("Remote") ?? false; + + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor WebAssembly (client) mode + /// + protected internal bool IsWebAssembly => OperatingSystem.IsBrowser(); + + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor Hybrid (MAUI) mode + /// + protected internal bool IsMaui => JsRuntime!.GetType().Name.Contains("WebView"); /// /// Implements the `IAsyncDisposable` pattern. @@ -668,7 +707,7 @@ public Task SetVisible(bool visible) try { - if (await jsonStreamReference.ReadJsStreamReference(MapComponentType) is MapComponent deserialized) + if (await jsonStreamReference.ReadJsStreamReferenceAsJSON(MapComponentType) is MapComponent deserialized) { if (IsDisposed) { @@ -991,6 +1030,7 @@ protected override void OnParametersSet() { record.CoreJsModule = CoreJsModule; record.AbortManager = new AbortManager(CoreJsModule!); + record.IsServer = IsServer; } } } @@ -1037,7 +1077,7 @@ protected virtual async Task RenderView(bool forceRender = false) /// /// Properties that were modified in code, and should no longer be set via markup, but instead set to the value here. /// - protected readonly internal Dictionary ModifiedParameters = new(); + protected internal readonly Dictionary ModifiedParameters = new(); /// /// Creates a cancellation token to control external calls @@ -1378,7 +1418,7 @@ public async Task OnReactiveWatcherUpdate(string watchExpression, IJSStreamRefer if (jsStreamReference is not null) { - typedValue = await jsStreamReference.ReadJsStreamReference(returnType); + typedValue = await jsStreamReference.ReadJsStreamReferenceAsJSON(returnType); } handler.DynamicInvoke(typedValue); @@ -1511,7 +1551,7 @@ public async Task OnReactiveListenerTriggered(string eventName, IJSStreamReferen if (jsStreamReference is not null) { - typedValue = await jsStreamReference.ReadJsStreamReference(returnType); + typedValue = await jsStreamReference.ReadJsStreamReferenceAsJSON(returnType); } handler.DynamicInvoke(typedValue); diff --git a/src/dymaptic.GeoBlazor.Core/Components/MapFont.cs b/src/dymaptic.GeoBlazor.Core/Components/MapFont.cs index 297fae3ea..ff67283fa 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/MapFont.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/MapFont.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components; -public partial class MapFont : MapComponent +[ProtobufSerializable] +public partial class MapFont : MapComponent, IProtobufSerializable { - - /// /// The text decoration. /// default none @@ -46,58 +45,10 @@ public partial class MapFont : MapComponent [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public FontWeight? Weight { get; set; } - internal MapFontSerializationRecord ToSerializationRecord() + /// + public MapFontSerializationRecord ToProtobuf() { return new MapFontSerializationRecord(Id.ToString(), Size?.Points, Family, Style?.ToString().ToKebabCase(), Weight?.ToString().ToKebabCase(), Decoration?.ToString().ToKebabCase()); } -} - -[ProtoContract] -internal record MapFontSerializationRecord -{ - public MapFontSerializationRecord() - { - } - - public MapFontSerializationRecord(string Id, double? Size, string? Family, string? FontStyle, string? Weight, - string? Decoration) - { - this.Id = Id; - this.Size = Size; - this.Family = Family; - this.FontStyle = FontStyle; - this.Weight = Weight; - this.Decoration = Decoration; - } - - [ProtoMember(1)] - public double? Size { get; init; } - - [ProtoMember(2)] - public string? Family { get; init; } - - [ProtoMember(3)] - public string? FontStyle { get; init; } - - [ProtoMember(4)] - public string? Weight { get; init; } - - [ProtoMember(5)] - public string? Decoration { get; init; } - - [ProtoMember(6)] - public string? Id { get; init; } - - public MapFont FromSerializationRecord() - { - Guid id = Guid.NewGuid(); - if (Guid.TryParse(Id, out Guid guid)) - { - id = guid; - } - return new MapFont(Size, Family, FontStyle is null ? null : Enum.Parse(FontStyle), - Weight is null ? null : Enum.Parse(Weight), - Decoration is null ? null : Enum.Parse(Decoration)) { Id = id }; - } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/MediaInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/MediaInfo.cs index b858e3217..ae1b3d94a 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/MediaInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/MediaInfo.cs @@ -1,73 +1,16 @@ namespace dymaptic.GeoBlazor.Core.Components; [JsonConverter(typeof(MediaInfoConverter))] -public abstract partial class MediaInfo : MapComponent +[ProtobufSerializable] +public abstract partial class MediaInfo : MapComponent, IProtobufSerializable { /// /// Indicates the type of media /// public abstract string Type { get; } - internal abstract MediaInfoSerializationRecord ToSerializationRecord(); -} - -[ProtoContract(Name = "MediaInfo")] -internal record MediaInfoSerializationRecord : MapComponentSerializationRecord -{ - public MediaInfoSerializationRecord() - { - } - - public MediaInfoSerializationRecord(string Id, string Type) - { - this.Id = Id; - this.Type = Type; - } - - [ProtoMember(1)] - public string Type { get; init; } = string.Empty; - - [ProtoMember(2)] - public string? AltText { get; init; } - - [ProtoMember(3)] - public string? Caption { get; init; } - - [ProtoMember(4)] - public string? Title { get; init; } - - [ProtoMember(5)] - public ChartMediaInfoValueSerializationRecord? Value { get; init; } - - [ProtoMember(6)] - public double? RefreshInterval { get; init; } - - [ProtoMember(7)] - public string? Id { get; init; } - - public MediaInfo FromSerializationRecord() - { - Guid id = Guid.NewGuid(); - if (Guid.TryParse(Id, out Guid guid)) - { - id = guid; - } - return Type switch - { - "bar-chart" => new BarChartMediaInfo(Title, Caption, AltText, - Value?.FromSerializationRecord() as ChartMediaInfoValue) { Id = id }, - "column-chart" => new ColumnChartMediaInfo(Title, Caption, AltText, - Value?.FromSerializationRecord() as ChartMediaInfoValue) { Id = id }, - "pie-chart" => new PieChartMediaInfo(Title, Caption, AltText, - Value?.FromSerializationRecord() as ChartMediaInfoValue) { Id = id }, - "line-chart" => new LineChartMediaInfo(Title, Caption, AltText, - Value?.FromSerializationRecord() as ChartMediaInfoValue) { Id = id }, - "image-media" => new ImageMediaInfo(Title, Caption, AltText, - Value?.FromSerializationRecord() as ImageMediaInfoValue, - RefreshInterval) { Id = id }, - _ => throw new NotSupportedException($"MediaInfo type {Type} is not supported.") - }; - } + /// + public abstract MediaInfoSerializationRecord ToProtobuf(); } internal class MediaInfoConverter : JsonConverter diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshComponent.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshComponent.cs new file mode 100644 index 000000000..41a68f24f --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshComponent.cs @@ -0,0 +1,59 @@ +namespace dymaptic.GeoBlazor.Core.Components; + +[ProtobufSerializable] +public partial class MeshComponent: IProtobufSerializable +{ + // Add custom code to this file to override generated code + /// + public MeshComponentSerializationRecord ToProtobuf() + { + MeshComponentMaterialSerializationRecord? materialRecord = Material switch + { + MeshMaterialMetallicRoughness metallicRoughness => metallicRoughness.ToProtobuf(), + MeshMaterial material => material.ToProtobuf(), + _ => null + }; + return new MeshComponentSerializationRecord(Faces, + materialRecord, Name, Shading?.ToString().ToKebabCase()); + } + + /// + /// Asynchronously retrieve the current value of the Material property. + /// + [CodeGenerationIgnore] + public async Task GetMaterial() + { + if (CoreJsModule is null) + { + return Material; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Material; + } + + IMeshComponentMaterial? result = await JsComponentReference.InvokeAsync( + "getMaterial", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + Material = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Material)] = Material; + } + + return Material; + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshComponent.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshComponent.gb.cs new file mode 100644 index 000000000..18fed5f08 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshComponent.gb.cs @@ -0,0 +1,417 @@ +// File auto-generated by dymaptic tooling. Any changes made here will be lost on future generation. To override functionality, use the relevant root .cs file. + +namespace dymaptic.GeoBlazor.Core.Components; + + +/// +/// GeoBlazor Docs +/// The MeshComponent class is used to apply one or more materials to +/// a single Mesh. +/// ArcGIS Maps SDK for JavaScript +/// +public partial class MeshComponent : MapComponent +{ + + /// + /// Parameterless constructor for use as a Razor Component. + /// + [ActivatorUtilitiesConstructor] + public MeshComponent() + { + } + + /// + /// Constructor for use in C# code. Use named parameters (e.g., item1: value1, item2: value2) to set properties in any order. + /// + /// + /// A flat array of indices that refer to vertices in the + /// vertexAttributes of the + /// mesh to which the component belongs. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// The material determines how the component is visualized. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a name of the component. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies the type of normals used for lighting. + /// ArcGIS Maps SDK for JavaScript + /// + public MeshComponent( + byte[]? faces = null, + IMeshComponentMaterial? material = null, + string? name = null, + MeshShading? shading = null) + { + AllowRender = false; +#pragma warning disable BL0005 + Faces = faces; + Material = material; + Name = name; + Shading = shading; +#pragma warning restore BL0005 + } + + +#region Public Properties / Blazor Parameters + + /// + /// GeoBlazor Docs + /// A flat array of indices that refer to vertices in the + /// vertexAttributes of the + /// mesh to which the component belongs. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public byte[]? Faces { get; set; } + + /// + /// GeoBlazor Docs + /// The material determines how the component is visualized. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public IMeshComponentMaterial? Material { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies a name of the component. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Name { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies the type of normals used for lighting. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshShading? Shading { get; set; } + +#endregion + +#region Property Getters + + /// + /// Asynchronously retrieve the current value of the Faces property. + /// + public async Task GetFaces() + { + if (CoreJsModule is null) + { + return Faces; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Faces; + } + + // get the property value + byte[]? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "faces"); + if (result is not null) + { +#pragma warning disable BL0005 + Faces = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Faces)] = Faces; + } + + return Faces; + } + + /// + /// Asynchronously retrieve the current value of the Name property. + /// + public async Task GetName() + { + if (CoreJsModule is null) + { + return Name; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Name; + } + + // get the property value + string? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "name"); + if (result is not null) + { +#pragma warning disable BL0005 + Name = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Name)] = Name; + } + + return Name; + } + + /// + /// Asynchronously retrieve the current value of the Shading property. + /// + public async Task GetShading() + { + if (CoreJsModule is null) + { + return Shading; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Shading; + } + + // get the property value + JsNullableEnumWrapper? result = await CoreJsModule!.InvokeAsync?>("getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "shading"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + Shading = (MeshShading)result.Value.Value!; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Shading)] = Shading; + } + + return Shading; + } + +#endregion + +#region Property Setters + + /// + /// Asynchronously set the value of the Faces property after render. + /// + /// + /// The value to set. + /// + public async Task SetFaces(byte[]? value) + { +#pragma warning disable BL0005 + Faces = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Faces)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "faces", value); + } + + /// + /// Asynchronously set the value of the Material property after render. + /// + /// + /// The value to set. + /// + public async Task SetMaterial(IMeshComponentMaterial? value) + { +#pragma warning disable BL0005 + Material = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Material)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "material", value); + } + + /// + /// Asynchronously set the value of the Name property after render. + /// + /// + /// The value to set. + /// + public async Task SetName(string? value) + { +#pragma warning disable BL0005 + Name = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Name)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "name", value); + } + + /// + /// Asynchronously set the value of the Shading property after render. + /// + /// + /// The value to set. + /// + public async Task SetShading(MeshShading? value) + { +#pragma warning disable BL0005 + Shading = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Shading)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "shading", value); + } + +#endregion + +#region Add to Collection Methods + + /// + /// Asynchronously adds elements to the Faces property. + /// + /// + /// The elements to add. + /// + public async Task AddToFaces(params byte[] values) + { + byte[] join = Faces is null + ? values + : [..Faces, ..values]; + await SetFaces(join); + } + +#endregion + +#region Remove From Collection Methods + + + /// + /// Asynchronously remove an element from the Faces property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromFaces(params byte[] values) + { + if (Faces is null) + { + return; + } + await SetFaces(Faces.Except(values).ToArray()); + } + +#endregion + +} diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshGeoreferencedVertexSpace.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshGeoreferencedVertexSpace.cs new file mode 100644 index 000000000..52e5d7ad9 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshGeoreferencedVertexSpace.cs @@ -0,0 +1,24 @@ +namespace dymaptic.GeoBlazor.Core.Components; + +/// +/// A mesh vertex space indicating that mesh vertices are either absolute georeferenced map coordinates or relative offsets in map space to a fully georeferenced origin. The map space is identified by the spatial reference of the mesh. +/// The vertex space of a mesh allows users to specify how the coordinates of the mesh vertices are interpreted. Use the georeferenced vertex space if the coordinates are already in the spatial reference of the mesh. The coordinates can be relative to the origin or absolute coordinates if the origin is not defined. +/// +/// +/// Origin of the vertex space. This will be interpreted as coordinates in the SpatialReference of the Mesh using the vertex space. If this is null, the coordinates are expected to be absolute. If not, then the coordinates are expected to be deltas relative to the origin. +/// +[CodeGenerationIgnore] +[ProtobufSerializable] +public record MeshGeoreferencedVertexSpace(double[]? Origin) : IMeshVertexSpace +{ + /// + /// The type of Vertex Space + /// + public string Type => "georeferenced"; + + /// + public MeshVertexSpaceSerializationRecord ToProtobuf() + { + return new MeshVertexSpaceSerializationRecord(Type, Origin); + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshLocalVertexSpace.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshLocalVertexSpace.cs new file mode 100644 index 000000000..25f02fe79 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshLocalVertexSpace.cs @@ -0,0 +1,20 @@ +namespace dymaptic.GeoBlazor.Core.Components; + +/// +/// A mesh vertex space that indicates mesh vertices to be in a plain cartesian space as often encountered in 3D modeling and CAD applications. Georeferencing is done by using the coordinates in the local tangent plane reference frame at the fully georeferenced origin of the vertex space. +/// +/// +/// Origin of the vertex space. This will be interpreted as coordinates in the SpatialReference of the Mesh using the vertex space. +/// +[CodeGenerationIgnore] +[ProtobufSerializable] +public record MeshLocalVertexSpace(double[]? Origin) : IMeshVertexSpace +{ + public string Type => "local"; + + /// + public MeshVertexSpaceSerializationRecord ToProtobuf() + { + return new MeshVertexSpaceSerializationRecord(Type, Origin); + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshMaterial.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshMaterial.cs new file mode 100644 index 000000000..021b766ec --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshMaterial.cs @@ -0,0 +1,23 @@ +namespace dymaptic.GeoBlazor.Core.Components; + +[ProtobufSerializable] +public partial class MeshMaterial: MapComponent, IMeshComponentMaterial +{ + // Add custom code to this file to override generated code + + /// + public virtual MeshComponentMaterialSerializationRecord ToProtobuf() + { + return new MeshComponentMaterialSerializationRecord(AlphaCutoff, + AlphaMode?.ToString().ToKebabCase(), + Color?.ToProtobuf(), + ColorTexture?.ToProtobuf(), + ColorTextureTransform?.ToProtobuf(), + DoubleSided, + NormalTexture?.ToProtobuf(), + NormalTextureTransform?.ToProtobuf(), + null, null, null, + null, null, null, + null, null); + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshMaterial.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshMaterial.gb.cs new file mode 100644 index 000000000..b94ca04b8 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshMaterial.gb.cs @@ -0,0 +1,823 @@ +// File auto-generated by dymaptic tooling. Any changes made here will be lost on future generation. To override functionality, use the relevant root .cs file. + +namespace dymaptic.GeoBlazor.Core.Components; + + +/// +/// GeoBlazor Docs +/// The material determines how a MeshComponent is visualized. +/// ArcGIS Maps SDK for JavaScript +/// +public partial class MeshMaterial +{ + + /// + /// Parameterless constructor for use as a Razor Component. + /// + [ActivatorUtilitiesConstructor] + public MeshMaterial() + { + } + + /// + /// Constructor for use in C# code. Use named parameters (e.g., item1: value1, item2: value2) to set properties in any order. + /// + /// + /// Specifies how transparency on the object is handled. + /// default 0.5 + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies how transparency on the object is handled. + /// default "auto" + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a single, uniform color for the mesh component. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a texture from which to get color information. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A transformation of UV mesh coordinates used to sample the color texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies whether both sides of each triangle are displayed, or only the front sides. + /// default true + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a texture from which to get normal information. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A transformation of UV mesh coordinates used to sample the normal texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + public MeshMaterial( + double? alphaCutoff = null, + AlphaMode? alphaMode = null, + MapColor? color = null, + MeshTexture? colorTexture = null, + MeshTextureTransform? colorTextureTransform = null, + bool? doubleSided = null, + MeshTexture? normalTexture = null, + MeshTextureTransform? normalTextureTransform = null) + { + AllowRender = false; +#pragma warning disable BL0005 + AlphaCutoff = alphaCutoff; + AlphaMode = alphaMode; + Color = color; + ColorTexture = colorTexture; + ColorTextureTransform = colorTextureTransform; + DoubleSided = doubleSided; + NormalTexture = normalTexture; + NormalTextureTransform = normalTextureTransform; +#pragma warning restore BL0005 + } + + +#region Public Properties / Blazor Parameters + + /// + /// GeoBlazor Docs + /// Specifies how transparency on the object is handled. + /// default 0.5 + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? AlphaCutoff { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies how transparency on the object is handled. + /// default "auto" + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public AlphaMode? AlphaMode { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies a single, uniform color for the mesh component. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MapColor? Color { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies a texture from which to get color information. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshTexture? ColorTexture { get; set; } + + /// + /// GeoBlazor Docs + /// A transformation of UV mesh coordinates used to sample the color texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshTextureTransform? ColorTextureTransform { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies whether both sides of each triangle are displayed, or only the front sides. + /// default true + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? DoubleSided { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies a texture from which to get normal information. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshTexture? NormalTexture { get; set; } + + /// + /// GeoBlazor Docs + /// A transformation of UV mesh coordinates used to sample the normal texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshTextureTransform? NormalTextureTransform { get; set; } + +#endregion + +#region Property Getters + + /// + /// Asynchronously retrieve the current value of the AlphaCutoff property. + /// + public async Task GetAlphaCutoff() + { + if (CoreJsModule is null) + { + return AlphaCutoff; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return AlphaCutoff; + } + + // get the property value + JsNullableDoubleWrapper? result = await CoreJsModule!.InvokeAsync("getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "alphaCutoff"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + AlphaCutoff = result.Value.Value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(AlphaCutoff)] = AlphaCutoff; + } + + return AlphaCutoff; + } + + /// + /// Asynchronously retrieve the current value of the AlphaMode property. + /// + public async Task GetAlphaMode() + { + if (CoreJsModule is null) + { + return AlphaMode; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return AlphaMode; + } + + // get the property value + JsNullableEnumWrapper? result = await CoreJsModule!.InvokeAsync?>("getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "alphaMode"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + AlphaMode = (AlphaMode)result.Value.Value!; +#pragma warning restore BL0005 + ModifiedParameters[nameof(AlphaMode)] = AlphaMode; + } + + return AlphaMode; + } + + /// + /// Asynchronously retrieve the current value of the Color property. + /// + public async Task GetColor() + { + if (CoreJsModule is null) + { + return Color; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Color; + } + + // get the property value + MapColor? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "color"); + if (result is not null) + { +#pragma warning disable BL0005 + Color = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Color)] = Color; + } + + return Color; + } + + /// + /// Asynchronously retrieve the current value of the ColorTexture property. + /// + public async Task GetColorTexture() + { + if (CoreJsModule is null) + { + return ColorTexture; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return ColorTexture; + } + + MeshTexture? result = await JsComponentReference.InvokeAsync( + "getColorTexture", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + ColorTexture = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(ColorTexture)] = ColorTexture; + } + + return ColorTexture; + } + + /// + /// Asynchronously retrieve the current value of the ColorTextureTransform property. + /// + public async Task GetColorTextureTransform() + { + if (CoreJsModule is null) + { + return ColorTextureTransform; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return ColorTextureTransform; + } + + MeshTextureTransform? result = await JsComponentReference.InvokeAsync( + "getColorTextureTransform", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + ColorTextureTransform = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(ColorTextureTransform)] = ColorTextureTransform; + } + + return ColorTextureTransform; + } + + /// + /// Asynchronously retrieve the current value of the DoubleSided property. + /// + public async Task GetDoubleSided() + { + if (CoreJsModule is null) + { + return DoubleSided; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return DoubleSided; + } + + // get the property value + JsNullableBoolWrapper? result = await CoreJsModule!.InvokeAsync("getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "doubleSided"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + DoubleSided = result.Value.Value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(DoubleSided)] = DoubleSided; + } + + return DoubleSided; + } + + /// + /// Asynchronously retrieve the current value of the NormalTexture property. + /// + public async Task GetNormalTexture() + { + if (CoreJsModule is null) + { + return NormalTexture; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return NormalTexture; + } + + MeshTexture? result = await JsComponentReference.InvokeAsync( + "getNormalTexture", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + NormalTexture = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(NormalTexture)] = NormalTexture; + } + + return NormalTexture; + } + + /// + /// Asynchronously retrieve the current value of the NormalTextureTransform property. + /// + public async Task GetNormalTextureTransform() + { + if (CoreJsModule is null) + { + return NormalTextureTransform; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return NormalTextureTransform; + } + + MeshTextureTransform? result = await JsComponentReference.InvokeAsync( + "getNormalTextureTransform", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + NormalTextureTransform = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(NormalTextureTransform)] = NormalTextureTransform; + } + + return NormalTextureTransform; + } + +#endregion + +#region Property Setters + + /// + /// Asynchronously set the value of the AlphaCutoff property after render. + /// + /// + /// The value to set. + /// + public async Task SetAlphaCutoff(double? value) + { +#pragma warning disable BL0005 + AlphaCutoff = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(AlphaCutoff)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "alphaCutoff", value); + } + + /// + /// Asynchronously set the value of the AlphaMode property after render. + /// + /// + /// The value to set. + /// + public async Task SetAlphaMode(AlphaMode? value) + { +#pragma warning disable BL0005 + AlphaMode = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(AlphaMode)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "alphaMode", value); + } + + /// + /// Asynchronously set the value of the Color property after render. + /// + /// + /// The value to set. + /// + public async Task SetColor(MapColor? value) + { +#pragma warning disable BL0005 + Color = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Color)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "color", value); + } + + /// + /// Asynchronously set the value of the ColorTexture property after render. + /// + /// + /// The value to set. + /// + public async Task SetColorTexture(MeshTexture? value) + { + if (value is not null) + { + value.CoreJsModule = CoreJsModule; + value.Parent = this; + value.Layer = Layer; + value.View = View; + } + +#pragma warning disable BL0005 + ColorTexture = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(ColorTexture)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "colorTexture", value); + } + + /// + /// Asynchronously set the value of the ColorTextureTransform property after render. + /// + /// + /// The value to set. + /// + public async Task SetColorTextureTransform(MeshTextureTransform? value) + { + if (value is not null) + { + value.CoreJsModule = CoreJsModule; + value.Parent = this; + value.Layer = Layer; + value.View = View; + } + +#pragma warning disable BL0005 + ColorTextureTransform = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(ColorTextureTransform)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "colorTextureTransform", value); + } + + /// + /// Asynchronously set the value of the DoubleSided property after render. + /// + /// + /// The value to set. + /// + public async Task SetDoubleSided(bool? value) + { +#pragma warning disable BL0005 + DoubleSided = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(DoubleSided)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "doubleSided", value); + } + + /// + /// Asynchronously set the value of the NormalTexture property after render. + /// + /// + /// The value to set. + /// + public async Task SetNormalTexture(MeshTexture? value) + { + if (value is not null) + { + value.CoreJsModule = CoreJsModule; + value.Parent = this; + value.Layer = Layer; + value.View = View; + } + +#pragma warning disable BL0005 + NormalTexture = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(NormalTexture)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "normalTexture", value); + } + + /// + /// Asynchronously set the value of the NormalTextureTransform property after render. + /// + /// + /// The value to set. + /// + public async Task SetNormalTextureTransform(MeshTextureTransform? value) + { + if (value is not null) + { + value.CoreJsModule = CoreJsModule; + value.Parent = this; + value.Layer = Layer; + value.View = View; + } + +#pragma warning disable BL0005 + NormalTextureTransform = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(NormalTextureTransform)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "normalTextureTransform", value); + } + +#endregion + +} diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshMaterialMetallicRoughness.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshMaterialMetallicRoughness.cs new file mode 100644 index 000000000..ebad95c13 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshMaterialMetallicRoughness.cs @@ -0,0 +1,28 @@ +namespace dymaptic.GeoBlazor.Core.Components; + +[ProtobufSerializable] +public partial class MeshMaterialMetallicRoughness +{ + // Add custom code to this file to override generated code + + /// + public override MeshComponentMaterialSerializationRecord ToProtobuf() + { + return new MeshComponentMaterialSerializationRecord(AlphaCutoff, + AlphaMode?.ToString().ToKebabCase(), + Color?.ToProtobuf(), + ColorTexture?.ToProtobuf(), + ColorTextureTransform?.ToProtobuf(), + DoubleSided, + NormalTexture?.ToProtobuf(), + NormalTextureTransform?.ToProtobuf(), + EmissiveColor?.ToProtobuf(), + EmissiveTexture?.ToProtobuf(), + EmissiveTextureTransform?.ToProtobuf(), + Metallic, + MetallicRoughnessTexture?.ToProtobuf(), + OcclusionTexture?.ToProtobuf(), + OcclusionTextureTransform?.ToProtobuf(), + Roughness); + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshMaterialMetallicRoughness.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshMaterialMetallicRoughness.gb.cs new file mode 100644 index 000000000..de08efab5 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshMaterialMetallicRoughness.gb.cs @@ -0,0 +1,883 @@ +// File auto-generated by dymaptic tooling. Any changes made here will be lost on future generation. To override functionality, use the relevant root .cs file. + +namespace dymaptic.GeoBlazor.Core.Components; + + +/// +/// GeoBlazor Docs +/// A material determines how a MeshComponent is visualized. +/// ArcGIS Maps SDK for JavaScript +/// +public partial class MeshMaterialMetallicRoughness : MeshMaterial, + IMeshComponentMaterial +{ + + /// + /// Parameterless constructor for use as a Razor Component. + /// + [ActivatorUtilitiesConstructor] + public MeshMaterialMetallicRoughness() + { + } + + /// + /// Constructor for use in C# code. Use named parameters (e.g., item1: value1, item2: value2) to set properties in any order. + /// + /// + /// Specifies how transparency on the object is handled. + /// default 0.5 + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies how transparency on the object is handled. + /// default "auto" + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a single, uniform color for the mesh component. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a texture from which to get color information. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A transformation of UV mesh coordinates used to sample the color texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies whether both sides of each triangle are displayed, or only the front sides. + /// default true + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a single, uniform emissive color for the MeshComponent. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a texture from which to get emissive color information. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A transformation of UV mesh coordinates used to sample the emissive texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies how much the material behaves like a metal. + /// default 1 + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a texture from which to get the combined metallic/roughness information. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies a texture from which to get normal information. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A transformation of UV mesh coordinates used to sample the normal texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Allows to specify a texture to get the occlusion information from. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A transformation of UV mesh coordinates used to sample the occlusion texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Indicates how rough the surface of the material is. + /// default 1 + /// ArcGIS Maps SDK for JavaScript + /// + public MeshMaterialMetallicRoughness( + double? alphaCutoff = null, + AlphaMode? alphaMode = null, + MapColor? color = null, + MeshTexture? colorTexture = null, + MeshTextureTransform? colorTextureTransform = null, + bool? doubleSided = null, + MapColor? emissiveColor = null, + MeshTexture? emissiveTexture = null, + MeshTextureTransform? emissiveTextureTransform = null, + double? metallic = null, + MeshTexture? metallicRoughnessTexture = null, + MeshTexture? normalTexture = null, + MeshTextureTransform? normalTextureTransform = null, + MeshTexture? occlusionTexture = null, + MeshTextureTransform? occlusionTextureTransform = null, + double? roughness = null) + { + AllowRender = false; +#pragma warning disable BL0005 + AlphaCutoff = alphaCutoff; + AlphaMode = alphaMode; + Color = color; + ColorTexture = colorTexture; + ColorTextureTransform = colorTextureTransform; + DoubleSided = doubleSided; + EmissiveColor = emissiveColor; + EmissiveTexture = emissiveTexture; + EmissiveTextureTransform = emissiveTextureTransform; + Metallic = metallic; + MetallicRoughnessTexture = metallicRoughnessTexture; + NormalTexture = normalTexture; + NormalTextureTransform = normalTextureTransform; + OcclusionTexture = occlusionTexture; + OcclusionTextureTransform = occlusionTextureTransform; + Roughness = roughness; +#pragma warning restore BL0005 + } + + +#region Public Properties / Blazor Parameters + + /// + /// GeoBlazor Docs + /// Specifies a single, uniform emissive color for the MeshComponent. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MapColor? EmissiveColor { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies a texture from which to get emissive color information. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshTexture? EmissiveTexture { get; set; } + + /// + /// GeoBlazor Docs + /// A transformation of UV mesh coordinates used to sample the emissive texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshTextureTransform? EmissiveTextureTransform { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies how much the material behaves like a metal. + /// default 1 + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? Metallic { get; set; } + + /// + /// GeoBlazor Docs + /// Specifies a texture from which to get the combined metallic/roughness information. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshTexture? MetallicRoughnessTexture { get; set; } + + /// + /// GeoBlazor Docs + /// Allows to specify a texture to get the occlusion information from. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshTexture? OcclusionTexture { get; set; } + + /// + /// GeoBlazor Docs + /// A transformation of UV mesh coordinates used to sample the occlusion texture. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public MeshTextureTransform? OcclusionTextureTransform { get; set; } + + /// + /// GeoBlazor Docs + /// Indicates how rough the surface of the material is. + /// default 1 + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? Roughness { get; set; } + +#endregion + +#region Property Getters + + /// + /// Asynchronously retrieve the current value of the EmissiveColor property. + /// + public async Task GetEmissiveColor() + { + if (CoreJsModule is null) + { + return EmissiveColor; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return EmissiveColor; + } + + // get the property value + MapColor? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "emissiveColor"); + if (result is not null) + { +#pragma warning disable BL0005 + EmissiveColor = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(EmissiveColor)] = EmissiveColor; + } + + return EmissiveColor; + } + + /// + /// Asynchronously retrieve the current value of the EmissiveTexture property. + /// + public async Task GetEmissiveTexture() + { + if (CoreJsModule is null) + { + return EmissiveTexture; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return EmissiveTexture; + } + + MeshTexture? result = await JsComponentReference.InvokeAsync( + "getEmissiveTexture", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + EmissiveTexture = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(EmissiveTexture)] = EmissiveTexture; + } + + return EmissiveTexture; + } + + /// + /// Asynchronously retrieve the current value of the EmissiveTextureTransform property. + /// + public async Task GetEmissiveTextureTransform() + { + if (CoreJsModule is null) + { + return EmissiveTextureTransform; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return EmissiveTextureTransform; + } + + MeshTextureTransform? result = await JsComponentReference.InvokeAsync( + "getEmissiveTextureTransform", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + EmissiveTextureTransform = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(EmissiveTextureTransform)] = EmissiveTextureTransform; + } + + return EmissiveTextureTransform; + } + + /// + /// Asynchronously retrieve the current value of the Metallic property. + /// + public async Task GetMetallic() + { + if (CoreJsModule is null) + { + return Metallic; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Metallic; + } + + // get the property value + JsNullableDoubleWrapper? result = await CoreJsModule!.InvokeAsync("getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "metallic"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + Metallic = result.Value.Value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Metallic)] = Metallic; + } + + return Metallic; + } + + /// + /// Asynchronously retrieve the current value of the MetallicRoughnessTexture property. + /// + public async Task GetMetallicRoughnessTexture() + { + if (CoreJsModule is null) + { + return MetallicRoughnessTexture; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return MetallicRoughnessTexture; + } + + MeshTexture? result = await JsComponentReference.InvokeAsync( + "getMetallicRoughnessTexture", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + MetallicRoughnessTexture = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(MetallicRoughnessTexture)] = MetallicRoughnessTexture; + } + + return MetallicRoughnessTexture; + } + + /// + /// Asynchronously retrieve the current value of the OcclusionTexture property. + /// + public async Task GetOcclusionTexture() + { + if (CoreJsModule is null) + { + return OcclusionTexture; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return OcclusionTexture; + } + + MeshTexture? result = await JsComponentReference.InvokeAsync( + "getOcclusionTexture", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + OcclusionTexture = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(OcclusionTexture)] = OcclusionTexture; + } + + return OcclusionTexture; + } + + /// + /// Asynchronously retrieve the current value of the OcclusionTextureTransform property. + /// + public async Task GetOcclusionTextureTransform() + { + if (CoreJsModule is null) + { + return OcclusionTextureTransform; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return OcclusionTextureTransform; + } + + MeshTextureTransform? result = await JsComponentReference.InvokeAsync( + "getOcclusionTextureTransform", CancellationTokenSource.Token); + + if (result is not null) + { +#pragma warning disable BL0005 + OcclusionTextureTransform = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(OcclusionTextureTransform)] = OcclusionTextureTransform; + } + + return OcclusionTextureTransform; + } + + /// + /// Asynchronously retrieve the current value of the Roughness property. + /// + public async Task GetRoughness() + { + if (CoreJsModule is null) + { + return Roughness; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Roughness; + } + + // get the property value + JsNullableDoubleWrapper? result = await CoreJsModule!.InvokeAsync("getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "roughness"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + Roughness = result.Value.Value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Roughness)] = Roughness; + } + + return Roughness; + } + +#endregion + +#region Property Setters + + /// + /// Asynchronously set the value of the EmissiveColor property after render. + /// + /// + /// The value to set. + /// + public async Task SetEmissiveColor(MapColor? value) + { +#pragma warning disable BL0005 + EmissiveColor = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(EmissiveColor)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "emissiveColor", value); + } + + /// + /// Asynchronously set the value of the EmissiveTexture property after render. + /// + /// + /// The value to set. + /// + public async Task SetEmissiveTexture(MeshTexture? value) + { + if (value is not null) + { + value.CoreJsModule = CoreJsModule; + value.Parent = this; + value.Layer = Layer; + value.View = View; + } + +#pragma warning disable BL0005 + EmissiveTexture = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(EmissiveTexture)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "emissiveTexture", value); + } + + /// + /// Asynchronously set the value of the EmissiveTextureTransform property after render. + /// + /// + /// The value to set. + /// + public async Task SetEmissiveTextureTransform(MeshTextureTransform? value) + { + if (value is not null) + { + value.CoreJsModule = CoreJsModule; + value.Parent = this; + value.Layer = Layer; + value.View = View; + } + +#pragma warning disable BL0005 + EmissiveTextureTransform = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(EmissiveTextureTransform)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "emissiveTextureTransform", value); + } + + /// + /// Asynchronously set the value of the Metallic property after render. + /// + /// + /// The value to set. + /// + public async Task SetMetallic(double? value) + { +#pragma warning disable BL0005 + Metallic = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Metallic)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "metallic", value); + } + + /// + /// Asynchronously set the value of the MetallicRoughnessTexture property after render. + /// + /// + /// The value to set. + /// + public async Task SetMetallicRoughnessTexture(MeshTexture? value) + { + if (value is not null) + { + value.CoreJsModule = CoreJsModule; + value.Parent = this; + value.Layer = Layer; + value.View = View; + } + +#pragma warning disable BL0005 + MetallicRoughnessTexture = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(MetallicRoughnessTexture)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "metallicRoughnessTexture", value); + } + + /// + /// Asynchronously set the value of the OcclusionTexture property after render. + /// + /// + /// The value to set. + /// + public async Task SetOcclusionTexture(MeshTexture? value) + { + if (value is not null) + { + value.CoreJsModule = CoreJsModule; + value.Parent = this; + value.Layer = Layer; + value.View = View; + } + +#pragma warning disable BL0005 + OcclusionTexture = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(OcclusionTexture)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "occlusionTexture", value); + } + + /// + /// Asynchronously set the value of the OcclusionTextureTransform property after render. + /// + /// + /// The value to set. + /// + public async Task SetOcclusionTextureTransform(MeshTextureTransform? value) + { + if (value is not null) + { + value.CoreJsModule = CoreJsModule; + value.Parent = this; + value.Layer = Layer; + value.View = View; + } + +#pragma warning disable BL0005 + OcclusionTextureTransform = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(OcclusionTextureTransform)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "occlusionTextureTransform", value); + } + + /// + /// Asynchronously set the value of the Roughness property after render. + /// + /// + /// The value to set. + /// + public async Task SetRoughness(double? value) + { +#pragma warning disable BL0005 + Roughness = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Roughness)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "roughness", value); + } + +#endregion + +} diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshTexture.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshTexture.cs new file mode 100644 index 000000000..c800ef64f --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshTexture.cs @@ -0,0 +1,518 @@ +namespace dymaptic.GeoBlazor.Core.Components; + +/// +/// GeoBlazor Docs +/// MeshTexture represents image data to be used for MeshMaterial or MeshMaterialMetallicRoughness. +/// ArcGIS Maps SDK for JavaScript +/// +[CodeGenerationIgnore] +[ProtobufSerializable] +public class MeshTexture : MapComponent, IProtobufSerializable +{ + + /// + /// Parameterless constructor for use as a Razor Component. + /// + [ActivatorUtilitiesConstructor] + public MeshTexture() + { + } + + /// + /// Constructor for use in C# code. Use named parameters (e.g., item1: value1, item2: value2) to set properties in any order. + /// + /// + /// A direct reference to the image or video element. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A direct reference to the image data. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Specifies how uv coordinates outside the [0, 1] range are handled. + /// default "repeat" + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Indicates whether the image data should be interpreted as being semi-transparent. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// The url to the image resource. + /// ArcGIS Maps SDK for JavaScript + /// + public MeshTexture( + ElementReference? htmlData = null, + ImageData? imageData = null, + SeparableWrapModes? wrap = null, + bool? transparent = null, + string? url = null) + { + AllowRender = false; +#pragma warning disable BL0005 + HtmlData = htmlData; + ImageData = imageData; + Wrap = wrap; + Transparent = transparent; + Url = url; +#pragma warning restore BL0005 + } + + +#region Public Properties / Blazor Parameters + + /// + /// A direct reference to the image or video data. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ElementReference? HtmlData { get; set; } + + /// + /// A direct reference to the image or video data. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ImageData? ImageData { get; set; } + + /// + /// Specifies how uv coordinates outside the [0, 1] range are handled. + /// default "repeat" + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public SeparableWrapModes? Wrap { get; set; } + + /// + /// Indicates whether the image data should be interpreted as being semi-transparent. + /// default undefined + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Transparent { get; set; } + + /// + /// The url to the image resource. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Url { get; set; } + +#endregion + +#region Property Getters + + /// + /// Asynchronously retrieve the current value of the HtmlData property. + /// + public async Task GetHtmlData() + { + if (CoreJsModule is null) + { + return HtmlData; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return HtmlData; + } + + // get the property value + JsNullableElementReferenceWrapper? result = await CoreJsModule!.InvokeAsync( + "getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "htmlData"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + HtmlData = result.Value.Value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(HtmlData)] = HtmlData; + } + + return HtmlData; + } + + /// + /// Asynchronously retrieve the current value of the ImageData property. + /// + public async Task GetImageData() + { + if (CoreJsModule is null) + { + return ImageData; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return ImageData; + } + + // get the property value + ImageData? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "data"); + if (result is not null) + { +#pragma warning disable BL0005 + ImageData = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(ImageData)] = ImageData; + } + + return ImageData; + } + + + /// + /// Asynchronously retrieve the current value of the SeparableWrapModesWrap property. + /// + public async Task GetWrap() + { + if (CoreJsModule is null) + { + return Wrap; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Wrap; + } + + // get the property value + SeparableWrapModes? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "wrap"); + if (result is not null) + { +#pragma warning disable BL0005 + Wrap = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Wrap)] = Wrap; + } + + return Wrap; + } + + /// + /// Asynchronously retrieve the current value of the Transparent property. + /// + public async Task GetTransparent() + { + if (CoreJsModule is null) + { + return Transparent; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Transparent; + } + + // get the property value + JsNullableBoolWrapper? result = await CoreJsModule!.InvokeAsync("getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "transparent"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + Transparent = result.Value.Value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Transparent)] = Transparent; + } + + return Transparent; + } + + /// + /// Asynchronously retrieve the current value of the Url property. + /// + public async Task GetUrl() + { + if (CoreJsModule is null) + { + return Url; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Url; + } + + // get the property value + string? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "url"); + if (result is not null) + { +#pragma warning disable BL0005 + Url = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Url)] = Url; + } + + return Url; + } + +#endregion + +#region Property Setters + + /// + /// Asynchronously set the value of the HtmlData property after render. + /// + /// + /// The value to set. + /// + public async Task SetHtmlData(ElementReference? value) + { +#pragma warning disable BL0005 + HtmlData = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(HtmlData)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "data", value); + } + + /// + /// Asynchronously set the value of the ImageData property after render. + /// + /// + /// The value to set. + /// + public async Task SetImageData(ImageData? value) + { +#pragma warning disable BL0005 + ImageData = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(ImageData)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "data", value); + } + + /// + /// Asynchronously set the value of the SeparableWrapModesWrap property after render. + /// + /// + /// The value to set. + /// + public async Task SetSeparableWrapModesWrap(SeparableWrapModes? value) + { +#pragma warning disable BL0005 + Wrap = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Wrap)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "wrap", value); + } + + /// + /// Asynchronously set the value of the Transparent property after render. + /// + /// + /// The value to set. + /// + public async Task SetTransparent(bool? value) + { +#pragma warning disable BL0005 + Transparent = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Transparent)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "transparent", value); + } + + /// + /// Asynchronously set the value of the Url property after render. + /// + /// + /// The value to set. + /// + public async Task SetUrl(string? value) + { +#pragma warning disable BL0005 + Url = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Url)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "url", value); + } + +#endregion + + /// + public MeshTextureSerializationRecord ToProtobuf() + { + return new MeshTextureSerializationRecord(ImageData?.ToProtobuf(), + Wrap is null + ? null + : [ + Wrap?.Horizontal?.ToString().ToKebabCase(), + Wrap?.Vertical?.ToString().ToKebabCase() + ], + Transparent, + Url); + } +} diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshTextureTransform.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshTextureTransform.cs new file mode 100644 index 000000000..7f8746fd6 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshTextureTransform.cs @@ -0,0 +1,14 @@ +namespace dymaptic.GeoBlazor.Core.Components; + +[ProtobufSerializable] +public partial class MeshTextureTransform: IProtobufSerializable +{ + // Add custom code to this file to override generated code + + /// + public MeshTextureTransformSerializationRecord ToProtobuf() + { + return new MeshTextureTransformSerializationRecord(Offset?.ToArray(), Rotation, + Scale?.ToArray()); + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshTextureTransform.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshTextureTransform.gb.cs new file mode 100644 index 000000000..c51bed4f7 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshTextureTransform.gb.cs @@ -0,0 +1,396 @@ +// File auto-generated by dymaptic tooling. Any changes made here will be lost on future generation. To override functionality, use the relevant root .cs file. + +namespace dymaptic.GeoBlazor.Core.Components; + + +/// +/// GeoBlazor Docs +/// MeshTextureTransform represents a transformation of UV mesh coordinates used to sample a +/// MeshTexture. +/// ArcGIS Maps SDK for JavaScript +/// +public partial class MeshTextureTransform : MapComponent +{ + + /// + /// Parameterless constructor for use as a Razor Component. + /// + [ActivatorUtilitiesConstructor] + public MeshTextureTransform() + { + } + + /// + /// Constructor for use in C# code. Use named parameters (e.g., item1: value1, item2: value2) to set properties in any order. + /// + /// + /// The offset of the UV coordinate origin as a factor of the texture dimensions. + /// default [0, 0] + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// The rotation of the UV coordinates in degrees, counter-clockwise around the origin. + /// default 0 + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// The scale factor applied to the components of the UV coordinates. + /// default [1, 1] + /// ArcGIS Maps SDK for JavaScript + /// + public MeshTextureTransform( + IReadOnlyList? offset = null, + double? rotation = null, + IReadOnlyList? scale = null) + { + AllowRender = false; +#pragma warning disable BL0005 + Offset = offset; + Rotation = rotation; + Scale = scale; +#pragma warning restore BL0005 + } + + +#region Public Properties / Blazor Parameters + + /// + /// GeoBlazor Docs + /// The offset of the UV coordinate origin as a factor of the texture dimensions. + /// default [0, 0] + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public IReadOnlyList? Offset { get; set; } + + /// + /// GeoBlazor Docs + /// The rotation of the UV coordinates in degrees, counter-clockwise around the origin. + /// default 0 + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? Rotation { get; set; } + + /// + /// GeoBlazor Docs + /// The scale factor applied to the components of the UV coordinates. + /// default [1, 1] + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public IReadOnlyList? Scale { get; set; } + +#endregion + +#region Property Getters + + /// + /// Asynchronously retrieve the current value of the Offset property. + /// + public async Task?> GetOffset() + { + if (CoreJsModule is null) + { + return Offset; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Offset; + } + + // get the property value + IReadOnlyList? result = await JsComponentReference!.InvokeAsync?>("getProperty", + CancellationTokenSource.Token, "offset"); + if (result is not null) + { +#pragma warning disable BL0005 + Offset = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Offset)] = Offset; + } + + return Offset; + } + + /// + /// Asynchronously retrieve the current value of the Rotation property. + /// + public async Task GetRotation() + { + if (CoreJsModule is null) + { + return Rotation; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Rotation; + } + + // get the property value + JsNullableDoubleWrapper? result = await CoreJsModule!.InvokeAsync("getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "rotation"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + Rotation = result.Value.Value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Rotation)] = Rotation; + } + + return Rotation; + } + + /// + /// Asynchronously retrieve the current value of the Scale property. + /// + public async Task?> GetScale() + { + if (CoreJsModule is null) + { + return Scale; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Scale; + } + + // get the property value + IReadOnlyList? result = await JsComponentReference!.InvokeAsync?>("getProperty", + CancellationTokenSource.Token, "scale"); + if (result is not null) + { +#pragma warning disable BL0005 + Scale = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Scale)] = Scale; + } + + return Scale; + } + +#endregion + +#region Property Setters + + /// + /// Asynchronously set the value of the Offset property after render. + /// + /// + /// The value to set. + /// + public async Task SetOffset(IReadOnlyList? value) + { +#pragma warning disable BL0005 + Offset = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Offset)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "offset", value); + } + + /// + /// Asynchronously set the value of the Rotation property after render. + /// + /// + /// The value to set. + /// + public async Task SetRotation(double? value) + { +#pragma warning disable BL0005 + Rotation = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Rotation)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "rotation", value); + } + + /// + /// Asynchronously set the value of the Scale property after render. + /// + /// + /// The value to set. + /// + public async Task SetScale(IReadOnlyList? value) + { +#pragma warning disable BL0005 + Scale = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Scale)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "scale", value); + } + +#endregion + +#region Add to Collection Methods + + /// + /// Asynchronously adds elements to the Offset property. + /// + /// + /// The elements to add. + /// + public async Task AddToOffset(params double[] values) + { + double[] join = Offset is null + ? values + : [..Offset, ..values]; + await SetOffset(join); + } + + /// + /// Asynchronously adds elements to the Scale property. + /// + /// + /// The elements to add. + /// + public async Task AddToScale(params double[] values) + { + double[] join = Scale is null + ? values + : [..Scale, ..values]; + await SetScale(join); + } + +#endregion + +#region Remove From Collection Methods + + + /// + /// Asynchronously remove an element from the Offset property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromOffset(params double[] values) + { + if (Offset is null) + { + return; + } + await SetOffset(Offset.Except(values).ToArray()); + } + + + /// + /// Asynchronously remove an element from the Scale property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromScale(params double[] values) + { + if (Scale is null) + { + return; + } + await SetScale(Scale.Except(values).ToArray()); + } + +#endregion + +} diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshTransform.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshTransform.cs new file mode 100644 index 000000000..db8a44295 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshTransform.cs @@ -0,0 +1,16 @@ +namespace dymaptic.GeoBlazor.Core.Components; + +[ProtobufSerializable] +public partial class MeshTransform: IProtobufSerializable +{ + // Add custom code to this file to override generated code + /// + public MeshTransformSerializationRecord ToProtobuf() + { + return new MeshTransformSerializationRecord( + RotationAngle, + RotationAxis?.ToArray(), + Scale?.ToArray(), + Translation?.ToArray()); + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshTransform.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshTransform.gb.cs new file mode 100644 index 000000000..2a1e33410 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshTransform.gb.cs @@ -0,0 +1,519 @@ +// File auto-generated by dymaptic tooling. Any changes made here will be lost on future generation. To override functionality, use the relevant root .cs file. + +namespace dymaptic.GeoBlazor.Core.Components; + + +/// +/// GeoBlazor Docs +/// A mesh transform. +/// ArcGIS Maps SDK for JavaScript +/// +public partial class MeshTransform : MapComponent +{ + + /// + /// Parameterless constructor for use as a Razor Component. + /// + [ActivatorUtilitiesConstructor] + public MeshTransform() + { + } + + /// + /// Constructor for use in C# code. Use named parameters (e.g., item1: value1, item2: value2) to set properties in any order. + /// + /// + /// Rotation angle in degrees. + /// default 0 + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Axis of rotation. + /// default [0, 0, 1] + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Scale. + /// default [1, 1, 1] + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Translation. + /// default [0, 0, 0] + /// ArcGIS Maps SDK for JavaScript + /// + public MeshTransform( + double? rotationAngle = null, + IReadOnlyList? rotationAxis = null, + IReadOnlyList? scale = null, + IReadOnlyList? translation = null) + { + AllowRender = false; +#pragma warning disable BL0005 + RotationAngle = rotationAngle; + RotationAxis = rotationAxis; + Scale = scale; + Translation = translation; +#pragma warning restore BL0005 + } + + +#region Public Properties / Blazor Parameters + + /// + /// GeoBlazor Docs + /// Rotation angle in degrees. + /// default 0 + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? RotationAngle { get; set; } + + /// + /// GeoBlazor Docs + /// Axis of rotation. + /// default [0, 0, 1] + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public IReadOnlyList? RotationAxis { get; set; } + + /// + /// GeoBlazor Docs + /// Scale. + /// default [1, 1, 1] + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public IReadOnlyList? Scale { get; set; } + + /// + /// GeoBlazor Docs + /// Translation. + /// default [0, 0, 0] + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public IReadOnlyList? Translation { get; set; } + +#endregion + +#region Property Getters + + /// + /// Asynchronously retrieve the current value of the RotationAngle property. + /// + public async Task GetRotationAngle() + { + if (CoreJsModule is null) + { + return RotationAngle; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return RotationAngle; + } + + // get the property value + JsNullableDoubleWrapper? result = await CoreJsModule!.InvokeAsync("getNullableValueTypedProperty", + CancellationTokenSource.Token, JsComponentReference, "rotationAngle"); + if (result is { Value: not null }) + { +#pragma warning disable BL0005 + RotationAngle = result.Value.Value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(RotationAngle)] = RotationAngle; + } + + return RotationAngle; + } + + /// + /// Asynchronously retrieve the current value of the RotationAxis property. + /// + public async Task?> GetRotationAxis() + { + if (CoreJsModule is null) + { + return RotationAxis; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return RotationAxis; + } + + // get the property value + IReadOnlyList? result = await JsComponentReference!.InvokeAsync?>("getProperty", + CancellationTokenSource.Token, "rotationAxis"); + if (result is not null) + { +#pragma warning disable BL0005 + RotationAxis = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(RotationAxis)] = RotationAxis; + } + + return RotationAxis; + } + + /// + /// Asynchronously retrieve the current value of the Scale property. + /// + public async Task?> GetScale() + { + if (CoreJsModule is null) + { + return Scale; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Scale; + } + + // get the property value + IReadOnlyList? result = await JsComponentReference!.InvokeAsync?>("getProperty", + CancellationTokenSource.Token, "scale"); + if (result is not null) + { +#pragma warning disable BL0005 + Scale = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Scale)] = Scale; + } + + return Scale; + } + + /// + /// Asynchronously retrieve the current value of the Translation property. + /// + public async Task?> GetTranslation() + { + if (CoreJsModule is null) + { + return Translation; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Translation; + } + + // get the property value + IReadOnlyList? result = await JsComponentReference!.InvokeAsync?>("getProperty", + CancellationTokenSource.Token, "translation"); + if (result is not null) + { +#pragma warning disable BL0005 + Translation = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Translation)] = Translation; + } + + return Translation; + } + +#endregion + +#region Property Setters + + /// + /// Asynchronously set the value of the RotationAngle property after render. + /// + /// + /// The value to set. + /// + public async Task SetRotationAngle(double? value) + { +#pragma warning disable BL0005 + RotationAngle = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(RotationAngle)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "rotationAngle", value); + } + + /// + /// Asynchronously set the value of the RotationAxis property after render. + /// + /// + /// The value to set. + /// + public async Task SetRotationAxis(IReadOnlyList? value) + { +#pragma warning disable BL0005 + RotationAxis = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(RotationAxis)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "rotationAxis", value); + } + + /// + /// Asynchronously set the value of the Scale property after render. + /// + /// + /// The value to set. + /// + public async Task SetScale(IReadOnlyList? value) + { +#pragma warning disable BL0005 + Scale = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Scale)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "scale", value); + } + + /// + /// Asynchronously set the value of the Translation property after render. + /// + /// + /// The value to set. + /// + public async Task SetTranslation(IReadOnlyList? value) + { +#pragma warning disable BL0005 + Translation = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Translation)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "translation", value); + } + +#endregion + +#region Add to Collection Methods + + /// + /// Asynchronously adds elements to the RotationAxis property. + /// + /// + /// The elements to add. + /// + public async Task AddToRotationAxis(params double[] values) + { + double[] join = RotationAxis is null + ? values + : [..RotationAxis, ..values]; + await SetRotationAxis(join); + } + + /// + /// Asynchronously adds elements to the Scale property. + /// + /// + /// The elements to add. + /// + public async Task AddToScale(params double[] values) + { + double[] join = Scale is null + ? values + : [..Scale, ..values]; + await SetScale(join); + } + + /// + /// Asynchronously adds elements to the Translation property. + /// + /// + /// The elements to add. + /// + public async Task AddToTranslation(params double[] values) + { + double[] join = Translation is null + ? values + : [..Translation, ..values]; + await SetTranslation(join); + } + +#endregion + +#region Remove From Collection Methods + + + /// + /// Asynchronously remove an element from the RotationAxis property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromRotationAxis(params double[] values) + { + if (RotationAxis is null) + { + return; + } + await SetRotationAxis(RotationAxis.Except(values).ToArray()); + } + + + /// + /// Asynchronously remove an element from the Scale property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromScale(params double[] values) + { + if (Scale is null) + { + return; + } + await SetScale(Scale.Except(values).ToArray()); + } + + + /// + /// Asynchronously remove an element from the Translation property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromTranslation(params double[] values) + { + if (Translation is null) + { + return; + } + await SetTranslation(Translation.Except(values).ToArray()); + } + +#endregion + +} diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshVertexAttributes.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshVertexAttributes.cs new file mode 100644 index 000000000..bb9efa7f8 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshVertexAttributes.cs @@ -0,0 +1,60 @@ +namespace dymaptic.GeoBlazor.Core.Components; + +[ProtobufSerializable] +public partial class MeshVertexAttributes: IProtobufSerializable +{ + // Add custom code to this file to override generated code + + /// + /// Asynchronously retrieve the current value of the Color property. + /// + [CodeGenerationIgnore] + public async Task GetColor() + { + if (CoreJsModule is null) + { + return Color; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Color; + } + + // get the property value + IJSStreamReference? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "color"); + if (result is not null) + { + await using Stream stream = await result.OpenReadStreamAsync(1_000_000_000); + await using MemoryStream ms = new MemoryStream(); + await stream.CopyToAsync(ms); +#pragma warning disable BL0005 + Color = ms.ToArray(); +#pragma warning restore BL0005 + ModifiedParameters[nameof(Color)] = Color; + } + + return Color; + } + + /// + public MeshVertexAttributesSerializationRecord ToProtobuf() + { + return new MeshVertexAttributesSerializationRecord(Color, + Normal, + Position, + Tangent, + Uv); + } +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/MeshVertexAttributes.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/MeshVertexAttributes.gb.cs new file mode 100644 index 000000000..ea75c3932 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Components/MeshVertexAttributes.gb.cs @@ -0,0 +1,624 @@ +// File auto-generated by dymaptic tooling. Any changes made here will be lost on future generation. To override functionality, use the relevant root .cs file. + +namespace dymaptic.GeoBlazor.Core.Components; + + +/// +/// GeoBlazor Docs +/// Object describing the attributes of each vertex of the mesh. +/// ArcGIS Maps SDK for JavaScript +/// +public partial class MeshVertexAttributes : MapComponent +{ + + /// + /// Parameterless constructor for use as a Razor Component. + /// + [ActivatorUtilitiesConstructor] + public MeshVertexAttributes() + { + } + + /// + /// Constructor for use in C# code. Use named parameters (e.g., item1: value1, item2: value2) to set properties in any order. + /// + /// + /// Since: 4.9 A flat array of the vertex colors (4 elements per vertex ranging from 0 to 255). + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A flat array of the vertex normals (3 elements per vertex ranging from -1 to 1). + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A flat array of vertex positions. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// Since: 4.11 A flat array of the vertex tangents (4 elements per vertex ranging from -1 to 1. + /// ArcGIS Maps SDK for JavaScript + /// + /// + /// A flat array of vertex uv coordinates (2 elements per vertex). + /// ArcGIS Maps SDK for JavaScript + /// + public MeshVertexAttributes( + byte[]? color = null, + double[]? normal = null, + double[]? position = null, + double[]? tangent = null, + double[]? uv = null) + { + AllowRender = false; +#pragma warning disable BL0005 + Color = color; + Normal = normal; + Position = position; + Tangent = tangent; + Uv = uv; +#pragma warning restore BL0005 + } + + +#region Public Properties / Blazor Parameters + + /// + /// GeoBlazor Docs + /// Since: 4.9 A flat array of the vertex colors (4 elements per vertex ranging from 0 to 255). + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public byte[]? Color { get; set; } + + /// + /// GeoBlazor Docs + /// A flat array of the vertex normals (3 elements per vertex ranging from -1 to 1). + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double[]? Normal { get; set; } + + /// + /// GeoBlazor Docs + /// A flat array of vertex positions. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double[]? Position { get; set; } + + /// + /// GeoBlazor Docs + /// Since: 4.11 A flat array of the vertex tangents (4 elements per vertex ranging from -1 to 1. + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double[]? Tangent { get; set; } + + /// + /// GeoBlazor Docs + /// A flat array of vertex uv coordinates (2 elements per vertex). + /// ArcGIS Maps SDK for JavaScript + /// + [ArcGISProperty] + [Parameter] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double[]? Uv { get; set; } + +#endregion + +#region Property Getters + + /// + /// Asynchronously retrieve the current value of the Normal property. + /// + public async Task GetNormal() + { + if (CoreJsModule is null) + { + return Normal; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Normal; + } + + // get the property value + double[]? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "normal"); + if (result is not null) + { +#pragma warning disable BL0005 + Normal = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Normal)] = Normal; + } + + return Normal; + } + + /// + /// Asynchronously retrieve the current value of the Position property. + /// + public async Task GetPosition() + { + if (CoreJsModule is null) + { + return Position; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Position; + } + + // get the property value + double[]? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "position"); + if (result is not null) + { +#pragma warning disable BL0005 + Position = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Position)] = Position; + } + + return Position; + } + + /// + /// Asynchronously retrieve the current value of the Tangent property. + /// + public async Task GetTangent() + { + if (CoreJsModule is null) + { + return Tangent; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Tangent; + } + + // get the property value + double[]? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "tangent"); + if (result is not null) + { +#pragma warning disable BL0005 + Tangent = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Tangent)] = Tangent; + } + + return Tangent; + } + + /// + /// Asynchronously retrieve the current value of the Uv property. + /// + public async Task GetUv() + { + if (CoreJsModule is null) + { + return Uv; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return Uv; + } + + // get the property value + double[]? result = await JsComponentReference!.InvokeAsync("getProperty", + CancellationTokenSource.Token, "uv"); + if (result is not null) + { +#pragma warning disable BL0005 + Uv = result; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Uv)] = Uv; + } + + return Uv; + } + +#endregion + +#region Property Setters + + /// + /// Asynchronously set the value of the Color property after render. + /// + /// + /// The value to set. + /// + public async Task SetColor(byte[]? value) + { +#pragma warning disable BL0005 + Color = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Color)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "color", value); + } + + /// + /// Asynchronously set the value of the Normal property after render. + /// + /// + /// The value to set. + /// + public async Task SetNormal(double[]? value) + { +#pragma warning disable BL0005 + Normal = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Normal)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "normal", value); + } + + /// + /// Asynchronously set the value of the Position property after render. + /// + /// + /// The value to set. + /// + public async Task SetPosition(double[]? value) + { +#pragma warning disable BL0005 + Position = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Position)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "position", value); + } + + /// + /// Asynchronously set the value of the Tangent property after render. + /// + /// + /// The value to set. + /// + public async Task SetTangent(double[]? value) + { +#pragma warning disable BL0005 + Tangent = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Tangent)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "tangent", value); + } + + /// + /// Asynchronously set the value of the Uv property after render. + /// + /// + /// The value to set. + /// + public async Task SetUv(double[]? value) + { +#pragma warning disable BL0005 + Uv = value; +#pragma warning restore BL0005 + ModifiedParameters[nameof(Uv)] = value; + + if (CoreJsModule is null) + { + return; + } + + try + { + JsComponentReference ??= await CoreJsModule.InvokeAsync( + "getJsComponent", CancellationTokenSource.Token, Id); + } + catch (JSException) + { + // this is expected if the component is not yet built + } + + if (JsComponentReference is null) + { + return; + } + + await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token, + JsComponentReference, "uv", value); + } + +#endregion + +#region Add to Collection Methods + + /// + /// Asynchronously adds elements to the Color property. + /// + /// + /// The elements to add. + /// + public async Task AddToColor(params byte[] values) + { + byte[] join = Color is null + ? values + : [..Color, ..values]; + await SetColor(join); + } + + /// + /// Asynchronously adds elements to the Normal property. + /// + /// + /// The elements to add. + /// + public async Task AddToNormal(params double[] values) + { + double[] join = Normal is null + ? values + : [..Normal, ..values]; + await SetNormal(join); + } + + /// + /// Asynchronously adds elements to the Position property. + /// + /// + /// The elements to add. + /// + public async Task AddToPosition(params double[] values) + { + double[] join = Position is null + ? values + : [..Position, ..values]; + await SetPosition(join); + } + + /// + /// Asynchronously adds elements to the Tangent property. + /// + /// + /// The elements to add. + /// + public async Task AddToTangent(params double[] values) + { + double[] join = Tangent is null + ? values + : [..Tangent, ..values]; + await SetTangent(join); + } + + /// + /// Asynchronously adds elements to the Uv property. + /// + /// + /// The elements to add. + /// + public async Task AddToUv(params double[] values) + { + double[] join = Uv is null + ? values + : [..Uv, ..values]; + await SetUv(join); + } + +#endregion + +#region Remove From Collection Methods + + + /// + /// Asynchronously remove an element from the Color property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromColor(params byte[] values) + { + if (Color is null) + { + return; + } + await SetColor(Color.Except(values).ToArray()); + } + + + /// + /// Asynchronously remove an element from the Normal property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromNormal(params double[] values) + { + if (Normal is null) + { + return; + } + await SetNormal(Normal.Except(values).ToArray()); + } + + + /// + /// Asynchronously remove an element from the Position property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromPosition(params double[] values) + { + if (Position is null) + { + return; + } + await SetPosition(Position.Except(values).ToArray()); + } + + + /// + /// Asynchronously remove an element from the Tangent property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromTangent(params double[] values) + { + if (Tangent is null) + { + return; + } + await SetTangent(Tangent.Except(values).ToArray()); + } + + + /// + /// Asynchronously remove an element from the Uv property. + /// + /// + /// The elements to remove. + /// + public async Task RemoveFromUv(params double[] values) + { + if (Uv is null) + { + return; + } + await SetUv(Uv.Except(values).ToArray()); + } + +#endregion + +} diff --git a/src/dymaptic.GeoBlazor.Core/Components/PieChartMediaInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/PieChartMediaInfo.cs index 1e9e4f668..6bd6c73f0 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/PieChartMediaInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/PieChartMediaInfo.cs @@ -1,21 +1,19 @@ namespace dymaptic.GeoBlazor.Core.Components; +[ProtobufSerializable] public partial class PieChartMediaInfo : MediaInfo { - - /// public override string Type => "pie-chart"; - - internal override MediaInfoSerializationRecord ToSerializationRecord() + public override MediaInfoSerializationRecord ToProtobuf() { return new MediaInfoSerializationRecord(Id.ToString(), "pie-chart") { AltText = AltText, Caption = Caption, Title = Title, - Value = Value?.ToSerializationRecord() + Value = Value?.ToProtobuf() }; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/AttachmentsPopupContent.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/AttachmentsPopupContent.cs index 667a7a345..5f9c4e3f6 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Popups/AttachmentsPopupContent.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/AttachmentsPopupContent.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Popups; +[ProtobufSerializable] public partial class AttachmentsPopupContent : PopupContent { - - /// public override PopupContentType Type => PopupContentType.Attachments; @@ -32,7 +31,8 @@ public partial class AttachmentsPopupContent : PopupContent public string? Title { get; set; } - internal override PopupContentSerializationRecord ToSerializationRecord() + /// + public override PopupContentSerializationRecord ToProtobuf() { return new PopupContentSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase()) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/ExpressionPopupContent.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/ExpressionPopupContent.cs index 1bfa5f21e..f6206fa52 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Popups/ExpressionPopupContent.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/ExpressionPopupContent.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Popups; +[ProtobufSerializable] public partial class ExpressionPopupContent : PopupContent { - - /// public override PopupContentType Type => PopupContentType.Expression; @@ -14,11 +13,12 @@ public partial class ExpressionPopupContent : PopupContent [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ElementExpressionInfo? ExpressionInfo { get; set; } - internal override PopupContentSerializationRecord ToSerializationRecord() + /// + public override PopupContentSerializationRecord ToProtobuf() { return new PopupContentSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase()) { - ExpressionInfo = ExpressionInfo?.ToSerializationRecord() + ExpressionInfo = ExpressionInfo?.ToProtobuf() }; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/FieldsPopupContent.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/FieldsPopupContent.cs index 14569acbc..d4b89116c 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Popups/FieldsPopupContent.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/FieldsPopupContent.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Popups; +[ProtobufSerializable] public partial class FieldsPopupContent : PopupContent { - - /// /// Describes the field's content in detail. /// @@ -56,11 +55,12 @@ public override async Task UnregisterChildComponent(MapComponent child) } - internal override PopupContentSerializationRecord ToSerializationRecord() + /// + public override PopupContentSerializationRecord ToProtobuf() { return new PopupContentSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase()) { - FieldInfos = FieldInfos?.Select(i => i.ToSerializationRecord()).ToArray(), + FieldInfos = FieldInfos?.Select(i => i.ToProtobuf()).ToArray(), Description = Description, Title = Title }; } diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/MediaPopupContent.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/MediaPopupContent.cs index 066ef071f..5a91c9824 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Popups/MediaPopupContent.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/MediaPopupContent.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Popups; +[ProtobufSerializable] public partial class MediaPopupContent : PopupContent { - - /// public override PopupContentType Type => PopupContentType.Media; @@ -72,14 +71,15 @@ public override async Task UnregisterChildComponent(MapComponent child) } - internal override PopupContentSerializationRecord ToSerializationRecord() + /// + public override PopupContentSerializationRecord ToProtobuf() { return new PopupContentSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase()) { ActiveMediaInfoIndex = ActiveMediaInfoIndex, Description = Description, Title = Title, - MediaInfos = MediaInfos?.Select(x => x.ToSerializationRecord()).ToArray() + MediaInfos = MediaInfos?.Select(x => x.ToProtobuf()).ToArray() }; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupContent.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupContent.cs index f61388b65..f3d931eb0 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupContent.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupContent.cs @@ -1,120 +1,16 @@ namespace dymaptic.GeoBlazor.Core.Components.Popups; [JsonConverter(typeof(PopupContentConverter))] -public abstract partial class PopupContent : MapComponent +[ProtobufSerializable] +public abstract partial class PopupContent : MapComponent, IProtobufSerializable { /// /// The type of Popup Content /// public abstract PopupContentType Type { get; } - internal abstract PopupContentSerializationRecord ToSerializationRecord(); -} - -[ProtoContract(Name = "PopupContent")] -internal record PopupContentSerializationRecord : MapComponentSerializationRecord -{ - public PopupContentSerializationRecord() - { - } - - public PopupContentSerializationRecord(string Id, string Type) - { - this.Type = Type; - this.Id = Id; - } - - [ProtoMember(1)] - public string Type { get; init; } = string.Empty; - - [ProtoMember(2)] - public string? Description { get; init; } - - [ProtoMember(3)] - public string? DisplayType { get; init; } - - [ProtoMember(4)] - public string? Title { get; init; } - - [ProtoMember(5)] - public ElementExpressionInfoSerializationRecord? ExpressionInfo { get; init; } - - [ProtoMember(6)] - public FieldInfoSerializationRecord[]? FieldInfos { get; init; } - - [ProtoMember(7)] - public int? ActiveMediaInfoIndex { get; init; } - - [ProtoMember(8)] - public MediaInfoSerializationRecord[]? MediaInfos { get; init; } - - [ProtoMember(9)] - public int? DisplayCount { get; init; } - - [ProtoMember(10)] - public RelatedRecordsInfoFieldOrderSerializationRecord[]? OrderByFields { get; init; } - - [ProtoMember(11)] - public long? RelationshipId { get; init; } - - [ProtoMember(12)] - public string? Text { get; init; } - - [ProtoMember(13)] - public string? Id { get; set; } - - [ProtoMember(14)] - public string[]? OutFields { get; init; } - - public PopupContent FromSerializationRecord() - { - Guid id = Guid.NewGuid(); - - if (Guid.TryParse(Id, out Guid guidId)) - { - id = guidId; - } - - if (Type == "custom") - { - // CustomPopupContent is in GeoBlazor Pro assembly, so we need to use reflection to get the type - Type? customType = System.Type.GetType("dymaptic.GeoBlazor.Pro.Components.Popups.CustomPopupContent, dymaptic.GeoBlazor.Pro"); - - if (customType is not null && customType.IsSubclassOf(typeof(PopupContent))) - { - PopupContent? customContent = Activator.CreateInstance(customType, args: [null, OutFields]) as PopupContent; - - if (customContent is null) - { - throw new InvalidOperationException("CustomPopupContent could not be created. Ensure the type is correct and the assembly is loaded."); - } - customContent.Id = id; - - return customContent; - } - } - - return Type switch - { - "fields" => new FieldsPopupContent(FieldInfos?.Select(i => - i.FromSerializationRecord()).ToArray() ?? [], - Description, Title) { Id = id }, - "text" => new TextPopupContent(Text){ Id = id }, - "attachments" => new AttachmentsPopupContent(Title, Description, - DisplayType is null ? null : Enum.Parse(DisplayType)) - { - Id = id - }, - "expression" => new ExpressionPopupContent(ExpressionInfo?.FromSerializationRecord()) { Id = id }, - "media" => new MediaPopupContent(Title, Description, - MediaInfos?.Select(i => i.FromSerializationRecord()).ToArray(), - ActiveMediaInfoIndex) { Id = id }, - "relationship" => new RelationshipPopupContent(Title, Description, DisplayCount, - DisplayType, OrderByFields?.Select(x => x.FromSerializationRecord()).ToList(), - RelationshipId) { Id = id }, - _ => throw new NotSupportedException($"PopupContent type {Type} is not supported") - }; - } + /// + public abstract PopupContentSerializationRecord ToProtobuf(); } internal class PopupContentConverter : JsonConverter diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupExpressionInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupExpressionInfo.cs index c87bcde40..7fb8f4436 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupExpressionInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupExpressionInfo.cs @@ -1,60 +1,11 @@ namespace dymaptic.GeoBlazor.Core.Components.Popups; -public partial class PopupExpressionInfo : MapComponent +[ProtobufSerializable] +public partial class PopupExpressionInfo : MapComponent, IProtobufSerializable { - internal PopupExpressionInfoSerializationRecord ToSerializationRecord() + /// + public PopupExpressionInfoSerializationRecord ToProtobuf() { return new PopupExpressionInfoSerializationRecord(Id.ToString(), Expression, Name, Title, ReturnType); } -} - -[ProtoContract(Name = "ExpressionInfo")] -internal record PopupExpressionInfoSerializationRecord : MapComponentSerializationRecord -{ - public PopupExpressionInfoSerializationRecord() - { - } - - public PopupExpressionInfoSerializationRecord(string Id, string? Expression, string? Name, string? Title, - PopupExpressionInfoReturnType? ReturnType) - { - this.Id = Id; - this.Expression = Expression; - this.Name = Name; - this.Title = Title; - this.ReturnType = ReturnType.ToString(); - } - - public PopupExpressionInfo FromSerializationRecord() - { - Guid id = Guid.NewGuid(); - - if (Guid.TryParse(Id, out Guid guid)) - { - id = guid; - } - - return new PopupExpressionInfo(Expression, Name, - ReturnType is null ? null : Enum.Parse(ReturnType), - Title) { Id = id }; - } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(1)] - public string? Expression { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public string? Name { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public string? Title { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(4)] - public string? ReturnType { get; init; } - - [ProtoMember(5)] - public string? Id { get; init; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupTemplate.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupTemplate.cs index fbb3112c8..c8b8e6812 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupTemplate.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupTemplate.cs @@ -1,6 +1,7 @@ namespace dymaptic.GeoBlazor.Core.Components.Popups; -public partial class PopupTemplate : MapComponent +[ProtobufSerializable] +public partial class PopupTemplate : MapComponent, IProtobufSerializable { /// /// Parameterless constructor for using as a razor component @@ -237,93 +238,13 @@ public override void ValidateRequiredChildren() } - internal PopupTemplateSerializationRecord ToSerializationRecord() + /// + public PopupTemplateSerializationRecord ToProtobuf() { return new PopupTemplateSerializationRecord(Title, StringContent, OutFields, - FieldInfos?.Select(f => f.ToSerializationRecord()), - Content?.Select(c => c.ToSerializationRecord()), - ExpressionInfos?.Select(e => e.ToSerializationRecord()), OverwriteActions, - ReturnGeometry, Actions?.Select(a => a.ToSerializationRecord()), Id.ToString()); - } -} - -[ProtoContract(Name = "PopupTemplate")] -internal record PopupTemplateSerializationRecord : MapComponentSerializationRecord -{ - public PopupTemplateSerializationRecord() - { - } - - public PopupTemplateSerializationRecord(string? Title, - string? StringContent = null, - IEnumerable? OutFields = null, - IEnumerable? FieldInfos = null, - IEnumerable? Content = null, - IEnumerable? ExpressionInfos = null, - bool? OverwriteActions = null, - bool? ReturnGeometry = null, - IEnumerable? Actions = null, - string? Id = null) - { - this.Title = Title; - this.StringContent = StringContent; - this.OutFields = OutFields; - this.FieldInfos = FieldInfos; - this.Content = Content; - this.ExpressionInfos = ExpressionInfos; - this.OverwriteActions = OverwriteActions; - this.ReturnGeometry = ReturnGeometry; - this.Actions = Actions; - this.Id = Id; + FieldInfos?.Select(f => f.ToProtobuf()), + Content?.Select(c => c.ToProtobuf()), + ExpressionInfos?.Select(e => e.ToProtobuf()), OverwriteActions, + ReturnGeometry, Actions?.Select(a => a.ToProtobuf()), Id.ToString()); } - - public PopupTemplate FromSerializationRecord() - { - return new PopupTemplate(Title, StringContent, OutFields?.ToList(), - FieldInfos?.Select(f => f.FromSerializationRecord()).ToList(), - Content?.Select(c => c.FromSerializationRecord()).ToList(), - ExpressionInfos?.Select(e => e.FromSerializationRecord()).ToList(), - OverwriteActions, ReturnGeometry, - Actions?.Select(a => a.FromSerializationRecord()).ToList()); - } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(1)] - public string? Title { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public string? StringContent { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public IEnumerable? OutFields { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(4)] - public IEnumerable? FieldInfos { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(5)] - public IEnumerable? Content { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(6)] - public IEnumerable? ExpressionInfos { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(7)] - public bool? OverwriteActions { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(8)] - public bool? ReturnGeometry { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(9)] - public IEnumerable? Actions { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(10)] - public string? Id { get; init; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/RelationshipPopupContent.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/RelationshipPopupContent.cs index 637971f62..2691fdffa 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Popups/RelationshipPopupContent.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/RelationshipPopupContent.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Popups; +[ProtobufSerializable] public partial class RelationshipPopupContent : PopupContent { - - /// public override PopupContentType Type => PopupContentType.Relationship; @@ -49,14 +48,15 @@ public partial class RelationshipPopupContent : PopupContent [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Title { get; set; } - internal override PopupContentSerializationRecord ToSerializationRecord() + /// + public override PopupContentSerializationRecord ToProtobuf() { return new PopupContentSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase()) { Description = Description, DisplayCount = DisplayCount, DisplayType = DisplayType, - OrderByFields = OrderByFields?.Select(r => r.ToSerializationRecord()).ToArray(), + OrderByFields = OrderByFields?.Select(r => r.ToProtobuf()).ToArray(), RelationshipId = RelationshipId, Title = Title }; diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/TextPopupContent.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/TextPopupContent.cs index a07cc6583..214d53f84 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Popups/TextPopupContent.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/TextPopupContent.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Popups; +[ProtobufSerializable] public partial class TextPopupContent : PopupContent { - - /// public override PopupContentType Type => PopupContentType.Text; @@ -17,7 +16,8 @@ public partial class TextPopupContent : PopupContent [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Text { get; set; } - internal override PopupContentSerializationRecord ToSerializationRecord() + /// + public override PopupContentSerializationRecord ToProtobuf() { return new PopupContentSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase()) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/RelatedRecordsInfoFieldOrder.cs b/src/dymaptic.GeoBlazor.Core/Components/RelatedRecordsInfoFieldOrder.cs index ccac34bef..896a1912d 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/RelatedRecordsInfoFieldOrder.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/RelatedRecordsInfoFieldOrder.cs @@ -5,7 +5,9 @@ namespace dymaptic.GeoBlazor.Core.Components; /// ArcGIS Maps SDK for JavaScript /// [CodeGenerationIgnore] -public class RelatedRecordsInfoFieldOrder : MapComponent +[ProtobufSerializable] +public class RelatedRecordsInfoFieldOrder : MapComponent, + IProtobufSerializable { /// /// Parameterless constructor for use as a Razor Component. @@ -44,26 +46,10 @@ public RelatedRecordsInfoFieldOrder(string? field, OrderBy? order) [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public OrderBy? Order { get; set; } - internal RelatedRecordsInfoFieldOrderSerializationRecord ToSerializationRecord() + /// + public RelatedRecordsInfoFieldOrderSerializationRecord ToProtobuf() { - return new RelatedRecordsInfoFieldOrderSerializationRecord(Field, Order, Id.ToString()); - } -} - -[ProtoContract(Name = "RelatedRecordsInfoFieldOrder")] -internal record RelatedRecordsInfoFieldOrderSerializationRecord( - [property: ProtoMember(1)] string? Field, - [property: ProtoMember(2)] OrderBy? Order, - [property: ProtoMember(3)] string Id) -{ - public RelatedRecordsInfoFieldOrder FromSerializationRecord() - { - Guid id = Guid.NewGuid(); - - if (Guid.TryParse(Id, out Guid guid)) - { - id = guid; - } - return new(Field, Order) { Id = id }; + return new RelatedRecordsInfoFieldOrderSerializationRecord(Field, Order?.ToString().ToKebabCase(), + Id.ToString()); } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Renderers/SimpleRenderer.cs b/src/dymaptic.GeoBlazor.Core/Components/Renderers/SimpleRenderer.cs index da6a8876a..ff5ab1412 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Renderers/SimpleRenderer.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Renderers/SimpleRenderer.cs @@ -37,7 +37,7 @@ public virtual async Task SetSymbol(Symbol symbol) if (CoreJsModule is not null) { await CoreJsModule.InvokeVoidAsync("setGraphicSymbol", - Id, Symbol.ToSerializationRecord()); + Id, Symbol.ToProtobuf()); } } diff --git a/src/dymaptic.GeoBlazor.Core/Components/SearchViewModel.cs b/src/dymaptic.GeoBlazor.Core/Components/SearchViewModel.cs index c7d87fcff..e2d503e20 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/SearchViewModel.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/SearchViewModel.cs @@ -21,7 +21,7 @@ public partial class SearchViewModel : MapComponent [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference()!; + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON()!; if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); diff --git a/src/dymaptic.GeoBlazor.Core/Components/SearchViewModel.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/SearchViewModel.gb.cs index f731314be..f6ae298dd 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/SearchViewModel.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/SearchViewModel.gb.cs @@ -3070,7 +3070,7 @@ public async Task OnJsSearchClear(IJSStreamReference jsStreamRef) return; } - SearchViewModelSearchClearEvent? searchClearEvent = await jsStreamRef.ReadJsStreamReference(); + SearchViewModelSearchClearEvent? searchClearEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (searchClearEvent is not null) { await OnSearchClear.InvokeAsync(searchClearEvent); @@ -3102,7 +3102,7 @@ public async Task OnJsSearchComplete(IJSStreamReference jsStreamRef) return; } - SearchViewModelSearchCompleteEvent? searchCompleteEvent = await jsStreamRef.ReadJsStreamReference(); + SearchViewModelSearchCompleteEvent? searchCompleteEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (searchCompleteEvent is not null) { await OnSearchComplete.InvokeAsync(searchCompleteEvent); @@ -3134,7 +3134,7 @@ public async Task OnJsSearchStart(IJSStreamReference jsStreamRef) return; } - SearchViewModelSearchStartEvent? searchStartEvent = await jsStreamRef.ReadJsStreamReference(); + SearchViewModelSearchStartEvent? searchStartEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (searchStartEvent is not null) { await OnSearchStart.InvokeAsync(searchStartEvent); @@ -3166,7 +3166,7 @@ public async Task OnJsSelectResult(IJSStreamReference jsStreamRef) return; } - SearchViewModelSelectResultEvent? selectResultEvent = await jsStreamRef.ReadJsStreamReference(); + SearchViewModelSelectResultEvent? selectResultEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (selectResultEvent is not null) { await OnSelectResult.InvokeAsync(selectResultEvent); @@ -3198,7 +3198,7 @@ public async Task OnJsSuggestComplete(IJSStreamReference jsStreamRef) return; } - SearchViewModelSuggestCompleteEvent? suggestCompleteEvent = await jsStreamRef.ReadJsStreamReference(); + SearchViewModelSuggestCompleteEvent? suggestCompleteEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (suggestCompleteEvent is not null) { await OnSuggestComplete.InvokeAsync(suggestCompleteEvent); @@ -3230,7 +3230,7 @@ public async Task OnJsSuggestStart(IJSStreamReference jsStreamRef) return; } - SearchViewModelSuggestStartEvent? suggestStartEvent = await jsStreamRef.ReadJsStreamReference(); + SearchViewModelSuggestStartEvent? suggestStartEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (suggestStartEvent is not null) { await OnSuggestStart.InvokeAsync(suggestStartEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/SpatialReference.cs b/src/dymaptic.GeoBlazor.Core/Components/SpatialReference.cs index b6c34a734..37642446d 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/SpatialReference.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/SpatialReference.cs @@ -1,7 +1,9 @@ namespace dymaptic.GeoBlazor.Core.Components; [JsonConverter(typeof(SpatialReferenceConverter))] -public partial class SpatialReference : MapComponent, IEquatable +[ProtobufSerializable] +public partial class SpatialReference : MapComponent, IEquatable, + IProtobufSerializable { /// /// Constructor for use in C# code. @@ -106,9 +108,10 @@ public SpatialReference Clone() return Wkid.HasValue ? new SpatialReference(Wkid!.Value) : new SpatialReference(); } - internal SpatialReferenceSerializationRecord ToSerializationRecord() + /// + public SpatialReferenceSerializationRecord ToProtobuf() { - return new SpatialReferenceSerializationRecord(Wkid, Wkt); + return new SpatialReferenceSerializationRecord(Wkid, Wkt, Wkt2); } /// @@ -234,31 +237,4 @@ public override void Write(Utf8JsonWriter writer, SpatialReference? value, JsonS writer.WriteEndObject(); } -} - -[ProtoContract(Name = "SpatialReference")] -internal record SpatialReferenceSerializationRecord : MapComponentSerializationRecord -{ - public SpatialReferenceSerializationRecord() - { - } - - public SpatialReferenceSerializationRecord(int? Wkid, string? Wkt = null) - { - this.Wkid = Wkid; - this.Wkt = Wkt; - } - - public SpatialReference FromSerializationRecord() - { - return new SpatialReference(Wkid ?? 4326); - } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(1)] - public int? Wkid { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public string? Wkt { get; init; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/FillSymbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/FillSymbol.cs index 72c83db7c..124526f0b 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/FillSymbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/FillSymbol.cs @@ -1,8 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; +[ProtobufSerializable] public abstract partial class FillSymbol : Symbol { - /// /// The outline of the polygon. /// ArcGIS Maps SDK for JavaScript diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/LineSymbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/LineSymbol.cs index eab783068..a6c3b3b3c 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/LineSymbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/LineSymbol.cs @@ -1,5 +1,6 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; +[ProtobufSerializable] public abstract partial class LineSymbol : Symbol { /// diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/MarkerSymbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/MarkerSymbol.cs index fd682f331..0af98a312 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/MarkerSymbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/MarkerSymbol.cs @@ -1,6 +1,7 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; [JsonConverter(typeof(MarkerSymbolJsonConverter))] +[ProtobufSerializable] public abstract partial class MarkerSymbol : Symbol { /// diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/Outline.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/Outline.cs index baacd31be..7a6b3eab1 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/Outline.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/Outline.cs @@ -3,6 +3,7 @@ /// /// A convenience subclass of for defining outlines of other symbols. /// +[ProtobufSerializable] public class Outline : SimpleLineSymbol { /// diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/PictureFillSymbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/PictureFillSymbol.cs index 28b094da8..5d074504a 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/PictureFillSymbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/PictureFillSymbol.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; +[ProtobufSerializable] public partial class PictureFillSymbol : FillSymbol { - - /// /// The height of the image in points. /// @@ -52,7 +51,8 @@ public partial class PictureFillSymbol : FillSymbol [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public Dimension? Yoffset { get; set; } - internal override SymbolSerializationRecord ToSerializationRecord() + /// + public override SymbolSerializationRecord ToProtobuf() { return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), null) { @@ -63,7 +63,7 @@ internal override SymbolSerializationRecord ToSerializationRecord() Yoffset = Yoffset?.Points, XScale = XScale, YScale = YScale, - Outline = Outline?.ToSerializationRecord() + Outline = Outline?.ToProtobuf() }; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/PictureMarkerSymbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/PictureMarkerSymbol.cs index 11ee159c2..ae0f08b77 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/PictureMarkerSymbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/PictureMarkerSymbol.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; +[ProtobufSerializable] public partial class PictureMarkerSymbol : MarkerSymbol { - - /// /// The height of the image in points. /// @@ -22,7 +21,8 @@ public partial class PictureMarkerSymbol : MarkerSymbol public override SymbolType Type => SymbolType.PictureMarker; - internal override SymbolSerializationRecord ToSerializationRecord() + /// + public override SymbolSerializationRecord ToProtobuf() { return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), null) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleFillSymbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleFillSymbol.cs index 8b6508520..61facfce8 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleFillSymbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleFillSymbol.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; +[ProtobufSerializable] public partial class SimpleFillSymbol : FillSymbol { - - /// /// The fill style. /// @@ -56,11 +55,12 @@ public override void ValidateRequiredChildren() Outline?.ValidateRequiredChildren(); } - internal override SymbolSerializationRecord ToSerializationRecord() + /// + public override SymbolSerializationRecord ToProtobuf() { - return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), Color) + return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), Color?.ToProtobuf()) { - Outline = Outline?.ToSerializationRecord(), + Outline = Outline?.ToProtobuf(), Style = Style?.ToString().ToKebabCase() }; } diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleLineSymbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleLineSymbol.cs index 0e4a65aa0..746144e69 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleLineSymbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleLineSymbol.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; +[ProtobufSerializable] public partial class SimpleLineSymbol : LineSymbol { - - /// public override SymbolType Type => SymbolType.SimpleLine; @@ -53,9 +52,10 @@ public partial class SimpleLineSymbol : LineSymbol [Parameter] public SimpleLineSymbolStyle? Style { get; set; } - internal override SymbolSerializationRecord ToSerializationRecord() + /// + public override SymbolSerializationRecord ToProtobuf() { - return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), Color) + return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), Color?.ToProtobuf()) { Width = Width?.Points, Style = Style?.ToString().ToKebabCase() diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleMarkerSymbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleMarkerSymbol.cs index 51599fc86..8c519bf0b 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleMarkerSymbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/SimpleMarkerSymbol.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; +[ProtobufSerializable] public partial class SimpleMarkerSymbol : MarkerSymbol { - - /// /// The size of the marker in points. This value may be autocast with a string expressing size in points or pixels (e.g. 12px). /// @@ -21,11 +20,12 @@ public partial class SimpleMarkerSymbol : MarkerSymbol [Parameter] public SimpleMarkerSymbolStyle? Style { get; set; } - internal override SymbolSerializationRecord ToSerializationRecord() + /// + public override SymbolSerializationRecord ToProtobuf() { - return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), Color) + return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), Color?.ToProtobuf()) { - Outline = Outline?.ToSerializationRecord(), + Outline = Outline?.ToProtobuf(), Size = Size?.Points, Style = Style?.ToString().ToKebabCase(), Angle = Angle, diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/Symbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/Symbol.cs index 3f4048109..6fff0db19 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/Symbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/Symbol.cs @@ -1,7 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; [JsonConverter(typeof(SymbolJsonConverter))] -public abstract partial class Symbol : MapComponent +[ProtobufSerializable] +public abstract partial class Symbol : MapComponent, IProtobufSerializable { /// /// The color of the symbol. @@ -16,181 +17,6 @@ public abstract partial class Symbol : MapComponent /// public abstract SymbolType Type { get; } - internal abstract SymbolSerializationRecord ToSerializationRecord(); -} - -[ProtoContract(Name = "Symbol")] -internal record SymbolSerializationRecord : MapComponentSerializationRecord -{ - public SymbolSerializationRecord() - { - } - - public SymbolSerializationRecord(string Id, - string Type, - MapColor? Color) - { - this.Id = Id; - this.Type = Type; - this.Color = Color; - } - - [ProtoMember(1)] - public string Type { get; init; } = string.Empty; - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public MapColor? Color { get; init; } - - [ProtoMember(3)] - public SymbolSerializationRecord? Outline { get; init; } - - [ProtoMember(4)] - public double? Size { get; init; } - - [ProtoMember(5)] - public string? Style { get; init; } - - [ProtoMember(6)] - public double? Angle { get; init; } - - [ProtoMember(7)] - public double? Xoffset { get; init; } - - [ProtoMember(8)] - public double? Yoffset { get; init; } - - [ProtoMember(9)] - public double? Width { get; init; } - - [ProtoMember(10)] - public string? LineStyle { get; init; } - - [ProtoMember(11)] - public string? Text { get; init; } - - [ProtoMember(12)] - public MapColor? HaloColor { get; init; } - - [ProtoMember(13)] - public double? HaloSize { get; init; } - - [ProtoMember(14)] - public MapFontSerializationRecord? Font { get; init; } - - [ProtoMember(15)] - public double? Height { get; init; } - - [ProtoMember(16)] - public string? Url { get; init; } - - [ProtoMember(17)] - public MapColor? BackgroundColor { get; init; } - - [ProtoMember(18)] - public double? BorderLineSize { get; init; } - - [ProtoMember(19)] - public MapColor? BorderLineColor { get; init; } - - [ProtoMember(20)] - public string? HorizontalAlignment { get; init; } - - [ProtoMember(21)] - public bool? Kerning { get; init; } - - [ProtoMember(22)] - public double? LineHeight { get; init; } - - [ProtoMember(23)] - public double? LineWidth { get; init; } - - [ProtoMember(24)] - public bool? Rotated { get; init; } - - [ProtoMember(25)] - public string? VerticalAlignment { get; init; } - - [ProtoMember(26)] - public double? XScale { get; init; } - - [ProtoMember(27)] - public double? YScale { get; init; } - - [ProtoMember(28)] - public string? Id { get; init; } - - [ProtoMember(29)] - public string? Name { get; init; } - - [ProtoMember(30)] - public string? PortalUrl { get; init; } - - [ProtoMember(31)] - public string? StyleName { get; init; } - - [ProtoMember(32)] - public string? StyleUrl { get; init; } - - public Symbol FromSerializationRecord(bool isOutline = false) - { - Guid id = Guid.NewGuid(); - if (Guid.TryParse(Id, out Guid guidId)) - { - id = guidId; - } - - if (Type == "web-style") - { - // WebStyleSymbol is in GeoBlazor Pro assembly, so we need to use reflection to get the type - Type? webStyleSymbolType = System.Type - .GetType("dymaptic.GeoBlazor.Pro.Components.Symbols.WebStyleSymbol, dymaptic.GeoBlazor.Pro"); - - if (webStyleSymbolType is not null) - { - Portal? portal = PortalUrl is null ? null : new Portal(url: PortalUrl); - Symbol webStyleSymbol = Activator.CreateInstance(webStyleSymbolType, Color, Name, portal, StyleName, StyleUrl) as Symbol - ?? throw new InvalidOperationException("Failed to create WebStyleSymbol instance."); - webStyleSymbol.Id = id; - return webStyleSymbol; - } - } - - return Type switch - { - "outline" => new Outline(Color, Width, - LineStyle is null ? null : Enum.Parse(LineStyle!, true)) - { - Id = id - }, - "simple-marker" => new SimpleMarkerSymbol(Outline?.FromSerializationRecord(true) as Outline, Color, Size, - Style is null ? null : Enum.Parse(Style!, true), Angle, Xoffset, Yoffset) - { - Id = id - }, - "simple-line" => isOutline - ? new Outline(Color, Width, - LineStyle is null ? null : Enum.Parse(LineStyle!, true)) - { - Id = id - } - : new SimpleLineSymbol(Color, Width, - LineStyle is null ? null : Enum.Parse(LineStyle!, true)) - { - Id = id - }, - "simple-fill" => new SimpleFillSymbol(Outline?.FromSerializationRecord(true) as Outline, Color, - Style is null ? null : Enum.Parse(Style!, true)) { Id = id }, - "picture-marker" => new PictureMarkerSymbol(Url!, Width, Height, Angle, Xoffset, Yoffset) { Id = id }, - "picture-fill" => new PictureFillSymbol(Url!, Width, Height, Xoffset, Yoffset, XScale, YScale, - Outline?.FromSerializationRecord(true) as Outline) { Id = id }, - "text" => new TextSymbol(Text ?? string.Empty, Color, HaloColor, HaloSize, - Font?.FromSerializationRecord(), Angle, BackgroundColor, BorderLineColor, - BorderLineSize, HorizontalAlignment is null ? null : Enum.Parse(HorizontalAlignment!, true), - Kerning, LineHeight, LineWidth, Rotated, - VerticalAlignment is null ? null : Enum.Parse(VerticalAlignment!, true), - Xoffset, Yoffset) { Id = id }, - _ => throw new ArgumentException($"Unknown symbol type: {Type}") - }; - } + /// + public abstract SymbolSerializationRecord ToProtobuf(); } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Components/Symbols/TextSymbol.cs b/src/dymaptic.GeoBlazor.Core/Components/Symbols/TextSymbol.cs index d510fe724..90d1e037d 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Symbols/TextSymbol.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Symbols/TextSymbol.cs @@ -1,9 +1,8 @@ namespace dymaptic.GeoBlazor.Core.Components.Symbols; +[ProtobufSerializable] public partial class TextSymbol : Symbol { - - /// public override SymbolType Type => SymbolType.Text; @@ -153,19 +152,19 @@ public partial class TextSymbol : Symbol [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public Dimension? Yoffset { get; set; } - - internal override SymbolSerializationRecord ToSerializationRecord() + /// + public override SymbolSerializationRecord ToProtobuf() { - return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), Color) + return new SymbolSerializationRecord(Id.ToString(), Type.ToString().ToKebabCase(), Color?.ToProtobuf()) { Text = Text, - HaloColor = HaloColor, + HaloColor = HaloColor?.ToProtobuf(), HaloSize = HaloSize?.Points, - Font = Font?.ToSerializationRecord(), + Font = Font?.ToProtobuf(), Angle = Angle, - BackgroundColor = BackgroundColor, + BackgroundColor = BackgroundColor?.ToProtobuf(), BorderLineSize = BorderLineSize, - BorderLineColor = BorderLineColor, + BorderLineColor = BorderLineColor?.ToProtobuf(), HorizontalAlignment = HorizontalAlignment?.ToString().ToKebabCase(), Kerning = Kerning, LineHeight = LineHeight, diff --git a/src/dymaptic.GeoBlazor.Core/Components/UniqueValueInfo.cs b/src/dymaptic.GeoBlazor.Core/Components/UniqueValueInfo.cs index ecd452abb..cc0fe46d2 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/UniqueValueInfo.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/UniqueValueInfo.cs @@ -35,7 +35,7 @@ public virtual async Task SetSymbol(Symbol symbol) Symbol = symbol; if (CoreJsModule is not null) { - await CoreJsModule.InvokeVoidAsync("setGraphicSymbol", Id, Symbol.ToSerializationRecord()); + await CoreJsModule.InvokeVoidAsync("setGraphicSymbol", Id, Symbol.ToProtobuf()); } } diff --git a/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor b/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor index 8871e8cb9..d771a8b9c 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor +++ b/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor @@ -6,7 +6,7 @@
@if (MapComponentType == typeof(SceneView)) { - + @if (!string.IsNullOrWhiteSpace(ErrorMessage)) {
@@ -18,7 +18,7 @@ } else { - + @if (!string.IsNullOrWhiteSpace(ErrorMessage)) {
diff --git a/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor.cs b/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor.cs index 8d1b63b3c..92da19702 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor.cs @@ -153,6 +153,9 @@ public Point? Center [Parameter] public bool ExcludeApiKey { get; set; } + [Parameter(CaptureUnmatchedValues = true)] + public Dictionary? UnMatchedAttributes { get; set; } + #endregion @@ -190,21 +193,6 @@ public IReadOnlyCollection Graphics [RequiredProperty] public Map? Map { get; private set; } - /// - /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode - /// - public bool IsServer => JsRuntime!.GetType().Name.Contains("Remote"); - - /// - /// Boolean flag to identify if GeoBlazor is running in Blazor WebAssembly (client) mode - /// - public bool IsWebAssembly => OperatingSystem.IsBrowser(); - - /// - /// Boolean flag to identify if GeoBlazor is running in Blazor Hybrid (MAUI) mode - /// - public bool IsMaui => JsRuntime!.GetType().Name.Contains("WebView"); - /// /// A boolean flag to indicate that the map extent has been modified in JavaScript, and therefore should not be modifiable by markup until is called /// @@ -1232,6 +1220,7 @@ public void Load() public async Task QueryFeatures(Query query, FeatureLayer featureLayer, Symbol displaySymbol, PopupTemplate popupTemplate) { + // TODO: V5 - Remove in favor of FeatureLayer.QueryFeatures await CoreJsModule!.InvokeVoidAsync("queryFeatureLayer", CancellationTokenSource.Token, (object)query, (object)featureLayer, (object)displaySymbol, (object)popupTemplate, Id); @@ -1251,6 +1240,7 @@ public async Task QueryFeatures(Query query, FeatureLayer featureLayer, Symbol d /// public async Task FindPlaces(AddressQuery query, Symbol displaySymbol, PopupTemplate popupTemplate) { + // TODO: V5 - remove in favor of LocationService await CoreJsModule!.InvokeVoidAsync("findPlaces", CancellationTokenSource.Token, (object)query, (object)displaySymbol, (object)popupTemplate, Id); } @@ -1337,8 +1327,8 @@ public async Task AddGraphics(IEnumerable graphics, CancellationToken c return; } - ProtoGraphicCollection collection = - new(newGraphics.Skip(skip).Take(chunkSize).Select(g => g.ToSerializationRecord(true)).ToArray()); + GraphicCollectionSerializationRecord collection = + new(newGraphics.Skip(skip).Take(chunkSize).Select(g => g.ToProtobuf()).ToArray()); MemoryStream ms = new(); Serializer.Serialize(ms, collection); @@ -1370,8 +1360,8 @@ public async Task AddGraphics(IEnumerable graphics, CancellationToken c return; } - ProtoGraphicCollection collection = new(newGraphics.Skip(skip).Take(chunkSize) - .Select(g => g.ToSerializationRecord(true)).ToArray()); + GraphicCollectionSerializationRecord collection = new(newGraphics.Skip(skip).Take(chunkSize) + .Select(g => g.ToProtobuf()).ToArray()); MemoryStream ms = new(); Serializer.Serialize(ms, collection); @@ -1406,8 +1396,8 @@ await CoreJsModule.InvokeVoidAsync("addGraphicsFromStream", cancellationToken, return; } - ProtoGraphicCollection collection = new(newGraphics.Skip(skip).Take(chunkSize) - .Select(g => g.ToSerializationRecord(true)).ToArray()); + GraphicCollectionSerializationRecord collection = new(newGraphics.Skip(skip).Take(chunkSize) + .Select(g => g.ToProtobuf()).ToArray()); MemoryStream ms = new(); Serializer.Serialize(ms, collection); @@ -1449,7 +1439,7 @@ public async Task AddGraphic(Graphic graphic) if (CoreJsModule is null) return; - ProtoGraphicCollection collection = new([graphic.ToSerializationRecord(true)]); + GraphicCollectionSerializationRecord collection = new([graphic.ToProtobuf()]); MemoryStream ms = new(); Serializer.Serialize(ms, collection); ms.Seek(0, SeekOrigin.Begin); @@ -1470,6 +1460,11 @@ public async Task ClearGraphics() _graphics.Clear(); if (CoreJsModule is not null) { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule!.InvokeVoidAsync("clearGraphics", CancellationTokenSource.Token, Id); } @@ -1570,6 +1565,12 @@ public async Task RemoveLayer(Layer layer, bool isBasemapLayer = false, bool isR } if (CoreJsModule is null || !removed) return; + + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule.InvokeVoidAsync("removeLayer", CancellationTokenSource.Token, layer.Id, Id, isBasemapLayer, isReferenceLayer); @@ -1589,6 +1590,11 @@ await CoreJsModule.InvokeVoidAsync("removeLayer", CancellationTokenSource.Token, /// public async Task SolveServiceArea(string serviceAreaUrl, double[] driveTimeCutOffs, Symbol serviceAreaSymbol) { + // TODO: V5 - Move to a separate service, expose CancellationToken to end user + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule!.InvokeVoidAsync("solveServiceArea", CancellationTokenSource.Token, serviceAreaUrl, driveTimeCutOffs, serviceAreaSymbol, Id); } @@ -1604,6 +1610,11 @@ public async Task RemoveGraphic(Graphic graphic) _graphics.Remove(graphic); if (CoreJsModule is null) return; + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule.InvokeVoidAsync("removeGraphic", CancellationTokenSource.Token, graphic.Id, Id); @@ -1630,6 +1641,11 @@ public async Task RemoveGraphics(IEnumerable graphics) } if (CoreJsModule is null) return; + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule.InvokeVoidAsync("removeGraphics", CancellationTokenSource.Token, oldGraphics.Select(g => g.Id), Id); @@ -1649,6 +1665,11 @@ public virtual async Task SetCenter(Point point) Longitude = point.Longitude; if (CoreJsModule is null || !MapRendered) return; + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } ViewExtentUpdate change = await CoreJsModule.InvokeAsync("setCenter", @@ -1671,6 +1692,11 @@ public async Task SetBackgroundColor(MapColor backgroundColor) { return; } + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule.InvokeVoidAsync("setBackgroundColor", CancellationTokenSource.Token, Id, backgroundColor); } @@ -1684,6 +1710,11 @@ public async Task SetBackgroundColor(MapColor backgroundColor) if (CoreJsModule is not null && MapRendered) { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } center = await CoreJsModule.InvokeAsync("getCenter", CancellationTokenSource.Token, Id); if (center is not null) @@ -1711,6 +1742,11 @@ public virtual async Task SetZoom(double zoom) { ShouldUpdate = false; ExtentSetByCode = true; + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } ViewExtentUpdate change = await CoreJsModule.InvokeAsync("setZoom", CancellationTokenSource.Token, Zoom, Id); @@ -1730,6 +1766,11 @@ public virtual async Task SetZoom(double zoom) { if (CoreJsModule is not null) { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } Zoom = await CoreJsModule.InvokeAsync("getZoom", CancellationTokenSource.Token, Id); } @@ -1747,6 +1788,11 @@ public virtual async Task SetScale(double scale) { ShouldUpdate = false; ExtentSetByCode = true; + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } ViewExtentUpdate change = await CoreJsModule.InvokeAsync("setScale", @@ -1767,6 +1813,11 @@ await CoreJsModule.InvokeAsync("setScale", { if (CoreJsModule is not null) { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } Scale = await CoreJsModule.InvokeAsync("getScale", CancellationTokenSource.Token, Id); } @@ -1784,6 +1835,11 @@ public async Task SetRotation(double rotation) { ShouldUpdate = false; ExtentSetByCode = true; + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } ViewExtentUpdate change = await CoreJsModule.InvokeAsync("setRotation", @@ -1804,6 +1860,11 @@ await CoreJsModule.InvokeAsync("setRotation", { if (CoreJsModule is not null) { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } Rotation = await CoreJsModule.InvokeAsync("getRotation", CancellationTokenSource.Token, Id); } @@ -1823,6 +1884,11 @@ public virtual async Task SetExtent(Extent extent) ShouldUpdate = false; ExtentSetByCode = true; + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } ViewExtentUpdate change = await CoreJsModule.InvokeAsync("setExtent", @@ -1843,6 +1909,11 @@ await CoreJsModule.InvokeAsync("setExtent", { if (CoreJsModule is not null) { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } Extent = await CoreJsModule.InvokeAsync("getExtent", CancellationTokenSource.Token, Id); } @@ -1860,6 +1931,11 @@ public async Task SetConstraints(Constraints constraints) if (CoreJsModule is null) return; + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule.InvokeVoidAsync("setConstraints", CancellationTokenSource.Token, (object)Constraints, Id); } @@ -1872,12 +1948,18 @@ await CoreJsModule.InvokeVoidAsync("setConstraints", ///
public async Task SetHighlightOptions(HighlightOptions highlightOptions) { + // TODO: V5 - Replace with IReadOnlyCollection Highlights if (!highlightOptions.Equals(HighlightOptions)) { HighlightOptions = highlightOptions; if (CoreJsModule is null) return; + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule.InvokeVoidAsync("setHighlightOptions", CancellationTokenSource.Token, (object)HighlightOptions, Id); } @@ -1895,6 +1977,12 @@ public async Task SetSpatialReference(SpatialReference spatialReference) SpatialReference = spatialReference; if (CoreJsModule is null) return; + + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule.InvokeVoidAsync("setSpatialReference", CancellationTokenSource.Token, (object)SpatialReference, Id); @@ -1910,6 +1998,11 @@ await CoreJsModule.InvokeVoidAsync("setSpatialReference", { if (CoreJsModule is not null) { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } SpatialReference = await CoreJsModule.InvokeAsync("getSpatialReference", CancellationTokenSource.Token, Id); } @@ -1937,6 +2030,12 @@ public async Task GoTo(Extent extent) ShouldUpdate = false; ExtentSetByCode = true; + + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } ViewExtentUpdate change = await CoreJsModule.InvokeAsync("goToExtent", @@ -1962,6 +2061,12 @@ public virtual async Task GoTo(IEnumerable graphics) ShouldUpdate = false; ExtentSetByCode = true; + + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } ViewExtentUpdate change = await CoreJsModule.InvokeAsync("goToGraphics", @@ -1997,7 +2102,7 @@ public async Task HitTest(ClickEvent clickEvent) /// public async Task HitTest(ClickEvent clickEvent, HitTestOptions? options) { - return await HitTestImplementation(new ScreenPoint(clickEvent.X, clickEvent.Y), options); + return await HitTest(new ScreenPoint(clickEvent.X, clickEvent.Y), options); } /// @@ -2022,7 +2127,7 @@ public async Task HitTest(PointerEvent pointerEvent) /// public async Task HitTest(PointerEvent pointerEvent, HitTestOptions? options) { - return await HitTestImplementation(new ScreenPoint(pointerEvent.X, pointerEvent.Y), options); + return await HitTest(new ScreenPoint(pointerEvent.X, pointerEvent.Y), options); } /// @@ -2047,7 +2152,14 @@ public async Task HitTest(ScreenPoint screenPoint) /// public async Task HitTest(ScreenPoint screenPoint, HitTestOptions? options) { - return await HitTestImplementation(screenPoint, options); + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } + return await JsSyncManager.InvokeJsMethod(JsComponentReference!, IsServer, + className: nameof(MapView), cancellationToken: CancellationTokenSource.Token, + parameters: [screenPoint, Id, options]); } /// @@ -2073,7 +2185,7 @@ public async Task HitTest(Point mapPoint) public async Task HitTest(Point mapPoint, HitTestOptions? options) { ScreenPoint screenPoint = await ToScreen(mapPoint); - return await HitTestImplementation(screenPoint, options); + return await HitTest(screenPoint, options); } /// @@ -2081,6 +2193,12 @@ public async Task HitTest(Point mapPoint, HitTestOptions? options /// public async Task ToMap(ScreenPoint screenPoint) { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } + return await CoreJsModule!.InvokeAsync("toMap", CancellationTokenSource.Token, screenPoint, Id); } @@ -2090,6 +2208,12 @@ public async Task ToMap(ScreenPoint screenPoint) /// public async Task ToScreen(Point mapPoint) { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } + return await CoreJsModule!.InvokeAsync("toScreen", CancellationTokenSource.Token, mapPoint, Id); } @@ -2099,6 +2223,11 @@ public async Task ToScreen(Point mapPoint) /// public async Task GetCursor() { + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } + return await CoreJsModule!.InvokeAsync("getCursor", CancellationTokenSource.Token, Id); } @@ -2108,6 +2237,11 @@ public async Task GetCursor() /// public async Task SetCursor(string cursor) { + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } + await CoreJsModule!.InvokeVoidAsync("setCursor", CancellationTokenSource.Token, cursor, Id); } @@ -2173,6 +2307,11 @@ await InvokeAsync(async () => { try { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } await CoreJsModule.InvokeVoidAsync("removeWidget", CancellationTokenSource.Token, widget.Id, Id); } @@ -2196,6 +2335,12 @@ public async Task TakeScreenshot(ScreenshotOptions? options = null) { try { + // TODO: V5 - Expose Cancellation Token option to end users + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } + JsScreenshot jsScreenshot = await CoreJsModule!.InvokeAsync("takeScreenshot", CancellationTokenSource.Token, Id, options); Stream mapStream = await jsScreenshot.Stream.OpenReadStreamAsync(1_000_000_000L); @@ -2322,7 +2467,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { await AuthenticationManager.Login(); } - + // we load CSS programmatically to avoid issues with devs adding or forgetting to add the links // so we can check and ensure at runtime, especially since we are changing the behavior in version 4.2.0 if (HasCustomAssetPath()) @@ -2372,6 +2517,11 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (_newWidgets.Any()) { + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } + Widget[] newWidgets = _newWidgets.ToArray(); _newWidgets.Clear(); foreach (Widget newWidget in newWidgets) @@ -2479,7 +2629,9 @@ protected virtual async Task BuildMapView() string mapType = Map is WebMap ? "webmap" : "map"; IJSObjectReference abortSignal = await AbortManager!.CreateAbortSignal(CancellationTokenSource.Token); CancellationTokenSource.CancelAfter(MapRenderTimeoutInMilliseconds); // timeout for the map view to be built - await CoreJsModule!.InvokeVoidAsync("buildMapView", CancellationTokenSource.Token, abortSignal, Id, + + JsComponentReference = await CoreJsModule!.InvokeAsync("buildMapView", + CancellationTokenSource.Token, abortSignal, Id, DotNetComponentReference, Longitude, Latitude, Rotation, Map, Zoom, Scale, mapType, Widgets, Graphics, SpatialReference, Constraints, Extent, BackgroundColor, EventRateLimitInMilliseconds, GetActiveEventHandlers(), IsServer, HighlightOptions, PopupEnabled, @@ -2578,6 +2730,11 @@ protected virtual async Task UpdateView() } ShouldUpdate = false; + + if (CancellationTokenSource.Token.IsCancellationRequested) + { + CancellationTokenSource = new CancellationTokenSource(); + } ViewExtentUpdate? change = await CoreJsModule!.InvokeAsync("updateView", CancellationTokenSource.Token, @@ -2713,45 +2870,6 @@ public override void ValidateRequiredChildren() widget.ValidateRequiredChildren(); } } - - private async Task HitTestImplementation(ScreenPoint screenPoint, HitTestOptions? options) - { - Guid hitTestId = Guid.NewGuid(); - HitTestResult result = await CoreJsModule!.InvokeAsync("hitTest", - CancellationTokenSource.Token, screenPoint, Id, options, hitTestId); - - if (_activeHitTests.TryGetValue(hitTestId, out ViewHit[]? viewHits)) - { - result.Results = viewHits; - } - - return result; - } - - /// - /// Internal use callback from JavaScript - /// - [JSInvokable] - public async Task OnHitTestStreamCallback(IJSStreamReference streamReference, Guid hitTestId) - { - if (IsDisposed) return; - try - { - await using Stream stream = await streamReference - .OpenReadStreamAsync(QueryResultsMaxSizeLimit); - using var ms = new MemoryStream(); - await stream.CopyToAsync(ms); - ms.Seek(0, SeekOrigin.Begin); - ProtoViewHitCollection collection = Serializer.Deserialize(ms); - ViewHit[] viewHits = collection.ViewHits!.Select(g => g.FromSerializationRecord()).ToArray(); - - _activeHitTests[hitTestId] = viewHits; - } - catch (Exception ex) - { - throw new SerializationException("Error deserializing graphics from stream.", ex); - } - } private bool IsPro() { @@ -2886,7 +3004,6 @@ protected List GetActiveEventHandlers() private bool? _isPro; private bool? _hasCustomAssetPath; private string? _customAssetsPath; - private readonly Dictionary _activeHitTests = new(); private bool _waitingForRender; private ArcGISTheme? _lastTheme; diff --git a/src/dymaptic.GeoBlazor.Core/Components/Views/SceneView.cs b/src/dymaptic.GeoBlazor.Core/Components/Views/SceneView.cs index 8e5e076ba..8604c2bea 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Views/SceneView.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Views/SceneView.cs @@ -188,7 +188,7 @@ protected override async Task BuildMapView() IJSObjectReference abortSignal = await AbortManager!.CreateAbortSignal(CancellationTokenSource.Token); CancellationTokenSource.CancelAfter(MapRenderTimeoutInMilliseconds); // timeout for the map view to be built - await CoreJsModule!.InvokeVoidAsync("buildMapView", + JsComponentReference = await CoreJsModule!.InvokeAsync("buildMapView", CancellationTokenSource.Token, abortSignal, Id, DotNetComponentReference, Longitude, Latitude, Rotation, Map, Zoom, Scale, mapType, Widgets, Graphics, SpatialReference, Constraints, Extent, BackgroundColor, diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/BasemapLayerListWidget.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/BasemapLayerListWidget.cs index eb3081a33..0fadb790f 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/BasemapLayerListWidget.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/BasemapLayerListWidget.cs @@ -279,7 +279,7 @@ public BasemapLayerListWidget( public async Task OnJsTriggerAction(IJSStreamReference jsStreamRef) { BasemapLayerListTriggerActionEvent? triggerActionEvent = - await jsStreamRef.ReadJsStreamReference(); + await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (triggerActionEvent is null) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/BookmarksWidget.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/BookmarksWidget.cs index c344d7deb..44e6254a7 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/BookmarksWidget.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/BookmarksWidget.cs @@ -45,7 +45,7 @@ public partial class BookmarksWidget : Widget [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); @@ -66,7 +66,7 @@ public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) public async Task OnJsBookmarkSelect(IJSStreamReference jsStreamRef) { View!.ExtentChangedInJs = true; - BookmarkSelectEvent? bookmarkSelectEvent = await jsStreamRef.ReadJsStreamReference(); + BookmarkSelectEvent? bookmarkSelectEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (bookmarkSelectEvent is not null) { await OnBookmarkSelect.InvokeAsync(bookmarkSelectEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/BookmarksWidget.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/BookmarksWidget.gb.cs index 1fe31fa87..1a4237da6 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/BookmarksWidget.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/BookmarksWidget.gb.cs @@ -1119,7 +1119,7 @@ public async Task OnJsBookmarkEdit(IJSStreamReference jsStreamRef) return; } - BookmarksBookmarkEditEvent? bookmarkEditEvent = await jsStreamRef.ReadJsStreamReference(); + BookmarksBookmarkEditEvent? bookmarkEditEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (bookmarkEditEvent is not null) { await OnBookmarkEdit.InvokeAsync(bookmarkEditEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/CompassWidget.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/CompassWidget.cs index 8687ede21..2d2c56e92 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/CompassWidget.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/CompassWidget.cs @@ -24,7 +24,7 @@ public partial class CompassWidget : Widget [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/HomeWidget.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/HomeWidget.cs index 529892940..d91d92ff0 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/HomeWidget.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/HomeWidget.cs @@ -25,7 +25,7 @@ public partial class HomeWidget : Widget [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); @@ -47,7 +47,7 @@ public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) public async Task OnJsGo(IJSStreamReference jsStreamRef) { View!.ExtentChangedInJs = true; - HomeGoEvent? goEvent = await jsStreamRef.ReadJsStreamReference(); + HomeGoEvent? goEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (goEvent is not null) { await OnGo.InvokeAsync(goEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/LayerListWidget.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/LayerListWidget.cs index 4115b68a5..e374cc67c 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/LayerListWidget.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/LayerListWidget.cs @@ -199,7 +199,7 @@ public LayerListWidget( public async Task OnJsTriggerAction(IJSStreamReference jsStreamRef) { LayerListTriggerActionEvent? triggerActionEvent = - await jsStreamRef.ReadJsStreamReference(); + await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (triggerActionEvent is null) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/LocateWidget.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/LocateWidget.cs index 1f2056ad0..c6e6f15ae 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/LocateWidget.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/LocateWidget.cs @@ -39,7 +39,7 @@ public partial class LocateWidget : Widget [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/LocateWidget.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/LocateWidget.gb.cs index db1fdc74b..768b7d070 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/LocateWidget.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/LocateWidget.gb.cs @@ -753,7 +753,7 @@ public async Task OnJsLocate(IJSStreamReference jsStreamRef) return; } - LocateEvent? locateEvent = await jsStreamRef.ReadJsStreamReference(); + LocateEvent? locateEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (locateEvent is not null) { await OnLocate.InvokeAsync(locateEvent); @@ -785,7 +785,7 @@ public async Task OnJsLocateError(IJSStreamReference jsStreamRef) return; } - LocateErrorEvent? locateErrorEvent = await jsStreamRef.ReadJsStreamReference(); + LocateErrorEvent? locateErrorEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (locateErrorEvent is not null) { await OnLocateError.InvokeAsync(locateErrorEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/PopupWidget.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/PopupWidget.cs index 45b370cee..e82352ecc 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/PopupWidget.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/PopupWidget.cs @@ -123,7 +123,7 @@ public partial class PopupWidget : Widget [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); @@ -163,7 +163,7 @@ public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) IJSStreamReference jsStreamRef = await JsComponentReference!.InvokeAsync( "getSelectedFeature", CancellationTokenSource.Token); - SelectedFeature = await jsStreamRef.ReadJsStreamReference(); + SelectedFeature = await jsStreamRef.ReadJsStreamReferenceAsJSON(); return SelectedFeature; } @@ -374,7 +374,7 @@ public async Task Close() public async Task OnJsTriggerAction(IJSStreamReference jsStreamRef) { PopupTriggerActionEvent? triggerActionEvent = - await jsStreamRef.ReadJsStreamReference(); + await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (triggerActionEvent is null || Actions is null) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/SearchWidget.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/SearchWidget.cs index 52f52fc21..7afc5326e 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/SearchWidget.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/SearchWidget.cs @@ -136,7 +136,7 @@ public partial class SearchWidget : Widget public async Task OnJsSearchComplete(IJSStreamReference jsStreamRef) { View!.ExtentChangedInJs = true; - SearchCompleteEvent? searchCompleteEvent = await jsStreamRef.ReadJsStreamReference(); + SearchCompleteEvent? searchCompleteEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (searchCompleteEvent is null) { @@ -183,7 +183,7 @@ public async Task OnJsSearchComplete(IJSStreamReference jsStreamRef) [CodeGenerationIgnore] public async Task OnJsSelectResult(IJSStreamReference jsStreamRef) { - SearchSelectResultEvent? selectResultEvent = await jsStreamRef.ReadJsStreamReference(); + SearchSelectResultEvent? selectResultEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (selectResultEvent is null) { @@ -229,7 +229,7 @@ public async Task OnJsSelectResult(IJSStreamReference jsStreamRef) public async Task OnJsSuggestComplete(IJSStreamReference jsStreamRef) { SearchSuggestCompleteEvent? suggestCompleteEvent = - await jsStreamRef.ReadJsStreamReference(); + await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (suggestCompleteEvent is null) { @@ -296,7 +296,7 @@ public async Task OnJsSuggestComplete(IJSStreamReference jsStreamRef) [CodeGenerationIgnore] public async Task OnJsGoToOverride(IJSStreamReference jsStreamRef) { - GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReference(); + GoToOverrideParameters? goToParameters = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (GoToOverride is not null && goToParameters is not null) { await GoToOverride.Invoke(goToParameters); @@ -372,7 +372,7 @@ private async Task SearchImplementation(object searchTerm) IJSStreamReference jsStreamRef = await JsComponentReference!.InvokeAsync("search", searchTerm); - return (await jsStreamRef.ReadJsStreamReference())!; + return (await jsStreamRef.ReadJsStreamReferenceAsJSON())!; } /// @@ -398,7 +398,7 @@ public async Task Suggest(string? value = null) IJSStreamReference jsStreamRef = await JsComponentReference!.InvokeAsync("suggest", value); - return (await jsStreamRef.ReadJsStreamReference())!; + return (await jsStreamRef.ReadJsStreamReferenceAsJSON())!; } /// @@ -430,7 +430,7 @@ public async Task Suggest(string? value = null) IJSStreamReference jsStreamRef = await JsComponentReference.InvokeAsync( "getActiveSource", CancellationTokenSource.Token); - SearchSource? result = await jsStreamRef.ReadJsStreamReference(); + SearchSource? result = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (result is not null) { @@ -472,7 +472,7 @@ public async Task Suggest(string? value = null) IJSStreamReference jsStreamRef = await JsComponentReference.InvokeAsync( "getAllSources", CancellationTokenSource.Token); - IReadOnlyList? result = await jsStreamRef.ReadJsStreamReference>(); + IReadOnlyList? result = await jsStreamRef.ReadJsStreamReferenceAsJSON>(); if (result is not null) { @@ -493,7 +493,7 @@ public async Task GetSelectedResult() { IJSStreamReference jsStreamRef = await JsComponentReference!.InvokeAsync("getSelectedResult"); - return (await jsStreamRef.ReadJsStreamReference())!; + return (await jsStreamRef.ReadJsStreamReferenceAsJSON())!; } /// @@ -524,7 +524,7 @@ public async Task GetSelectedResult() IJSStreamReference jsStreamRef = await JsComponentReference!.InvokeAsync("getSources", CancellationTokenSource.Token); - IReadOnlyList? result = await jsStreamRef.ReadJsStreamReference>(); + IReadOnlyList? result = await jsStreamRef.ReadJsStreamReferenceAsJSON>(); if (result is not null) { @@ -564,7 +564,7 @@ public async Task GetSelectedResult() IJSStreamReference jsStreamRef = await JsComponentReference!.InvokeAsync("getSources", CancellationTokenSource.Token); - IReadOnlyList? result = await jsStreamRef.ReadJsStreamReference>(); + IReadOnlyList? result = await jsStreamRef.ReadJsStreamReferenceAsJSON>(); if (result is not null) { diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/SearchWidget.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/SearchWidget.gb.cs index b62c6c4ce..e7582b206 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/SearchWidget.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/SearchWidget.gb.cs @@ -2072,7 +2072,7 @@ public async Task OnJsSearchBlur(IJSStreamReference jsStreamRef) return; } - SearchBlurEvent? searchBlurEvent = await jsStreamRef.ReadJsStreamReference(); + SearchBlurEvent? searchBlurEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (searchBlurEvent is not null) { await OnSearchBlur.InvokeAsync(searchBlurEvent); @@ -2104,7 +2104,7 @@ public async Task OnJsSearchClear(IJSStreamReference jsStreamRef) return; } - SearchClearEvent? searchClearEvent = await jsStreamRef.ReadJsStreamReference(); + SearchClearEvent? searchClearEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (searchClearEvent is not null) { await OnSearchClear.InvokeAsync(searchClearEvent); @@ -2136,7 +2136,7 @@ public async Task OnJsSearchFocus(IJSStreamReference jsStreamRef) return; } - SearchFocusEvent? searchFocusEvent = await jsStreamRef.ReadJsStreamReference(); + SearchFocusEvent? searchFocusEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (searchFocusEvent is not null) { await OnSearchFocus.InvokeAsync(searchFocusEvent); @@ -2168,7 +2168,7 @@ public async Task OnJsSearchStart(IJSStreamReference jsStreamRef) return; } - SearchStartEvent? searchStartEvent = await jsStreamRef.ReadJsStreamReference(); + SearchStartEvent? searchStartEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (searchStartEvent is not null) { await OnSearchStart.InvokeAsync(searchStartEvent); @@ -2200,7 +2200,7 @@ public async Task OnJsSuggestStart(IJSStreamReference jsStreamRef) return; } - SearchSuggestStartEvent? suggestStartEvent = await jsStreamRef.ReadJsStreamReference(); + SearchSuggestStartEvent? suggestStartEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (suggestStartEvent is not null) { await OnSuggestStart.InvokeAsync(suggestStartEvent); diff --git a/src/dymaptic.GeoBlazor.Core/Components/Widgets/SliderWidget.gb.cs b/src/dymaptic.GeoBlazor.Core/Components/Widgets/SliderWidget.gb.cs index 7f3d2461a..f3ecef028 100644 --- a/src/dymaptic.GeoBlazor.Core/Components/Widgets/SliderWidget.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Components/Widgets/SliderWidget.gb.cs @@ -2475,7 +2475,7 @@ public async Task OnJsMaxChange(IJSStreamReference jsStreamRef) return; } - SliderMaxChangeEvent? maxChangeEvent = await jsStreamRef.ReadJsStreamReference(); + SliderMaxChangeEvent? maxChangeEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (maxChangeEvent is not null) { await OnMaxChange.InvokeAsync(maxChangeEvent); @@ -2507,7 +2507,7 @@ public async Task OnJsMaxClick(IJSStreamReference jsStreamRef) return; } - SliderMaxClickEvent? maxClickEvent = await jsStreamRef.ReadJsStreamReference(); + SliderMaxClickEvent? maxClickEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (maxClickEvent is not null) { await OnMaxClick.InvokeAsync(maxClickEvent); @@ -2539,7 +2539,7 @@ public async Task OnJsMinChange(IJSStreamReference jsStreamRef) return; } - SliderMinChangeEvent? minChangeEvent = await jsStreamRef.ReadJsStreamReference(); + SliderMinChangeEvent? minChangeEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (minChangeEvent is not null) { await OnMinChange.InvokeAsync(minChangeEvent); @@ -2571,7 +2571,7 @@ public async Task OnJsMinClick(IJSStreamReference jsStreamRef) return; } - SliderMinClickEvent? minClickEvent = await jsStreamRef.ReadJsStreamReference(); + SliderMinClickEvent? minClickEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (minClickEvent is not null) { await OnMinClick.InvokeAsync(minClickEvent); @@ -2603,7 +2603,7 @@ public async Task OnJsSegmentClick(IJSStreamReference jsStreamRef) return; } - SliderSegmentClickEvent? segmentClickEvent = await jsStreamRef.ReadJsStreamReference(); + SliderSegmentClickEvent? segmentClickEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (segmentClickEvent is not null) { await OnSegmentClick.InvokeAsync(segmentClickEvent); @@ -2635,7 +2635,7 @@ public async Task OnJsSegmentDrag(IJSStreamReference jsStreamRef) return; } - SliderSegmentDragEvent? segmentDragEvent = await jsStreamRef.ReadJsStreamReference(); + SliderSegmentDragEvent? segmentDragEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (segmentDragEvent is not null) { await OnSegmentDrag.InvokeAsync(segmentDragEvent); @@ -2667,7 +2667,7 @@ public async Task OnJsThumbChange(IJSStreamReference jsStreamRef) return; } - SliderThumbChangeEvent? thumbChangeEvent = await jsStreamRef.ReadJsStreamReference(); + SliderThumbChangeEvent? thumbChangeEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (thumbChangeEvent is not null) { await OnThumbChange.InvokeAsync(thumbChangeEvent); @@ -2699,7 +2699,7 @@ public async Task OnJsThumbClick(IJSStreamReference jsStreamRef) return; } - SliderThumbClickEvent? thumbClickEvent = await jsStreamRef.ReadJsStreamReference(); + SliderThumbClickEvent? thumbClickEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (thumbClickEvent is not null) { await OnThumbClick.InvokeAsync(thumbClickEvent); @@ -2731,7 +2731,7 @@ public async Task OnJsThumbDrag(IJSStreamReference jsStreamRef) return; } - SliderThumbDragEvent? thumbDragEvent = await jsStreamRef.ReadJsStreamReference(); + SliderThumbDragEvent? thumbDragEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (thumbDragEvent is not null) { await OnThumbDrag.InvokeAsync(thumbDragEvent); @@ -2763,7 +2763,7 @@ public async Task OnJsTickClick(IJSStreamReference jsStreamRef) return; } - SliderTickClickEvent? tickClickEvent = await jsStreamRef.ReadJsStreamReference(); + SliderTickClickEvent? tickClickEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (tickClickEvent is not null) { await OnTickClick.InvokeAsync(tickClickEvent); @@ -2795,7 +2795,7 @@ public async Task OnJsTrackClick(IJSStreamReference jsStreamRef) return; } - SliderTrackClickEvent? trackClickEvent = await jsStreamRef.ReadJsStreamReference(); + SliderTrackClickEvent? trackClickEvent = await jsStreamRef.ReadJsStreamReferenceAsJSON(); if (trackClickEvent is not null) { await OnTrackClick.InvokeAsync(trackClickEvent); diff --git a/src/dymaptic.GeoBlazor.Core/DependencyExtension.cs b/src/dymaptic.GeoBlazor.Core/DependencyExtension.cs index bd33e8890..280167afb 100644 --- a/src/dymaptic.GeoBlazor.Core/DependencyExtension.cs +++ b/src/dymaptic.GeoBlazor.Core/DependencyExtension.cs @@ -13,14 +13,45 @@ public static IServiceCollection AddGeoBlazor(this IServiceCollection serviceCol { GeoBlazorSettings settings = configuration?.GetSection("GeoBlazor").Get() ?? new GeoBlazorSettings(); + + RegisterSerializationData(); return serviceCollection .AddSingleton(_ => settings) .AddScoped() - .AddScoped() - .AddScoped() - .AddScoped() .AddScoped() .AddScoped() + .AddCoreLogicComponents() .AddScoped(); } + + /// + /// Internal Call from Pro to Core DI + /// + internal static IServiceCollection AddGeoBlazorCoreFromPro(this IServiceCollection serviceCollection, + GeoBlazorSettings settings) + { + // don't add the app validator or register serialization data here + return serviceCollection + .AddSingleton(_ => settings) + .AddScoped() + .AddScoped() + .AddScoped() + .AddCoreLogicComponents(); + } + + private static void RegisterSerializationData() + { + JsSyncManager.SerializableMethods = CoreSerializationData.SerializableMethods; + JsSyncManager.ProtoContractTypes = CoreSerializationData.ProtoContractTypes; + JsSyncManager.ProtoCollectionTypes = CoreSerializationData.ProtoCollectionTypes; + JsSyncManager.Initialize(); + } + + private static IServiceCollection AddCoreLogicComponents(this IServiceCollection serviceCollection) + { + return serviceCollection + .AddScoped() + .AddScoped() + .AddScoped(); + } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Enums/Shading.cs b/src/dymaptic.GeoBlazor.Core/Enums/MeshShading.cs similarity index 88% rename from src/dymaptic.GeoBlazor.Core/Enums/Shading.cs rename to src/dymaptic.GeoBlazor.Core/Enums/MeshShading.cs index 880d9ed91..2a1c3d364 100644 --- a/src/dymaptic.GeoBlazor.Core/Enums/Shading.cs +++ b/src/dymaptic.GeoBlazor.Core/Enums/MeshShading.cs @@ -7,8 +7,8 @@ namespace dymaptic.GeoBlazor.Core.Enums; /// Specifies the type of normals used for lighting. /// ArcGIS Maps SDK for JavaScript /// -[JsonConverter(typeof(EnumToKebabCaseStringConverter))] -public enum Shading +[JsonConverter(typeof(EnumToKebabCaseStringConverter))] +public enum MeshShading { #pragma warning disable CS1591 Source, diff --git a/src/dymaptic.GeoBlazor.Core/Enums/Horizontal.cs b/src/dymaptic.GeoBlazor.Core/Enums/WrapMode.cs similarity index 74% rename from src/dymaptic.GeoBlazor.Core/Enums/Horizontal.cs rename to src/dymaptic.GeoBlazor.Core/Enums/WrapMode.cs index 35e093254..df43499e5 100644 --- a/src/dymaptic.GeoBlazor.Core/Enums/Horizontal.cs +++ b/src/dymaptic.GeoBlazor.Core/Enums/WrapMode.cs @@ -4,10 +4,11 @@ namespace dymaptic.GeoBlazor.Core.Enums; /// /// GeoBlazor Docs -/// Enumeration for Horizontal +/// Enumeration for Mesh Texture Wrap Modes. /// -[JsonConverter(typeof(EnumToKebabCaseStringConverter))] -public enum Horizontal +[JsonConverter(typeof(EnumToKebabCaseStringConverter))] +[CodeGenerationIgnore] +public enum WrapMode { #pragma warning disable CS1591 Clamp, diff --git a/src/dymaptic.GeoBlazor.Core/Interfaces/IInteractiveRecord.cs b/src/dymaptic.GeoBlazor.Core/Interfaces/IInteractiveRecord.cs index 755704294..70d645f5e 100644 --- a/src/dymaptic.GeoBlazor.Core/Interfaces/IInteractiveRecord.cs +++ b/src/dymaptic.GeoBlazor.Core/Interfaces/IInteractiveRecord.cs @@ -25,4 +25,6 @@ public interface IInteractiveRecord /// Reference to the Core JavaScript module. /// public IJSObjectReference? CoreJsModule { get; set; } + + public bool IsServer { get; set; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Interfaces/IMediaInfoValue.cs b/src/dymaptic.GeoBlazor.Core/Interfaces/IMediaInfoValue.cs new file mode 100644 index 000000000..06654b006 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Interfaces/IMediaInfoValue.cs @@ -0,0 +1,9 @@ +namespace dymaptic.GeoBlazor.Core.Interfaces; + +/// +/// Interface for and +/// +[ProtobufSerializable] +public interface IMediaInfoValue: IProtobufSerializable +{ +} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Model/AttributesDictionary.cs b/src/dymaptic.GeoBlazor.Core/Model/AttributesDictionary.cs index e97ad9e00..8d21cd83b 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/AttributesDictionary.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/AttributesDictionary.cs @@ -502,7 +502,7 @@ IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); } - internal AttributeSerializationRecord[] ToSerializationRecord() + public AttributeSerializationRecord[] ToProtobufArray() { return _backingDictionary .Select(kvp => @@ -526,6 +526,12 @@ internal AttributeSerializationRecord[] ToSerializationRecord() }) .ToArray(); } + + /// + public AttributeCollectionSerializationRecord ToProtobuf() + { + return new AttributeCollectionSerializationRecord(ToProtobufArray()); + } private readonly Dictionary _backingDictionary; @@ -538,30 +544,6 @@ internal AttributeSerializationRecord[] ToSerializationRecord() public object? this[string key] => _backingDictionary[key]; } -[ProtoContract(Name = "Attribute")] -internal record AttributeSerializationRecord : MapComponentSerializationRecord -{ - public AttributeSerializationRecord() - { - } - - public AttributeSerializationRecord(string Key, - string? Value, - string ValueType) - { - this.Key = Key; - this.Value = Value; - this.ValueType = ValueType; - } - - [ProtoMember(1)] - public string Key { get; init; } = string.Empty; - [ProtoMember(2)] - public string? Value { get; init; } - [ProtoMember(3)] - public string ValueType { get; init; } = string.Empty; -} - internal class AttributesDictionaryConverter : JsonConverter { public override AttributesDictionary? Read(ref Utf8JsonReader reader, Type typeToConvert, diff --git a/src/dymaptic.GeoBlazor.Core/Model/FieldsIndex.gb.cs b/src/dymaptic.GeoBlazor.Core/Model/FieldsIndex.gb.cs index fba8d0aa9..dcc9b7df2 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/FieldsIndex.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/FieldsIndex.gb.cs @@ -41,6 +41,11 @@ public partial record FieldsIndex( /// public IJSObjectReference? CoreJsModule { get; set; } + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode + /// + public bool IsServer { get; set; } + /// /// Cancellation Token for async methods. /// diff --git a/src/dymaptic.GeoBlazor.Core/Model/GraphicHit.cs b/src/dymaptic.GeoBlazor.Core/Model/GraphicHit.cs index b7de42024..2d5faa15d 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/GraphicHit.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/GraphicHit.cs @@ -16,5 +16,17 @@ namespace dymaptic.GeoBlazor.Core.Model; /// /// The point geometry in the spatial reference of the view corresponding with the input screen coordinates. /// -public record GraphicHit(Graphic Graphic, Guid? LayerId, Point MapPoint) : ViewHit("graphic", MapPoint); +/// +/// +[ProtobufSerializable] +[CodeGenerationIgnore] +public record GraphicHit(Graphic Graphic, Guid? LayerId, Point MapPoint, double? Distance = null) : ViewHit("graphic", MapPoint) +{ + /// + public override ViewHitSerializationRecord ToProtobuf() + { + return new ViewHitSerializationRecord(Type, MapPoint.ToProtobuf(), + Graphic.ToProtobuf(), LayerId?.ToString(), Distance); + } +} diff --git a/src/dymaptic.GeoBlazor.Core/Model/GraphicOrigin.cs b/src/dymaptic.GeoBlazor.Core/Model/GraphicOrigin.cs index 89f151ebc..f4c07de32 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/GraphicOrigin.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/GraphicOrigin.cs @@ -16,46 +16,16 @@ namespace dymaptic.GeoBlazor.Core.Model; /// ArcGIS Maps SDK for JavaScript /// [CodeGenerationIgnore] +[ProtobufSerializable] public record GraphicOrigin( Guid? LayerId = null, string? ArcGISLayerId = null, - int? LayerIndex = null) : VectorTileOrigin(LayerId, ArcGISLayerId, LayerIndex) + int? LayerIndex = null) : VectorTileOrigin(LayerId, ArcGISLayerId, LayerIndex), + IProtobufSerializable { - internal GraphicOriginSerializationRecord ToSerializationRecord() + /// + public GraphicOriginSerializationRecord ToProtobuf() { return new GraphicOriginSerializationRecord(LayerId?.ToString(), ArcGISLayerId, LayerIndex); } -} - -[ProtoContract(Name = "GraphicOrigin")] -internal record GraphicOriginSerializationRecord : MapComponentSerializationRecord -{ - public GraphicOriginSerializationRecord() - { - } - - public GraphicOriginSerializationRecord(string? LayerId, string? ArcGISLayerId, int? LayerIndex) - { - this.LayerId = LayerId; - this.ArcGISLayerId = ArcGISLayerId; - this.LayerIndex = LayerIndex; - } - - public GraphicOrigin FromSerializationRecord() - { - return new GraphicOrigin(LayerId is null ? null : Guid.Parse(LayerId), - ArcGISLayerId, LayerIndex); - } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(1)] - public string? LayerId { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(2)] - public string? ArcGISLayerId { get; init; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [ProtoMember(3)] - public int? LayerIndex { get; init; } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Model/Ground.gb.cs b/src/dymaptic.GeoBlazor.Core/Model/Ground.gb.cs index 34bbebae5..3f5c9576a 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/Ground.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/Ground.gb.cs @@ -55,6 +55,11 @@ public partial record Ground( ///
public IJSObjectReference? CoreJsModule { get; set; } + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode + /// + public bool IsServer { get; set; } + /// /// Cancellation Token for async methods. /// diff --git a/src/dymaptic.GeoBlazor.Core/Model/ImageData.cs b/src/dymaptic.GeoBlazor.Core/Model/ImageData.cs index e752a61ad..13aced7ea 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/ImageData.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/ImageData.cs @@ -16,7 +16,17 @@ namespace dymaptic.GeoBlazor.Core.Model; /// /// The width of the image. /// -public record ImageData(byte[] Data, string ColorSpace, long Height, long Width); +[ProtoContract] +[ProtobufSerializable] +public record ImageData(byte[] Data, string ColorSpace, long Height, long Width) + : IProtobufSerializable +{ + /// + public ImageDataSerializationRecord ToProtobuf() + { + return new ImageDataSerializationRecord(Data, ColorSpace, Height, Width); + } +} /// /// Internal representation of a screenshot, for passing from JavaScript. diff --git a/src/dymaptic.GeoBlazor.Core/Model/MapColor.cs b/src/dymaptic.GeoBlazor.Core/Model/MapColor.cs index 732b55069..ad3e7ddc9 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/MapColor.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/MapColor.cs @@ -7,9 +7,9 @@ namespace dymaptic.GeoBlazor.Core.Model; /// Creates a new color object by passing either a hex, rgb(a), hsl(a) or named color value. Hex, hsl(a) and named color values can be passed as a string: ArcGIS Maps SDK for JavaScript /// [JsonConverter(typeof(MapColorConverter))] -[ProtoContract] [CodeGenerationIgnore] -public class MapColor : IEquatable +[ProtobufSerializable] +public class MapColor : IEquatable, IProtobufSerializable { private double[]? _rgbaValues = []; private string? _hexOrNameValue; @@ -63,7 +63,6 @@ public MapColor(string hexOrNameValue) /// /// The numeric values for calculating a color (rgb/rgba). /// - [ProtoMember(1)] public double[]? RgbaValues { get => _rgbaValues; @@ -81,7 +80,6 @@ public double[]? RgbaValues /// /// The name or hex value of the color. /// - [ProtoMember(2)] public string? HexOrNameValue { get => _hexOrNameValue; @@ -113,6 +111,11 @@ public bool Equals(MapColor? other) return RgbaValues.SequenceEqual(other.RgbaValues) && (HexOrNameValue == other.HexOrNameValue); } + public MapColorSerializationRecord ToProtobuf() + { + return new MapColorSerializationRecord(RgbaValues, HexOrNameValue); + } + /// public override bool Equals(object? obj) { diff --git a/src/dymaptic.GeoBlazor.Core/Model/MapPath.cs b/src/dymaptic.GeoBlazor.Core/Model/MapPath.cs index 2b922cdd9..41a076348 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/MapPath.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/MapPath.cs @@ -5,7 +5,8 @@ /// ArcGIS Maps SDK for JavaScript ///
[JsonConverter(typeof(MapPathConverter))] -public class MapPath : List, IEquatable +[ProtobufSerializable] +public class MapPath : List, IEquatable, IProtobufSerializable { /// /// Implicitly converts a to a . @@ -79,10 +80,10 @@ public MapPath Clone() return newPath; } - - internal MapPathSerializationRecord ToSerializationRecord() + /// + public MapPathSerializationRecord ToProtobuf() { - return new MapPathSerializationRecord(this.Select(p => p.ToSerializationRecord()).ToArray()); + return new MapPathSerializationRecord(this.Select(p => p.ToProtobuf()).ToArray()); } } @@ -90,7 +91,8 @@ internal MapPathSerializationRecord ToSerializationRecord() /// This is another representation of that should be used to create s. /// [JsonConverter(typeof(MapPointConverter))] -public class MapPoint : List, IEquatable +[ProtobufSerializable] +public class MapPoint : List, IEquatable, IProtobufSerializable { /// /// Implicitly converts a to a . @@ -145,54 +147,13 @@ public MapPoint Copy() return new MapPoint(this); } - internal MapPointSerializationRecord ToSerializationRecord() + /// + public MapPointSerializationRecord ToProtobuf() { return new MapPointSerializationRecord(ToArray()); } } -[ProtoContract(Name = "MapPath")] -internal record MapPathSerializationRecord -{ - public MapPathSerializationRecord() - { - } - - public MapPathSerializationRecord(MapPointSerializationRecord[] Points) - { - this.Points = Points; - } - - public MapPath FromSerializationRecord() - { - return new MapPath(Points.Select(p => p.FromSerializationRecord())); - } - - [ProtoMember(1)] - public MapPointSerializationRecord[] Points { get; init; } = []; -} - -[ProtoContract(Name = "MapPoint")] -internal record MapPointSerializationRecord -{ - public MapPointSerializationRecord() - { - } - - public MapPointSerializationRecord(double[] Coordinates) - { - this.Coordinates = Coordinates; - } - - public MapPoint FromSerializationRecord() - { - return new MapPoint(Coordinates); - } - - [ProtoMember(1)] - public double[] Coordinates { get; init; } = []; -} - internal class MapPointEqualityComparer : EqualityComparer { public static MapPointEqualityComparer Instance => _instance ??= new MapPointEqualityComparer(); diff --git a/src/dymaptic.GeoBlazor.Core/Model/PortalGroup.gb.cs b/src/dymaptic.GeoBlazor.Core/Model/PortalGroup.gb.cs index 265476d20..f759ad3b6 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/PortalGroup.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/PortalGroup.gb.cs @@ -85,6 +85,11 @@ public partial record PortalGroup( /// public IJSObjectReference? CoreJsModule { get; set; } + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode + /// + public bool IsServer { get; set; } + /// /// Cancellation Token for async methods. /// diff --git a/src/dymaptic.GeoBlazor.Core/Model/PortalItemResource.gb.cs b/src/dymaptic.GeoBlazor.Core/Model/PortalItemResource.gb.cs index 4b2850bc9..6e74c1941 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/PortalItemResource.gb.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/PortalItemResource.gb.cs @@ -51,6 +51,11 @@ public partial record PortalItemResource( ///
public IJSObjectReference? CoreJsModule { get; set; } + /// + /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode + /// + public bool IsServer { get; set; } + /// /// Cancellation Token for async methods. /// diff --git a/src/dymaptic.GeoBlazor.Core/Model/SeparableWrapModes.cs b/src/dymaptic.GeoBlazor.Core/Model/SeparableWrapModes.cs index 75d56c0f1..3918f371b 100644 --- a/src/dymaptic.GeoBlazor.Core/Model/SeparableWrapModes.cs +++ b/src/dymaptic.GeoBlazor.Core/Model/SeparableWrapModes.cs @@ -1,6 +1,32 @@ namespace dymaptic.GeoBlazor.Core.Model; -public partial record SeparableWrapModes +/// +/// GeoBlazor Docs +/// A separable wrap configuration for horizontal and vertical wrapping modes. +/// ArcGIS Maps SDK for JavaScript +/// +/// +/// Horizontal wrapping mode. +/// ArcGIS Maps SDK for JavaScript +/// +/// +/// Vertical wrapping mode. +/// ArcGIS Maps SDK for JavaScript +/// +[CodeGenerationIgnore] +public record SeparableWrapModes( + [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + WrapMode? Horizontal = null, + [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + WrapMode? Vertical = null) { - // Add custom code to this file to override generated code -} \ No newline at end of file + /// + /// A separable wrap configuration for horizontal and vertical wrapping modes. + /// + /// + /// A wrapping mode to be used for both horizontal and vertical directions. + /// + public SeparableWrapModes(WrapMode? mode):this(mode, mode) + { + } +} diff --git a/src/dymaptic.GeoBlazor.Core/Model/SeparableWrapModes.gb.cs b/src/dymaptic.GeoBlazor.Core/Model/SeparableWrapModes.gb.cs deleted file mode 100644 index 7d319e615..000000000 --- a/src/dymaptic.GeoBlazor.Core/Model/SeparableWrapModes.gb.cs +++ /dev/null @@ -1,22 +0,0 @@ -// File auto-generated by dymaptic tooling. Any changes made here will be lost on future generation. To override functionality, use the relevant root .cs file. - -namespace dymaptic.GeoBlazor.Core.Model; - -/// -/// GeoBlazor Docs -/// A separable wrap configuration for horizontal and vertical wrapping modes. -/// ArcGIS Maps SDK for JavaScript -/// -/// -/// Horizontal wrapping mode. -/// ArcGIS Maps SDK for JavaScript -/// -/// -/// Vertical wrapping mode. -/// ArcGIS Maps SDK for JavaScript -/// -public partial record SeparableWrapModes( - [property:JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - Horizontal? Horizontal = null, - [property:JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - Vertical? Vertical = null); diff --git a/src/dymaptic.GeoBlazor.Core/Results/HitTestResult.cs b/src/dymaptic.GeoBlazor.Core/Results/HitTestResult.cs index a7adbddfa..902f90f73 100644 --- a/src/dymaptic.GeoBlazor.Core/Results/HitTestResult.cs +++ b/src/dymaptic.GeoBlazor.Core/Results/HitTestResult.cs @@ -7,6 +7,7 @@ namespace dymaptic.GeoBlazor.Core.Results; /// /// The screen coordinates (or native mouse event) of the click on the view. /// +[CodeGenerationIgnore] public record HitTestResult(ScreenPoint ScreenPoint) { /// @@ -30,43 +31,13 @@ public record HitTestResult(ScreenPoint ScreenPoint) /// The point geometry in the spatial reference of the view corresponding with the input screen coordinates. /// [JsonConverter(typeof(ViewHitConverter))] -public record ViewHit(string Type, Point MapPoint); - -[ProtoContract] -internal record ProtoViewHitCollection -{ - [ProtoMember(1)] - public ProtoViewHit[]? ViewHits { get; set; } -} - -[ProtoContract] -internal record ProtoViewHit +[ProtobufSerializable] +public record ViewHit(string Type, Point MapPoint) : IProtobufSerializable { - [ProtoMember(1)] - public string? Type { get; set; } - - [ProtoMember(2)] - public GeometrySerializationRecord? MapPoint { get; set; } - - [ProtoMember(3)] - public GraphicSerializationRecord? Graphic { get; set; } - - [ProtoMember(4)] - public string? LayerId { get; set; } - - public ViewHit FromSerializationRecord() + /// + public virtual ViewHitSerializationRecord ToProtobuf() { - if (Type == "graphic") - { - Guid? layerId = null; - if (Guid.TryParse(LayerId, out Guid layerGuid)) - { - layerId = layerGuid; - } - return new GraphicHit(Graphic!.FromSerializationRecord(), layerId, - (Point)MapPoint!.FromSerializationRecord()); - } - return new ViewHit(Type!, (Point)MapPoint!.FromSerializationRecord()); + return new ViewHitSerializationRecord(Type, MapPoint.ToProtobuf(), null, null, null); } } diff --git a/src/dymaptic.GeoBlazor.Core/Scripts/geoblazorProto.ts b/src/dymaptic.GeoBlazor.Core/Scripts/geoblazorProto.ts index c708ff541..db68fdcfd 100644 --- a/src/dymaptic.GeoBlazor.Core/Scripts/geoblazorProto.ts +++ b/src/dymaptic.GeoBlazor.Core/Scripts/geoblazorProto.ts @@ -359,6 +359,9 @@ message PopupTemplateCollection { repeated PopupTemplate items = 1; bool isNull = 1000; } +message ProtoGraphicCollection { + repeated Graphic graphics = 1; +} message RelatedRecordsInfoFieldOrder { bool isNull = 1000; } diff --git a/src/dymaptic.GeoBlazor.Core/Serialization/EnumJsonConverters.cs b/src/dymaptic.GeoBlazor.Core/Serialization/EnumJsonConverters.cs index 47146cb82..c178d97c2 100644 --- a/src/dymaptic.GeoBlazor.Core/Serialization/EnumJsonConverters.cs +++ b/src/dymaptic.GeoBlazor.Core/Serialization/EnumJsonConverters.cs @@ -236,4 +236,42 @@ public override TemporalTime Read(ref Utf8JsonReader reader, Type typeToConvert, return value is not null ? (TemporalTime)Enum.Parse(typeof(TemporalTime), value, true) : default; } +} + +/// +/// Converter with no hyphens +/// +internal class ImageFormatConverter : EnumToKebabCaseStringConverter where T: notnull +{ + /// + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + string? stringVal = Enum.GetName(typeof(T), value); + string resultString = stringVal!.ToLowerInvariant(); + writer.WriteStringValue(resultString); + } +} + +internal class ImageFormatReadonlyListConverter : EnumToKebabCaseReadOnlyListConverter where T : notnull +{ + public override void Write(Utf8JsonWriter writer, IReadOnlyList? value, JsonSerializerOptions options) + { + if (value is null || !value.Any()) + { + writer.WriteStartArray(); + writer.WriteEndArray(); + return; + } + + writer.WriteStartArray(); + foreach (T item in value) + { + string? stringVal = Enum.GetName(typeof(T), item); + if (stringVal is not null) + { + writer.WriteStringValue(stringVal.ToLowerInvariant()); + } + } + writer.WriteEndArray(); + } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Serialization/IJSStreamReferenceHelper.cs b/src/dymaptic.GeoBlazor.Core/Serialization/IJSStreamReferenceHelper.cs index 8d26f2432..9abbaff48 100644 --- a/src/dymaptic.GeoBlazor.Core/Serialization/IJSStreamReferenceHelper.cs +++ b/src/dymaptic.GeoBlazor.Core/Serialization/IJSStreamReferenceHelper.cs @@ -8,17 +8,17 @@ public static class IJSStreamReferenceHelper /// /// Convenience method to deserialize an to a specific .NET type. /// - public static async Task ReadJsStreamReference(this IJSStreamReference jsStreamReference, + public static async Task ReadJsStreamReferenceAsJSON(this IJSStreamReference jsStreamReference, long maxAllowedSize = 1_000_000_000L) { - return (T?)await ReadJsStreamReference(jsStreamReference, typeof(T), maxAllowedSize); + return (T?)await ReadJsStreamReferenceAsJSON(jsStreamReference, typeof(T), maxAllowedSize); } /// /// Convenience method to deserialize an to a specific .NET type. /// This overload returns an , so the type does not need to be known at compile time. /// - public static async Task ReadJsStreamReference(this IJSStreamReference jsStreamReference, Type returnType, + public static async Task ReadJsStreamReferenceAsJSON(this IJSStreamReference jsStreamReference, Type returnType, long maxAllowedSize = 1_000_000_000) { await using Stream stream = await jsStreamReference.OpenReadStreamAsync(maxAllowedSize); @@ -26,6 +26,17 @@ public static class IJSStreamReferenceHelper string json = await reader.ReadToEndAsync(); + if (returnType == typeof(string)) + { + return json.Trim('"'); + } + return JsonSerializer.Deserialize(json, returnType, GeoBlazorSerialization.JsonSerializerOptions); } + + public static async Task ReadJsStreamReferenceAsStream(this IJSStreamReference jsStreamReference, + long maxAllowedSize = 1_000_000_000L) + { + return await jsStreamReference.OpenReadStreamAsync(maxAllowedSize); + } } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Serialization/JsSyncManager.cs b/src/dymaptic.GeoBlazor.Core/Serialization/JsSyncManager.cs index 27ca00d0e..01ff9b078 100644 --- a/src/dymaptic.GeoBlazor.Core/Serialization/JsSyncManager.cs +++ b/src/dymaptic.GeoBlazor.Core/Serialization/JsSyncManager.cs @@ -11,7 +11,7 @@ public static class JsSyncManager public static Dictionary ProtoContractTypes { get; set; } = []; public static Dictionary ProtoCollectionTypes { get; set; } = []; - + public static void Initialize() { foreach (Type protoType in ProtoContractTypes.Values) @@ -20,7 +20,7 @@ public static void Initialize() } RuntimeTypeModel.Default.CompileInPlace(); - + _serializableMethods = SerializableMethods .ToDictionary(g => g.Key, g => g.Value.ToList()); } @@ -46,14 +46,14 @@ public static void Initialize() /// /// The collection of parameters to pass to the JS call. /// - public static async Task InvokeVoidJsMethod(this IJSObjectReference js, bool isServer, + public static async Task InvokeVoidJsMethod(this IJSObjectReference js, bool isServer, [CallerMemberName]string method = "", string className = "", CancellationToken cancellationToken = default, params object?[] parameters) { SerializableMethodRecord methodRecord = GetMethodRecord(method, className, true, parameters); List parameterList = GenerateSerializedParameters(methodRecord, parameters, isServer); - await js.InvokeVoidAsync("invokeVoidSerializedMethod", cancellationToken, + await js.InvokeVoidAsync("invokeVoidSerializedMethod", cancellationToken, [methodRecord.MethodName, isServer, ..parameterList]); } @@ -78,9 +78,9 @@ await js.InvokeVoidAsync("invokeVoidSerializedMethod", cancellationToken, /// /// The collection of parameters to pass to the JS call. /// - public static async Task InvokeJsMethod(this IJSObjectReference js, bool isServer, + public static async Task InvokeJsMethod(this IJSObjectReference js, bool isServer, [CallerMemberName]string method = "", string className = "", - CancellationToken cancellationToken = default, + CancellationToken cancellationToken = default, params object?[] parameters) { SerializableMethodRecord methodRecord = GetMethodRecord(method, className, false, parameters); @@ -105,12 +105,12 @@ public static async Task InvokeJsMethod(this IJSObjectReference js, bool i { ProtoContractTypes.TryGetValue(returnType!, out protoReturnType); } - + protoReturnTypeName = protoReturnType?.Name.Replace("SerializationRecord", ""); } - + IJSStreamReference? streamRef = await js.InvokeAsync( - "invokeSerializedMethod", cancellationToken, + "invokeSerializedMethod", cancellationToken, [methodRecord.MethodName, true, returnTypeIsProtobuf, protoReturnTypeName, ..parameterList]); if (streamRef is null) @@ -135,11 +135,11 @@ public static async Task InvokeJsMethod(this IJSObjectReference js, bool i { return default!; } - + // double-cast to force to generic return (T)(object)result; } - + return (await streamRef.ReadJsStreamReferenceAsJSON())!; } @@ -147,7 +147,7 @@ public static async Task InvokeJsMethod(this IJSObjectReference js, bool i "invokeSerializedMethod", cancellationToken, [methodRecord.MethodName, false, false, null, ..parameterList]); } - private static SerializableMethodRecord GetMethodRecord(string method, string className, bool returnsVoid, + private static SerializableMethodRecord GetMethodRecord(string method, string className, bool returnsVoid, object?[] providedParameters) { if (!_serializableMethods.TryGetValue(className, out List? classMethods)) @@ -156,14 +156,14 @@ private static SerializableMethodRecord GetMethodRecord(string method, string _serializableMethods[className] = classMethods; } - if (classMethods.Where(m => + if (classMethods.Where(m => // same method name string.Equals(m.MethodName, method, StringComparison.OrdinalIgnoreCase) // same number of parameters && m.Parameters.Length == providedParameters.Length // either both void or both non-void && ((m.ReturnValue is null && returnsVoid) - || (m.ReturnValue is not null && !returnsVoid))).ToList() + || (m.ReturnValue is not null && !returnsVoid))).ToList() is not { } matchedMethods) { // use reflection since we don't have a stored method record @@ -174,12 +174,12 @@ private static SerializableMethodRecord GetMethodRecord(string method, string .ToArray(); matchedMethods = []; - + foreach (MethodInfo methodInfo in methodInfos) { List methodParams = []; var paramInfos = methodInfo.GetParameters(); - + foreach (ParameterInfo paramInfo in paramInfos) { NullabilityInfo nullabilityInfo = nullabilityContext.Create(paramInfo); @@ -195,7 +195,7 @@ private static SerializableMethodRecord GetMethodRecord(string method, string : null; methodParams.Add(new SerializableParameterRecord(paramType, isNullable, collectionType)); } - + SerializableParameterRecord? returnRecord = null; if (!returnsVoid && methodInfo.ReturnType != typeof(void)) @@ -230,7 +230,7 @@ private static SerializableMethodRecord GetMethodRecord(string method, string ? returnType.GetElementType() : returnType.GenericTypeArguments[0]; } - + bool isGenericParameter = returnType.IsGenericParameter; if (isGenericParameter) @@ -266,7 +266,7 @@ private static SerializableMethodRecord GetMethodRecord(string method, string } Type requestedReturnType = typeof(T); - + // find record with potentially matching parameter types including nulls return matchedMethods.First(m => { @@ -279,7 +279,7 @@ private static SerializableMethodRecord GetMethodRecord(string method, string { providedParameterType = Nullable.GetUnderlyingType(providedParameterType)!; } - + SerializableParameterRecord methodParam = m.Parameters[i]; if (providedParameterType is null) @@ -303,7 +303,7 @@ private static SerializableMethodRecord GetMethodRecord(string method, string return true; }); } - + private static List GenerateSerializedParameters(SerializableMethodRecord methodRecord, object?[] parameters, bool isServer) { @@ -329,16 +329,16 @@ private static SerializableMethodRecord GetMethodRecord(string method, string /// /// Boolean flag to identify if GeoBlazor is running in Blazor Server mode /// - private static object?[] ProcessParameter(object? parameterValue, SerializableParameterRecord parameterRecord, + private static object?[] ProcessParameter(object? parameterValue, SerializableParameterRecord parameterRecord, bool isServer) { if (parameterValue is null) { return ["null", null]; } - + Type paramType = parameterRecord.Type; - + if (simpleTypes.Contains(paramType) || paramType.IsPrimitive) { return [GetKey(paramType), parameterValue]; @@ -356,7 +356,7 @@ private static SerializableMethodRecord GetMethodRecord(string method, string // pass as type string so JS can parse correctly return [nameof(String), stringValue]; } - + if (paramType.IsGenericType && paramType.GetGenericTypeDefinition() == typeof(Nullable<>)) { Type underlyingType = Nullable.GetUnderlyingType(paramType)!; @@ -370,22 +370,22 @@ private static SerializableMethodRecord GetMethodRecord(string method, string ? paramType.GetElementType()! : paramType.GenericTypeArguments[0]); string key = $"{GetKey(genericType)}Collection"; - + if (ProtoContractTypes.ContainsKey(genericType)) { object protobufParameter = list.ToProtobufCollectionParameter(genericType, isServer); return [key, protobufParameter]; } - + return [key, parameterValue.ToJsonParameter(isServer)]; } - + if (ProtoContractTypes.ContainsKey(paramType)) { object protobufParameter = parameterValue.ToProtobufParameter(paramType, isServer); return [GetKey(paramType), protobufParameter]; } - + if (parameterValue is AttributesDictionary attributesDictionary) { AttributeSerializationRecord[] serializedItems = attributesDictionary.ToProtobufArray(); @@ -393,7 +393,7 @@ private static SerializableMethodRecord GetMethodRecord(string method, string MemoryStream memoryStream = new(); Serializer.Serialize(memoryStream, collection); memoryStream.Seek(0, SeekOrigin.Begin); - + if (isServer) { return [nameof(AttributesDictionary), new DotNetStreamReference(memoryStream)]; @@ -406,7 +406,7 @@ private static SerializableMethodRecord GetMethodRecord(string method, string return [GetKey(paramType), parameterValue.ToJsonParameter(isServer)]; } - + private static object ToJsonParameter(this T obj, bool isServer) { if (isServer) @@ -416,7 +416,7 @@ private static object ToJsonParameter(this T obj, bool isServer) memoryStream.Seek(0, SeekOrigin.Begin); return new DotNetStreamReference(memoryStream); } - + return JsonSerializer.Serialize(obj, GeoBlazorSerialization.JsonSerializerOptions); } @@ -438,7 +438,7 @@ private static SerializableParameterRecord GetSerializableParameterRecord(object { return new SerializableParameterRecord(typeof(object), true, null); } - + Type paramType = parameter.GetType(); if (simpleTypes.Contains(paramType)) @@ -451,12 +451,12 @@ private static SerializableParameterRecord GetSerializableParameterRecord(object // anonymous object return new SerializableParameterRecord(typeof(object), true, null); } - + bool isCollection = paramType.IsAssignableTo(typeof(IEnumerable)); - Type? collectionType = isCollection - ? paramType.IsArray - ? paramType.GetElementType() - : paramType.GetGenericArguments()[0] + Type? collectionType = isCollection + ? paramType.IsArray + ? paramType.GetElementType() + : paramType.GetGenericArguments()[0] : null; return new SerializableParameterRecord(paramType, true, collectionType); } @@ -468,7 +468,7 @@ private static SerializableParameterRecord GetSerializableReturnRecord(bool r return new SerializableParameterRecord(typeof(void), false, null); } Type returnType = typeof(T); - + if (simpleTypes.Contains(returnType)) { return new SerializableParameterRecord(returnType, true, null); @@ -476,22 +476,22 @@ private static SerializableParameterRecord GetSerializableReturnRecord(bool r if (returnType == typeof(AttributesDictionary)) { - return new SerializableParameterRecord(typeof(AttributesDictionary), true, + return new SerializableParameterRecord(typeof(AttributesDictionary), true, typeof(AttributeSerializationRecord)); } bool isCollection = returnType.IsAssignableTo(typeof(IEnumerable)) && !returnType.IsAssignableTo(typeof(IDictionary)); - Type? collectionType = isCollection - ? returnType.IsArray - ? returnType.GetElementType() - : returnType.GetGenericArguments()[0] + Type? collectionType = isCollection + ? returnType.IsArray + ? returnType.GetElementType() + : returnType.GetGenericArguments()[0] : null; return new SerializableParameterRecord(returnType, true, collectionType); } - + private static Dictionary> _serializableMethods = []; private static readonly NullabilityInfoContext nullabilityContext = new(); - + private static readonly Type[] simpleTypes = [ typeof(string), typeof(char), typeof(bool), typeof(byte), typeof(sbyte), typeof(short), @@ -501,6 +501,6 @@ private static SerializableParameterRecord GetSerializableReturnRecord(bool r ]; } -public record SerializableMethodRecord(string MethodName, SerializableParameterRecord[] Parameters, +public record SerializableMethodRecord(string MethodName, SerializableParameterRecord[] Parameters, SerializableParameterRecord? ReturnValue); -public record SerializableParameterRecord(Type Type, bool IsNullable, Type? SingleType); +public record SerializableParameterRecord(Type Type, bool IsNullable, Type? SingleType); \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/Serialization/ProtobufSerializationBase.cs b/src/dymaptic.GeoBlazor.Core/Serialization/ProtobufSerializationBase.cs deleted file mode 100644 index bbc6528be..000000000 --- a/src/dymaptic.GeoBlazor.Core/Serialization/ProtobufSerializationBase.cs +++ /dev/null @@ -1,77 +0,0 @@ -using ProtoBuf; - -namespace dymaptic.GeoBlazor.Core.Serialization; - -/// -/// Base class for all Protobuf serialization records for MapComponents. -/// -[ProtoContract(Name = "MapComponent")] -public record MapComponentSerializationRecord -{ - // ProtoMember tag 1000 is used for base class properties to avoid conflicts with derived class tags. - // Derived classes use tags 1-999 for their specific properties. - - /// - /// Indicates whether this record represents a null value. - /// - [ProtoMember(1000)] - public virtual bool IsNull { get; init; } -} - -/// -/// Generic base class for Protobuf serialization records that can convert back to their source type. -/// -/// The type that this record serializes. -public abstract record MapComponentSerializationRecord : MapComponentSerializationRecord -{ - /// - /// Converts this serialization record back to its source type. - /// - public abstract T? FromSerializationRecord(); -} - -/// -/// Base class for Protobuf serialization records representing collections. -/// -[ProtoContract(Name = "MapComponentCollection")] -public record MapComponentBaseCollectionSerializationRecord -{ - // ProtoMember tag 1000 is used for base class properties to avoid conflicts with derived class tags. - - /// - /// Indicates whether this record represents a null collection. - /// - [ProtoMember(1000)] - public virtual bool IsNull { get; init; } -} - -/// -/// Generic base class for Protobuf serialization records representing collections. -/// -/// The type of items in the collection. -public abstract record MapComponentCollectionSerializationRecord : MapComponentBaseCollectionSerializationRecord - where TItem : MapComponentSerializationRecord -{ - /// - /// The items in the collection. - /// - public abstract TItem[]? Items { get; set; } -} - -/// -/// Record representing serializable method metadata for JS interop. -/// -public record SerializableMethodRecord( - string MethodName, - SerializableParameterRecord[]? Parameters, - SerializableParameterRecord? ReturnValue); - -/// -/// Record representing a serializable parameter for JS interop. -/// -public record SerializableParameterRecord( - string Name, - Type Type, - bool IsNullable, - bool IsCollection, - Type? CollectionItemType); diff --git a/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj b/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj index 120cdc930..537e09a7a 100644 --- a/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj +++ b/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj @@ -24,6 +24,8 @@ net8.0 true GeoBlazor_Untested + latest + true enable enable - 5.0.0.21 + 5.0.0.27 true Debug;Release;SourceGen Highlighting AnyCPU diff --git a/GeoBlazorBuild.ps1 b/GeoBlazorBuild.ps1 index ffaafb513..cdf0c34b5 100644 --- a/GeoBlazorBuild.ps1 +++ b/GeoBlazorBuild.ps1 @@ -64,6 +64,7 @@ try { $ProProjectPath = Join-Path -Path $ProRepoRoot "src/dymaptic.GeoBlazor.Pro" $ValidatorProjectPath = Join-Path -Path $ProRepoRoot "src/dymaptic.GeoBlazor.Pro.Validator" $AssetsPath = Join-Path -Path $CoreProjectPath "wwwroot/assets" + $BuildScriptsPath = Join-Path -Path $CoreRepoRoot "build" $OtherConfiguration = if ($Configuration.ToLowerInvariant() -eq "release") { "Debug" } else { "Release" } @@ -109,19 +110,19 @@ try { Write-Host "" Write-Host "" dotnet clean (Join-Path $CoreProjectPath dymaptic.GeoBlazor.Core.csproj) /p:PipelineBuild=true - Get-ChildItem -Path (Join-Path $CoreProjectPath "bin") -Recurse -Force | Remove-Item -Recurse -Force - Get-ChildItem -Path (Join-Path $CoreProjectPath "obj") -Recurse -Force | Remove-Item -Recurse -Force + Remove-Item -Path (Join-Path $CoreProjectPath "bin") -Recurse -Force + Remove-Item -Path (Join-Path $CoreProjectPath "obj") -Recurse -Force if (Test-Path (Join-Path $CoreProjectPath "wwwroot/js")) { Get-ChildItem -Path (Join-Path $CoreProjectPath "wwwroot/js") -Recurse -Force | Remove-Item -Recurse -Force } if (Test-Path (Join-Path $CoreProjectPath "node_modules")) { - Get-ChildItem -Path (Join-Path $CoreProjectPath "node_modules") -Recurse -Force | Remove-Item -Recurse -Force + Remove-Item (Join-Path $CoreProjectPath "node_modules") -Recurse -Force } if ($Pro -eq $true) { dotnet clean (Join-Path $ProProjectPath dymaptic.GeoBlazor.Pro.csproj) /p:PipelineBuild=true - Get-ChildItem -Path (Join-Path $ProProjectPath "bin") -Recurse -Force | Remove-Item -Recurse -Force - Get-ChildItem -Path (Join-Path $ProProjectPath "obj") -Recurse -Force | Remove-Item -Recurse -Force + Remove-Item -Path (Join-Path $ProProjectPath "bin") -Recurse -Force + Remove-Item -Path (Join-Path $ProProjectPath "obj") -Recurse -Force Get-ChildItem -Path (Join-Path $ProProjectPath "obf") -Recurse -Force | Remove-Item -Recurse -Force if (Test-Path (Join-Path $ProProjectPath "build/resources")) { Get-ChildItem -Path (Join-Path $ProProjectPath "build/resources") -Recurse -Force | Remove-Item -Recurse -Force @@ -130,12 +131,12 @@ try { Get-ChildItem -Path (Join-Path $ProProjectPath "wwwroot/js") -Recurse -Force | Remove-Item -Recurse -Force } if (Test-Path (Join-Path $ProProjectPath "node_modules")) { - Get-ChildItem -Path (Join-Path $ProProjectPath "node_modules") -Recurse -Force | Remove-Item -Recurse -Force + Remove-Item -Path (Join-Path $ProProjectPath "node_modules") -Recurse -Force } if (Test-Path $ValidatorProjectPath) { dotnet clean (Join-Path $ValidatorProjectPath dymaptic.GeoBlazor.Pro.V.csproj) - Get-ChildItem -Path (Join-Path $ValidatorProjectPath "bin") -Recurse -Force | Remove-Item -Recurse -Force - Get-ChildItem -Path (Join-Path $ValidatorProjectPath "obj") -Recurse -Force | Remove-Item -Recurse -Force + Remove-Item -Path (Join-Path $ValidatorProjectPath "bin") -Recurse -Force + Remove-Item -Path (Join-Path $ValidatorProjectPath "obj") -Recurse -Force Get-ChildItem -Path (Join-Path $ValidatorProjectPath "obf") -Recurse -Force | Remove-Item -Recurse -Force } @@ -144,20 +145,6 @@ try { Write-Host "" $Step++ - - ## Delete old assets - from prior to 4.2.x - if (Test-Path $AssetsPath) { - $StepStartTime = Get-Date - Write-Host "" - Write-Host "$Step. Deleting old assets at $AssetsPath" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - Get-ChildItem -Path $AssetsPath -Recurse | Remove-Item -Recurse -Force - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - - $Step++ - } $CustomVersionSet = $null -ne $Version -and $Version -ne "" @@ -224,8 +211,6 @@ try { $Step++ } - Set-Location $CoreProjectPath - $StepStartTime = Get-Date $CoreLockFilePath = Join-Path -Path $CoreProjectPath "esBuild.$Configuration.lock" @@ -242,11 +227,13 @@ try { Write-Host "Lock released, continuing..." } + Set-Location $BuildScriptsPath + Write-Host "" Write-Host "$Step. Building Core JavaScript" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline Write-Host "" Write-Host "" - ./esBuild.ps1 -c $Configuration + dotnet run ESBuild.cs -- -c $Configuration if ($LASTEXITCODE -ne 0) { Write-Host "ERROR: esBuild.ps1 failed with exit code $LASTEXITCODE. Exiting." -ForegroundColor Red exit 1 @@ -267,6 +254,8 @@ try { Write-Host "" $Step++ + + Set-Location $CoreProjectPath $StepStartTime = Get-Date Write-Host "" @@ -429,12 +418,14 @@ try { } Write-Host "Lock released, continuing..." } + + Set-Location $BuildScriptsPath Write-Host "" Write-Host "$Step. Building Pro JavaScript" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline Write-Host "" Write-Host "" - ./esProBuild.ps1 -c $Configuration + dotnet run ESBuild.cs -- -c $Configuration --pro if ($LASTEXITCODE -ne 0) { Write-Host "ERROR: esProBuild.ps1 failed with exit code $LASTEXITCODE. Exiting." -ForegroundColor Red exit 1 @@ -462,6 +453,8 @@ try { Write-Host "" Write-Host "" + Set-Location $ProProjectPath + # double-escape line breaks $ProBuild = "dotnet build dymaptic.GeoBlazor.Pro.csproj --no-restore `` -c $Configuration `` diff --git a/build/ConsoleDialog.cs b/build/ConsoleDialog.cs index 617ef5bc5..c97d78e3e 100644 --- a/build/ConsoleDialog.cs +++ b/build/ConsoleDialog.cs @@ -1,3 +1,5 @@ +#!/usr/bin/env dotnet + using System.Diagnostics; // Manages a console window for displaying log messages during source generation. @@ -63,7 +65,8 @@ void StartConsoleWindow(string title) void StartWindowsConsole(string title) { string escapedPath = _consoleTempFile!.Replace("'", "''"); - string command = $"$Host.UI.RawUI.WindowTitle = 'GeoBlazor Source Generator: {title}'; " + + string windowTitle = string.IsNullOrWhiteSpace(title) ? "GeoBlazor Build" : title; + string command = $"$Host.UI.RawUI.WindowTitle = '{windowTitle}'; " + $"Write-Host 'GeoBlazor Source Generator Output' -ForegroundColor Cyan; " + $"Write-Host ('=' * 50); " + $"Get-Content -Path '{escapedPath}' -Wait -Tail 100"; diff --git a/build/esBuild.cs b/build/ESBuild.cs similarity index 94% rename from build/esBuild.cs rename to build/ESBuild.cs index 0f1961d6d..c014212f8 100644 --- a/build/esBuild.cs +++ b/build/ESBuild.cs @@ -6,6 +6,7 @@ // -c, --configuration Build configuration (default: Debug) // -f, --force Force rebuild, ignoring lock files and record // -p, --pro Run the GeoBlazor Pro ESBuild process +// -d, --dialog Show a console dialog during build // -h, --help Display help message using System.Diagnostics; @@ -20,6 +21,7 @@ bool force = false; bool help = false; bool pro = false; +bool dialog = false; for (int i = 0; i < args.Length; i++) { @@ -33,6 +35,10 @@ configuration = args[++i]; } break; + case "-d": + case "--dialog": + dialog = true; + break; case "-f": case "--force": force = true; @@ -55,8 +61,6 @@ } } -Trace.Listeners.Add(new ConsoleTraceListener()); - if (help) { Trace.WriteLine("ESBuild TypeScript -> JavaScript Compilation Script"); @@ -70,6 +74,27 @@ return 0; } +Trace.Listeners.Add(new ConsoleTraceListener()); + +Process? dialogProcess = null; + +if (dialog) +{ + dialogProcess = StartConsoleDialog(scriptDir, + $"GeoBlazor {(pro ? "Pro" : "Core")} ESBuild"); + if (dialogProcess?.StandardInput is null) + { + Trace.WriteLine("Failed to start console dialog. Exiting."); + } + else + { + dialogProcess.StandardInput.AutoFlush = true; + Trace.Listeners.Add(new DialogTraceListener(dialogProcess)); + } +} + +Trace.WriteLine("Launching ESBuild..."); + // Normalize configuration configuration = configuration.Equals("release", StringComparison.OrdinalIgnoreCase) ? "Release" : "Debug"; @@ -95,15 +120,6 @@ string proLockFilePath = configuration == "Release" ? proReleaseLockFile : proDebugLockFile; string lockFilePath = pro ? proLockFilePath : coreLockFilePath; -Trace.WriteLine($"Core source directory: {coreSourceDir}"); - -if (pro) -{ - Trace.WriteLine($"Pro source directory: {proSourceDir}"); -} -Trace.WriteLine($"Scripts directory: {coreScriptsDir}"); -Trace.WriteLine($"Configuration: {configuration}"); - // Handle --force flag: delete record file if (force && File.Exists(coreRecordFilePath)) { @@ -139,18 +155,6 @@ Environment.Exit(0); } -// Start dialog process only if we're actually going to build -Process? dialogProcess = StartConsoleDialog(scriptDir, $"GeoBlazor {(pro ? "Pro" : "Core")} ESBuild"); -if (dialogProcess?.StandardInput is null) -{ - Trace.WriteLine("Failed to start console dialog. Exiting."); -} -else -{ - dialogProcess.StandardInput.AutoFlush = true; - Trace.Listeners.Add(new DialogTraceListener(dialogProcess)); -} - // Check if the process is locked for the current configuration bool locked = configuration == "Debug" && File.Exists(coreDebugLockFile) || configuration == "Release" && File.Exists(coreReleaseLockFile) @@ -339,6 +343,7 @@ static bool CheckIfNeedsBuild(string recordFilePath, string currentBranch, strin if (Directory.Exists(outputDir) && Directory.GetFiles(outputDir).Length > 0) { Trace.WriteLine("Output directory is not empty. Skipping build."); + KillDialog(dialogProcess); Environment.Exit(0); } else @@ -473,6 +478,10 @@ static void KillDialog(Process? dialog) { if (dialog?.StandardInput is not null) { + // Flush to ensure all pending messages are sent before exit + dialog.StandardInput.Flush(); + // Small delay to allow the dialog to display the final message + Thread.Sleep(500); dialog.StandardInput.WriteLine("exit"); } } diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProcessHelper.cs b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProcessHelper.cs index bcd3fc342..e4baee42e 100644 --- a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProcessHelper.cs +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProcessHelper.cs @@ -204,6 +204,8 @@ public static void CloseDialog() return; } + _consoleProcess.StandardInput.Flush(); + Thread.Sleep(500); _consoleProcess.StandardInput.WriteLine("exit"); _consoleProcess.WaitForExit(); _consoleProcess.Dispose(); @@ -239,9 +241,10 @@ private static void ShowOrUpdateConsole(string title, string message, }; _consoleProcess = Process.Start(startInfo); + _consoleProcess!.StandardInput.AutoFlush = true; } - _consoleProcess!.StandardInput.WriteLine(message); + _consoleProcess.StandardInput.WriteLine(message); } private static readonly string shellCommand = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/SerializationGenerator.cs b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/SerializationGenerator.cs index 76afe8086..1d2711f92 100644 --- a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/SerializationGenerator.cs +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/SerializationGenerator.cs @@ -83,7 +83,7 @@ namespace dymaptic.GeoBlazor.{{(isPro ? "Pro" : "Core")}}.Serialization; /// /// This class is generated by a source generator and contains pre-analyzed serialization information. /// - internal static class {{className}} + internal static partial class {{className}} { """); @@ -157,7 +157,7 @@ private static string GenerateExtensionMethods(Dictionary /// A collection of types that can be serialized to Protobuf /// - public static Dictionary ProtoContractTypes => _protoContractTypes; + public static partial Dictionary ProtoContractTypes => _protoContractTypes; private static readonly Dictionary _protoContractTypes = new() { @@ -168,7 +168,7 @@ private static string GenerateExtensionMethods(Dictionary /// A collection of types that can be serialized to Protobuf as collections of a specific Type ///
- public static Dictionary ProtoCollectionTypes => _protoCollectionTypes; + public static partial Dictionary ProtoCollectionTypes => _protoCollectionTypes; private static readonly Dictionary _protoCollectionTypes = new() { @@ -365,7 +365,7 @@ private static string GenerateSerializableMethodRecords( /// /// A collection of serializable methods and their parameters/return types. /// - public static Dictionary SerializableMethods => _serializableMethods + public static partial Dictionary SerializableMethods => _serializableMethods .Concat(CoreSerializationData.SerializableMethods) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); @@ -380,7 +380,7 @@ private static string GenerateSerializableMethodRecords( /// /// A collection of serializable methods and their parameters/return types. /// - public static Dictionary SerializableMethods => _serializableMethods; + public static partial Dictionary SerializableMethods => _serializableMethods; private static readonly Dictionary _serializableMethods = new() { diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator/ESBuildGenerator.cs b/src/dymaptic.GeoBlazor.Core.SourceGenerator/ESBuildGenerator.cs index 1f640c92f..39147f21f 100644 --- a/src/dymaptic.GeoBlazor.Core.SourceGenerator/ESBuildGenerator.cs +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator/ESBuildGenerator.cs @@ -14,6 +14,10 @@ namespace dymaptic.GeoBlazor.Core.SourceGenerator; [SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1035:Do not use APIs banned for analyzers")] public class ESBuildGenerator : IIncrementalGenerator { + private static string? BuildScriptsPath => _corePath is null + ? null + : Path.GetFullPath(Path.Combine(_corePath, "..", "..", "build")); + /// public void Initialize(IncrementalGeneratorInitializationContext context) { @@ -67,7 +71,9 @@ private void FilesChanged(SourceProductionContext context, ProcessHelper.Log(nameof(ESBuildGenerator), "Skipping ESBuild process as PipelineBuild is set to true.", DiagnosticSeverity.Info, - context); + context, true); + + ProcessHelper.CloseDialog(); return; } @@ -152,12 +158,19 @@ private void LaunchESBuild(SourceProductionContext context) bool buildSuccess = false; bool proBuildSuccess = false; - // gets the esBuild.ps1 script from the Core path + // gets the ESBuild.cs script tasks.Add(Task.Run(async () => { - await ProcessHelper.RunPowerShellScript("Core", - _corePath!, "esBuild.ps1", - ["-c", _configuration!], logBuilder, context.CancellationToken); + await ProcessHelper.Execute("Core", + BuildScriptsPath!, "dotnet", + [ + "run", + "ESBuild.cs", + "-c", _configuration!, // pass config to MSBuild + "--", + "-c", _configuration!, // set config for ESBuild + "-d" // show dialog + ], logBuilder, context.CancellationToken); buildSuccess = true; })); @@ -167,9 +180,17 @@ await ProcessHelper.RunPowerShellScript("Core", tasks.Add(Task.Run(async () => { - await ProcessHelper.RunPowerShellScript("Pro", - _proPath, "esProBuild.ps1", - ["-c", _configuration!], logBuilder, context.CancellationToken); + await ProcessHelper.Execute("Pro", + BuildScriptsPath!, "dotnet", + [ + "run", + "ESBuild.cs", + "-c", _configuration!, // pass config to MSBuild + "--", + "-c", _configuration!, // set config for ESBuild + "-d", // show dialog + "--pro" // build for Pro project + ], logBuilder, context.CancellationToken); proBuildSuccess = true; })); } diff --git a/src/dymaptic.GeoBlazor.Core/Serialization/CoreSerializationData.cs b/src/dymaptic.GeoBlazor.Core/Serialization/CoreSerializationData.cs new file mode 100644 index 000000000..8651a13d3 --- /dev/null +++ b/src/dymaptic.GeoBlazor.Core/Serialization/CoreSerializationData.cs @@ -0,0 +1,16 @@ +namespace dymaptic.GeoBlazor.Core.Serialization; + +/// +/// Partial class containing serialization data for core GeoBlazor types. +/// Source generator provides implementation. +/// + +// ReSharper disable once PartialTypeWithSinglePart +internal static partial class CoreSerializationData +{ + public static partial Dictionary SerializableMethods { get; } + + public static partial Dictionary ProtoContractTypes { get; } + + public static partial Dictionary ProtoCollectionTypes { get; } +} \ No newline at end of file From d9c7ea231ad506cad0c7aa84f5c3a349b7eadeb8 Mon Sep 17 00:00:00 2001 From: Tim Purdum Date: Wed, 21 Jan 2026 16:20:48 -0600 Subject: [PATCH 6/7] Remove unused PowerShell build scripts for GeoBlazor to clean up repository and streamline build process --- .github/workflows/dev-pr-build.yml | 2 +- .github/workflows/main-release-build.yml | 2 +- CLAUDE.md | 6 +- Directory.Build.props | 3 +- Directory.Build.targets | 2 +- Dockerfile | 21 +- GeoBlazorBuild.ps1 | 534 -------- badge_fullmethodcoverage.svg | 2 +- badge_linecoverage.svg | 2 +- badge_methodcoverage.svg | 2 +- build-scripts/BuildAppSettings.cs | 181 +++ build-scripts/BuildTemplates.cs | 609 ++++++++++ {build => build-scripts}/ConsoleDialog.cs | 40 +- {build => build-scripts}/ESBuild.cs | 154 ++- build-scripts/ESBuildClearLocks.cs | 72 ++ build-scripts/ESBuildWaitForCompletion.cs | 149 +++ build-scripts/FetchNuGetVersion.cs | 98 ++ build-scripts/GeoBlazorBuild.cs | 1074 +++++++++++++++++ build-scripts/ScriptBuilder.cs | 125 ++ build-tools/BuildAppSettings.deps.json | 23 + build-tools/BuildAppSettings.dll | Bin 0 -> 10240 bytes build-tools/BuildAppSettings.exe | Bin 0 -> 162304 bytes .../BuildAppSettings.runtimeconfig.json | 36 + build-tools/BuildTemplates.deps.json | 23 + build-tools/BuildTemplates.dll | Bin 0 -> 23040 bytes build-tools/BuildTemplates.exe | Bin 0 -> 162304 bytes build-tools/BuildTemplates.runtimeconfig.json | 15 + build-tools/ConsoleDialog.deps.json | 23 + build-tools/ConsoleDialog.dll | Bin 0 -> 11264 bytes build-tools/ConsoleDialog.exe | Bin 0 -> 162304 bytes build-tools/ConsoleDialog.runtimeconfig.json | 36 + build-tools/ESBuild.deps.json | 23 + build-tools/ESBuild.dll | Bin 0 -> 18944 bytes build-tools/ESBuild.exe | Bin 0 -> 162304 bytes build-tools/ESBuild.runtimeconfig.json | 36 + build-tools/ESBuildClearLocks.deps.json | 23 + build-tools/ESBuildClearLocks.dll | Bin 0 -> 8192 bytes build-tools/ESBuildClearLocks.exe | Bin 0 -> 162304 bytes .../ESBuildClearLocks.runtimeconfig.json | 36 + .../ESBuildWaitForCompletion.deps.json | 23 + build-tools/ESBuildWaitForCompletion.dll | Bin 0 -> 9728 bytes build-tools/ESBuildWaitForCompletion.exe | Bin 0 -> 162816 bytes ...SBuildWaitForCompletion.runtimeconfig.json | 36 + build-tools/FetchNuGetVersion.deps.json | 23 + build-tools/FetchNuGetVersion.dll | Bin 0 -> 9216 bytes build-tools/FetchNuGetVersion.exe | Bin 0 -> 162304 bytes .../FetchNuGetVersion.runtimeconfig.json | 36 + build-tools/GeoBlazorBuild.deps.json | 23 + build-tools/GeoBlazorBuild.dll | Bin 0 -> 40448 bytes build-tools/GeoBlazorBuild.exe | Bin 0 -> 162304 bytes build-tools/GeoBlazorBuild.runtimeconfig.json | 36 + buildAppSettings.ps1 | 84 -- bumpVersion.ps1 | 88 -- esBuildClearLocks.ps1 | 22 - esBuildWaitForCompletion.ps1 | 42 - showDialog.ps1 | 879 -------------- .../ProcessHelper.cs | 223 +++- .../ProtobufDefinitionsGenerator.cs | 31 +- .../SerializationGenerator.cs | 8 +- .../ESBuildGenerator.cs | 84 +- .../ProtobufSourceGenerator.cs | 59 +- .../badge_fullmethodcoverage.svg | 4 +- .../badge_linecoverage.svg | 4 +- .../badge_methodcoverage.svg | 4 +- .../dymaptic.GeoBlazor.Core.csproj | 2 +- src/dymaptic.GeoBlazor.Core/esBuild.ps1 | 311 ----- src/dymaptic.GeoBlazor.Core/esBuildLogger.ps1 | 48 - .../GeoBlazorTestClass.cs | 97 +- .../TestConfig.cs | 58 +- 69 files changed, 3320 insertions(+), 2257 deletions(-) delete mode 100644 GeoBlazorBuild.ps1 create mode 100644 build-scripts/BuildAppSettings.cs create mode 100644 build-scripts/BuildTemplates.cs rename {build => build-scripts}/ConsoleDialog.cs (89%) rename {build => build-scripts}/ESBuild.cs (80%) create mode 100644 build-scripts/ESBuildClearLocks.cs create mode 100644 build-scripts/ESBuildWaitForCompletion.cs create mode 100644 build-scripts/FetchNuGetVersion.cs create mode 100644 build-scripts/GeoBlazorBuild.cs create mode 100644 build-scripts/ScriptBuilder.cs create mode 100644 build-tools/BuildAppSettings.deps.json create mode 100644 build-tools/BuildAppSettings.dll create mode 100644 build-tools/BuildAppSettings.exe create mode 100644 build-tools/BuildAppSettings.runtimeconfig.json create mode 100644 build-tools/BuildTemplates.deps.json create mode 100644 build-tools/BuildTemplates.dll create mode 100644 build-tools/BuildTemplates.exe create mode 100644 build-tools/BuildTemplates.runtimeconfig.json create mode 100644 build-tools/ConsoleDialog.deps.json create mode 100644 build-tools/ConsoleDialog.dll create mode 100644 build-tools/ConsoleDialog.exe create mode 100644 build-tools/ConsoleDialog.runtimeconfig.json create mode 100644 build-tools/ESBuild.deps.json create mode 100644 build-tools/ESBuild.dll create mode 100644 build-tools/ESBuild.exe create mode 100644 build-tools/ESBuild.runtimeconfig.json create mode 100644 build-tools/ESBuildClearLocks.deps.json create mode 100644 build-tools/ESBuildClearLocks.dll create mode 100644 build-tools/ESBuildClearLocks.exe create mode 100644 build-tools/ESBuildClearLocks.runtimeconfig.json create mode 100644 build-tools/ESBuildWaitForCompletion.deps.json create mode 100644 build-tools/ESBuildWaitForCompletion.dll create mode 100644 build-tools/ESBuildWaitForCompletion.exe create mode 100644 build-tools/ESBuildWaitForCompletion.runtimeconfig.json create mode 100644 build-tools/FetchNuGetVersion.deps.json create mode 100644 build-tools/FetchNuGetVersion.dll create mode 100644 build-tools/FetchNuGetVersion.exe create mode 100644 build-tools/FetchNuGetVersion.runtimeconfig.json create mode 100644 build-tools/GeoBlazorBuild.deps.json create mode 100644 build-tools/GeoBlazorBuild.dll create mode 100644 build-tools/GeoBlazorBuild.exe create mode 100644 build-tools/GeoBlazorBuild.runtimeconfig.json delete mode 100644 buildAppSettings.ps1 delete mode 100644 bumpVersion.ps1 delete mode 100644 esBuildClearLocks.ps1 delete mode 100644 esBuildWaitForCompletion.ps1 delete mode 100644 showDialog.ps1 delete mode 100644 src/dymaptic.GeoBlazor.Core/esBuild.ps1 delete mode 100644 src/dymaptic.GeoBlazor.Core/esBuildLogger.ps1 diff --git a/.github/workflows/dev-pr-build.yml b/.github/workflows/dev-pr-build.yml index a71212069..505e73619 100644 --- a/.github/workflows/dev-pr-build.yml +++ b/.github/workflows/dev-pr-build.yml @@ -99,7 +99,7 @@ jobs: - name: Build GeoBlazor shell: pwsh run: | - ./GeoBlazorBuild.ps1 -xml -pkg -docs -c "Release" + dotnet ./build-tools/GeoBlazorBuild.dll -xml -pkg -docs -c "Release" # Copies the nuget package to the artifacts directory - name: Upload nuget artifact diff --git a/.github/workflows/main-release-build.yml b/.github/workflows/main-release-build.yml index bc1e2eb13..26910c343 100644 --- a/.github/workflows/main-release-build.yml +++ b/.github/workflows/main-release-build.yml @@ -50,7 +50,7 @@ jobs: - name: Build GeoBlazor shell: pwsh run: | - ./GeoBlazorBuild.ps1 -xml -pkg -pub -c "Release" + dotnet ./build-tools/GeoBlazorBuild.dll -xml -pkg -pub -c "Release" # xmllint is a dependency of the copy steps below - name: Install xmllint diff --git a/CLAUDE.md b/CLAUDE.md index b96d9849e..e971b0a6a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,9 +38,9 @@ GeoBlazor is a Blazor component library that brings ArcGIS Maps SDK for JavaScri ### Build ```bash # Clean build of the Core project -pwsh GeoBlazorBuild.ps1 +dotnet ./build-tools/GeoBlazorBuild.dll -# GeoBlazorBuild.ps1 includes lots of options, use -h to see options +-- _`GeoBlazorBuild` includes lots of options, use -h to see options_ # Build entire solution dotnet build src/dymaptic.GeoBlazor.Core.sln @@ -77,7 +77,7 @@ pwsh bumpVersion.ps1 -test 1.2.3 # Test version bump ### Development ```bash # Clear ESBuild locks if build is stuck -pwsh esBuildClearLocks.ps1 +dotnet ./build-tools/ESBuildClearLocks.dll # Watch TypeScript changes (from src/dymaptic.GeoBlazor.Core/) npm run watchBuild diff --git a/Directory.Build.props b/Directory.Build.props index 36f9d9fe7..8dfa8a8e3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,7 +5,7 @@ enable enable - 5.0.0.27 + 5.0.0.37 true Debug;Release;SourceGen Highlighting AnyCPU @@ -23,5 +23,6 @@ + \ No newline at end of file diff --git a/Directory.Build.targets b/Directory.Build.targets index 5a086a0b9..ff2f4fea7 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 55b675c51..832b91c9a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,8 +27,10 @@ COPY ./*.ps1 ./ COPY ./Directory.Build.* ./ COPY ./.gitignore ./.gitignore COPY ./nuget.config ./nuget.config +COPY ./build-tools ./build-tools +COPY ./build-scripts/ScriptBuilder.cs ./build-scripts/ScriptBuilder.cs -RUN pwsh -Command "./GeoBlazorBuild.ps1" +RUN dotnet ./build-tools/GeoBlazorBuild.dll -v current COPY ./test/dymaptic.GeoBlazor.Core.Test.Blazor.Shared/dymaptic.GeoBlazor.Core.Test.Blazor.Shared.csproj ./test/dymaptic.GeoBlazor.Core.Test.Blazor.Shared.csproj COPY ./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp.csproj ./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp.csproj @@ -40,15 +42,14 @@ RUN dotnet restore ./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor COPY ./test/dymaptic.GeoBlazor.Core.Test.Blazor.Shared ./test/dymaptic.GeoBlazor.Core.Test.Blazor.Shared COPY ./test/dymaptic.GeoBlazor.Core.Test.WebApp ./test/dymaptic.GeoBlazor.Core.Test.WebApp -RUN pwsh -Command './buildAppSettings.ps1 \ - -ArcGISApiKey $env:ARCGIS_API_KEY \ - -LicenseKey $env:GEOBLAZOR_LICENSE_KEY \ - -OutputPaths @( \ - "./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp.Client/wwwroot/appsettings.json", \ - "./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp.Client/wwwroot/appsettings.Production.json", \ - "./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp/appsettings.json", \ - "./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp/appsettings.Production.json") \ - -WfsServers $env:WFS_SERVERS' +RUN dotnet ./build-tools/BuildAppSettings.dll \ + -k "$ARCGIS_API_KEY" \ + -l "$GEOBLAZOR_LICENSE_KEY" \ + -o "./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp.Client/wwwroot/appsettings.json" \ + -o "./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp.Client/wwwroot/appsettings.Production.json" \ + -o "./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp/appsettings.json" \ + -o "./test/dymaptic.GeoBlazor.Core.Test.WebApp/dymaptic.GeoBlazor.Core.Test.WebApp/appsettings.Production.json" \ + -w "$WFS_SERVERS" # Build from source with debug symbols for code coverage # UsePackageReference=false builds GeoBlazor from source instead of NuGet diff --git a/GeoBlazorBuild.ps1 b/GeoBlazorBuild.ps1 deleted file mode 100644 index cdf0c34b5..000000000 --- a/GeoBlazorBuild.ps1 +++ /dev/null @@ -1,534 +0,0 @@ -# This is the primary build script for GeoBlazor and GeoBlazor Pro. -param( - [switch]$Pro, - [switch][Alias("pub")]$PublishVersion, - [switch][Alias("obf")]$Obfuscate, - [switch][Alias("docs")]$GenerateDocs, - [switch][Alias("xml")]$GenerateXmlComments, - [switch][Alias("pkg")]$Package, - [switch][Alias("bl")]$Binlog, - [switch][Alias("h")]$Help, - [string][Alias("v")]$Version, - [string][Alias("c")]$Configuration = "Release", - [string][Alias("vc")]$ValidatorConfig = "Release", - [string][Alias("su")]$ServerUrl = "https://licensing.dymaptic.com", - [int][Alias("retries")]$BuildRetries = 5) - -if ($Help) { - Write-Host "GeoBlazor Build Script" - Write-Host "" - Write-Host "Parameters:" - Write-Host " -Pro (-pro) Build GeoBlazor Pro as well as Core (default is false)" - Write-Host " -PublishVersion (-pub) Truncate the build version to 3 digits for NuGet (default is false)" - Write-Host " -Obfuscate (-obf) Obfuscate the Pro license validation logic (default is false)" - Write-Host " -GenerateDocs (-docs) Generate documentation files for the docs site (default is false)" - Write-Host " -GenerateXmlComments (-xml) Generate the XML comments that provide intellisense when using the library in an IDE" - Write-Host " -Package (-pkg) Create NuGet packages (default is false)" - Write-Host " -Binlog (-bl) Generate MSBuild binary log files (default is false)" - Write-Host " -Version (-v) Specify a custom version number (default is to auto-increment the current build version)" - Write-Host " -Configuration (-c) Build configuration (default is 'Release')" - Write-Host " -ValidatorConfig (-v) Validator build configuration (default is 'Release')" - Write-Host " -ServerUrl (-su) License server URL (default is 'https://licensing.dymaptic.com')" - Write-Host " -BuildRetries (-retries) Number of times to retry the build on failure (default is 5)" - Write-Host " -Help (-h) Display this help message" - exit 0 -} - -if ($GenerateDocs) { - $GenerateXmlComments = $true -} - -Write-Host "Starting GeoBlazor Build Script" -Write-Host "Pro Build: $Pro" -Write-Host "Set Nuget Publish Version Build: $PublishVersion" -Write-Host "Obfuscate Pro Build: $Obfuscate" -Write-Host "Generate Documentation Files: $GenerateDocs" -Write-Host "Generate XML Documentation: $GenerateXmlComments" -Write-Host "Build Package: $($Package -eq $true)" -Write-Host "Version: $Version" -Write-Host "Configuration: $Configuration" -Write-Host "Validator Configuration: $ValidatorConfig" -Write-Host "License Server URL: $ServerUrl" - -$scriptStartTime = Get-Date - -$CoreRepoRoot = $PSScriptRoot -$ProRepoRoot = (Join-Path -Path $PSScriptRoot "..") -$BinlogFlag = $Binlog ? ' -bl' : '' - -try { - ## Paths - $CorePropsPath = Join-Path -Path $CoreRepoRoot "Directory.Build.props" - $CoreProjectPath = Join-Path -Path $CoreRepoRoot "src/dymaptic.GeoBlazor.Core" - $ProPropsPath = Join-Path -Path $ProRepoRoot "Directory.Build.props" - $ProProjectPath = Join-Path -Path $ProRepoRoot "src/dymaptic.GeoBlazor.Pro" - $ValidatorProjectPath = Join-Path -Path $ProRepoRoot "src/dymaptic.GeoBlazor.Pro.Validator" - $AssetsPath = Join-Path -Path $CoreProjectPath "wwwroot/assets" - $BuildScriptsPath = Join-Path -Path $CoreRepoRoot "build" - - $OtherConfiguration = if ($Configuration.ToLowerInvariant() -eq "release") { "Debug" } else { "Release" } - - # Set up locks - $CoreLockFilePath = Join-Path -Path $CoreProjectPath "esBuild.$OtherConfiguration.lock" - $ProLockFilePath = Join-Path -Path $ProProjectPath "esProBuild.$OtherConfiguration.lock" - - if ((Test-Path $CoreLockFilePath) -or (Test-Path $ProLockFilePath)) { - # wait for the lock to be released - Write-Host "Another instance of the esBuild scripts are already running, please wait." - while ((Test-Path $CoreLockFilePath) -or (Test-Path $ProLockFilePath)) { - Start-Sleep -Seconds 1 - Write-Host -NoNewline "." - if ($scriptStartTime.AddMinutes(1) -lt (Get-Date)) { - if (Test-Path $CoreLockFilePath) { - Write-Host "`nLock file $CoreLockFilePath still exists after 1 minute, removing stale lock." - Remove-Item -Path $CoreLockFilePath -Force - } - if (Test-Path $ProLockFilePath) { - Write-Host "`nLock file $ProLockFilePath still exists after 1 minute, removing stale lock." - Remove-Item -Path $ProLockFilePath -Force - } - } - } - Write-Host "Lock released, continuing..." - } - - ## Create lock files to prevent multiple instances of the script from running at the same time - New-Item -Path $CoreLockFilePath - if ($Pro -eq $true) { - New-Item -Path $ProLockFilePath - } - - # Set Environment Variables - $env:PipelineBuild = "true" - - $Step = 1 - - ## Clean out old build artifacts - $StepStartTime = Get-Date - Write-Host "" - Write-Host "$Step. Cleaning old build artifacts" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - dotnet clean (Join-Path $CoreProjectPath dymaptic.GeoBlazor.Core.csproj) /p:PipelineBuild=true - Remove-Item -Path (Join-Path $CoreProjectPath "bin") -Recurse -Force - Remove-Item -Path (Join-Path $CoreProjectPath "obj") -Recurse -Force - if (Test-Path (Join-Path $CoreProjectPath "wwwroot/js")) { - Get-ChildItem -Path (Join-Path $CoreProjectPath "wwwroot/js") -Recurse -Force | Remove-Item -Recurse -Force - } - if (Test-Path (Join-Path $CoreProjectPath "node_modules")) { - Remove-Item (Join-Path $CoreProjectPath "node_modules") -Recurse -Force - } - - if ($Pro -eq $true) { - dotnet clean (Join-Path $ProProjectPath dymaptic.GeoBlazor.Pro.csproj) /p:PipelineBuild=true - Remove-Item -Path (Join-Path $ProProjectPath "bin") -Recurse -Force - Remove-Item -Path (Join-Path $ProProjectPath "obj") -Recurse -Force - Get-ChildItem -Path (Join-Path $ProProjectPath "obf") -Recurse -Force | Remove-Item -Recurse -Force - if (Test-Path (Join-Path $ProProjectPath "build/resources")) { - Get-ChildItem -Path (Join-Path $ProProjectPath "build/resources") -Recurse -Force | Remove-Item -Recurse -Force - } - if (Test-Path (Join-Path $ProProjectPath "wwwroot/js")) { - Get-ChildItem -Path (Join-Path $ProProjectPath "wwwroot/js") -Recurse -Force | Remove-Item -Recurse -Force - } - if (Test-Path (Join-Path $ProProjectPath "node_modules")) { - Remove-Item -Path (Join-Path $ProProjectPath "node_modules") -Recurse -Force - } - if (Test-Path $ValidatorProjectPath) { - dotnet clean (Join-Path $ValidatorProjectPath dymaptic.GeoBlazor.Pro.V.csproj) - Remove-Item -Path (Join-Path $ValidatorProjectPath "bin") -Recurse -Force - Remove-Item -Path (Join-Path $ValidatorProjectPath "obj") -Recurse -Force - Get-ChildItem -Path (Join-Path $ValidatorProjectPath "obf") -Recurse -Force | Remove-Item -Recurse -Force - } - - } - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - - $Step++ - - $CustomVersionSet = $null -ne $Version -and $Version -ne "" - - if ($CustomVersionSet -ne $true) { - $StepStartTime = Get-Date - Set-Location $CoreRepoRoot - - ## Set the version number in Directory.Build.props - Write-Host "" - Write-Host "$Step. Updating Library Versions" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - - [xml]$CoreProps = [xml](Get-Content $CorePropsPath) - $CurrentCoreVersion = $CoreProps.Project.PropertyGroup.CoreVersion - - if ($PublishVersion) { - $NewCoreVersion = ./bumpVersion.ps1 -publish - } else { - $NewCoreVersion = ./bumpVersion.ps1 - } - - if ($Pro -eq $true) { - [xml]$ProProps = [xml](Get-Content $ProPropsPath) - $CurrentProVersion = $ProProps.Project.PropertyGroup.ProVersion - - if ($PublishVersion) { - $Version = ./bumpVersion.ps1 -publish -pro - } else { - $Version = ./bumpVersion.ps1 -pro - } - - if ($NewCoreVersion -gt $Version -and $CurrentCoreVersion -gt $CurrentProVersion) { - $Version = $NewCoreVersion - } elseif ($NewCoreVersion -lt $Version) { - "Core version ($NewCoreVersion) and Pro version ($Version) do not match after bumping. Please ensure both versions are the same in Directory.Build.props." - } - - if ($CurrentProVersion -eq $Version) { - Write-Host "Pro Version is already set to $Version, no update needed." - } - else - { - Write-Host "Updating Pro Version from $CurrentProVersion to $Version" - $ProProps.Project.PropertyGroup.ProVersion = $Version - $ProProps.Save($ProPropsPath) - } - } else { - $Version = $NewCoreVersion - } - - if ($CurrentCoreVersion -eq $Version) { - Write-Host "Core Version is already set to $Version, no update needed." - } - else { - Write-Host "Updating Core Version from $CurrentCoreVersion to $Version" - $CoreProps.Project.PropertyGroup.CoreVersion = $Version - $CoreProps.Save($CorePropsPath) - } - - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - - $Step++ - } - - $StepStartTime = Get-Date - - $CoreLockFilePath = Join-Path -Path $CoreProjectPath "esBuild.$Configuration.lock" - - $Locked = $null -ne (Get-Item -Path $CoreLockFilePath -EA 0) - - if ($Locked) { - # wait for the lock to be released - Write-Host "Another instance of the esBuild script is already running, please wait." - while (Test-Path $CoreLockFilePath) { - Start-Sleep -Seconds 1 - Write-Host -NoNewline "." - } - Write-Host "Lock released, continuing..." - } - - Set-Location $BuildScriptsPath - - Write-Host "" - Write-Host "$Step. Building Core JavaScript" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - dotnet run ESBuild.cs -- -c $Configuration - if ($LASTEXITCODE -ne 0) { - Write-Host "ERROR: esBuild.ps1 failed with exit code $LASTEXITCODE. Exiting." -ForegroundColor Red - exit 1 - } - - # Verify JavaScript files were created - $CoreJsPath = Join-Path -Path $CoreProjectPath "wwwroot/js" - if (-not (Test-Path $CoreJsPath) -or (Get-ChildItem -Path $CoreJsPath -Filter "*.js" | Measure-Object).Count -eq 0) { - Write-Host "WARNING: Core JavaScript files not found at $CoreJsPath, waiting..." -ForegroundColor Yellow - Start-Sleep -Seconds 2 - if (-not (Test-Path $CoreJsPath) -or (Get-ChildItem -Path $CoreJsPath -Filter "*.js" | Measure-Object).Count -eq 0) { - Write-Host "ERROR: Core JavaScript files still not found after waiting. Exiting." -ForegroundColor Red - exit 1 - } - } - - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - - $Step++ - - Set-Location $CoreProjectPath - - $StepStartTime = Get-Date - Write-Host "" - Write-Host "$Step. Restoring .Net Packages" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - dotnet restore /p:PipelineBuild=true - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - - $Step++ - - $StepStartTime = Get-Date - Write-Host "" - Write-Host "$Step. Building Core Project and NuGet Package" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - - # double-escape line breaks - $CoreBuild = "dotnet build dymaptic.GeoBlazor.Core.csproj --no-restore `` - -c $Configuration `` - /p:PipelineBuild=true `` - /p:GenerateDocs=$($GenerateDocs.ToString().ToLower()) `` - /p:GenerateXmlComments=$($GenerateXmlComments.ToString().ToLower()) `` - /p:CoreVersion=$Version `` - /p:GeneratePackage=$($Package.ToString().ToLower()) $BinlogFlag 2>&1" - Write-Host "Executing '$CoreBuild'" - - # sometimes the build fails due to a Microsoft bug, retry a few times - for ($i = 1; $i -lt $BuildRetries; $i++) { - try - { - Invoke-Expression $CoreBuild | Tee-Object -Variable Build - if ($LASTEXITCODE -ne 0) { - Write-Host "ERROR: Core Build command failed with exit code $LASTEXITCODE. Exiting." - $HasError = true - } else { - $HasError = (($Build -match "[1-9][0-9]* [Ee]rror(s)") -or ($Build -match "Build FAILED")) - if ($HasError -eq $false) - { - break - } - } - } - catch - { - $HasError = $true - Write-Host "Build attempt $i of $BuildRetries failed with exception: $_" - } - - Write-Host "Build attempt $i of $BuildRetries failed." - if ($i -lt $BuildRetries -1) - { - Write-Host "Waiting 2 seconds before retrying..." - Start-Sleep -Seconds 2 - } - } - - if ($HasError -eq $true) - { - exit 1 - } - - if ($Package -eq $true) { - # Copy generated NuGet package to script root - $CoreNupkg = Get-ChildItem -Path "bin/$Configuration" -Filter "*.nupkg" -Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 1 - if ($CoreNupkg) { - Copy-Item -Path $CoreNupkg.FullName -Destination $CoreRepoRoot -Force - Write-Host "Copied $($CoreNupkg.Name) to $CoreRepoRoot" - } - } - - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - - $Step++ - - if ($Pro -eq $true) { - Set-Location $ProProjectPath - - $StepStartTime = Get-Date - Write-Host "" - Write-Host "$Step. Restoring .NET Packages" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - dotnet restore /p:PipelineBuild=true - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - - $Step++ - - # Set OptOutFromObfuscation before building Validator or Pro (needed for both) - $OptOutFromObfuscation = $Obfuscate -eq $false - - if (Test-Path $ValidatorProjectPath) { - ## Build the Validator MSBuild task - $StepStartTime = Get-Date - Set-Location $ValidatorProjectPath - Write-Host "" - Write-Host "$Step. Building Validator project in configuration $ValidatorConfig" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - - # Set the ServerUrls in the Validator project - $ServerUrl = $ServerUrl.TrimEnd('/') - Write-Host "Setting License Server Url to $ServerUrl" - $ValidatorContent = Get-Content 'DevBuildValidator.cs' -Raw; - $ValidatorContent = $ValidatorContent -replace 'public string SU \{ get; set; \} = null!;', "public string SU { get; set; } = `"$ServerUrl/api/validate/v4`";" - Set-Content 'DevBuildValidator.cs' -Value $ValidatorContent -NoNewline -Force -Encoding UTF8 - if ($IsMacOS) { - & sync - } - Start-Sleep -Milliseconds 500 - $ValidatorContent = Get-Content 'DevBuildValidator.cs' -Raw; - if ($ValidatorContent -notmatch [regex]::Escape("public string SU { get; set; } = `"$ServerUrl/api/validate/v4`";")) { - throw "Failed to set ServerUrl in DevBuildValidator.cs" - } - $ValidatorContent = Get-Content 'PublishTaskValidator.cs' -Raw; - $ValidatorContent = $ValidatorContent -replace 'public string SU \{ get; set; \} = null!;', "public string SU { get; set; } = `"$ServerUrl/api/validate/v4/publish`";" - Set-Content 'PublishTaskValidator.cs' -Value $ValidatorContent -NoNewline -Force -Encoding UTF8 - if ($IsMacOS) { - & sync - } - Start-Sleep -Milliseconds 500 - $ValidatorContent = Get-Content 'PublishTaskValidator.cs' -Raw; - if ($ValidatorContent -notmatch [regex]::Escape("public string SU { get; set; } = `"$ServerUrl/api/validate/v4/publish`";")) { - throw "Failed to set ServerUrl in PublishTaskValidator.cs" - } - - dotnet build dymaptic.GeoBlazor.Pro.V.csproj /p:OptOutFromObfuscation=$($OptOutFromObfuscation.ToString().ToLower()) ` - /p:ProVersion=$Version -c $ValidatorConfig $BinlogFlag 2>&1 | Tee-Object -Variable Build - - # Restore the ServerUrls in the Validator project - $ValidatorContent = Get-Content 'DevBuildValidator.cs' -Raw; - $ValidatorContent = $ValidatorContent -replace 'public string SU \{ get; set; \} = ".*";', 'public string SU { get; set; } = null!;' - Set-Content 'DevBuildValidator.cs' -Value $ValidatorContent -NoNewline - $ValidatorContent = Get-Content 'PublishTaskValidator.cs' -Raw; - $ValidatorContent = $ValidatorContent -replace 'public string SU \{ get; set; \} = ".*";', 'public string SU { get; set; } = null!;' - Set-Content 'PublishTaskValidator.cs' -Value $ValidatorContent -NoNewline - $HasError = (($Build -match "[1-9][0-9]* [Ee]rror(s)") -or ($Build -match "Build FAILED")) - if ($HasError -eq $true) { - exit 1 - } - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - - $Step++ - } - - Set-Location $ProProjectPath - - $StepStartTime = Get-Date - - if (Test-Path $ProLockFilePath) { - # wait for the lock to be released - Write-Host "Another instance of the esBuild scripts are already running, please wait." - while (Test-Path $ProLockFilePath) { - Start-Sleep -Seconds 1 - Write-Host -NoNewline "." - } - Write-Host "Lock released, continuing..." - } - - Set-Location $BuildScriptsPath - - Write-Host "" - Write-Host "$Step. Building Pro JavaScript" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - dotnet run ESBuild.cs -- -c $Configuration --pro - if ($LASTEXITCODE -ne 0) { - Write-Host "ERROR: esProBuild.ps1 failed with exit code $LASTEXITCODE. Exiting." -ForegroundColor Red - exit 1 - } - - # Verify JavaScript files were created - $ProJsPath = Join-Path -Path $ProProjectPath "wwwroot/js" - if (-not (Test-Path $ProJsPath) -or (Get-ChildItem -Path $ProJsPath -Filter "*.js" | Measure-Object).Count -eq 0) { - Write-Host "WARNING: Pro JavaScript files not found at $ProJsPath, waiting..." -ForegroundColor Yellow - Start-Sleep -Seconds 2 - if (-not (Test-Path $ProJsPath) -or (Get-ChildItem -Path $ProJsPath -Filter "*.js" | Measure-Object).Count -eq 0) { - Write-Host "ERROR: Pro JavaScript files still not found after waiting. Exiting." -ForegroundColor Red - exit 1 - } - } - - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - - $Step++ - - $StepStartTime = Get-Date - Write-Host "" - Write-Host "$Step. Building Pro project and package" -BackgroundColor DarkMagenta -ForegroundColor White -NoNewline - Write-Host "" - Write-Host "" - - Set-Location $ProProjectPath - - # double-escape line breaks - $ProBuild = "dotnet build dymaptic.GeoBlazor.Pro.csproj --no-restore `` - -c $Configuration `` - /p:PipelineBuild=true `` - /p:GenerateDocs=$($GenerateDocs.ToString().ToLower()) `` - /p:GenerateXmlComments=$($GenerateXmlComments.ToString().ToLower()) `` - /p:CoreVersion=$Version `` - /p:ProVersion=$Version `` - /p:OptOutFromObfuscation=$($OptOutFromObfuscation.ToString().ToLower()) `` - /p:GeneratePackage=$($Package.ToString().ToLower()) $BinlogFlag 2>&1" - Write-Host "Executing '$ProBuild'" - - # sometimes the build fails due to a Microsoft bug, retry a few times - for ($i = 1; $i -lt $BuildRetries; $i++) { - try - { - Invoke-Expression $ProBuild | Tee-Object -Variable Build - if ($LASTEXITCODE -ne 0) { - Write-Host "ERROR: Pro Build command failed with exit code $LASTEXITCODE. Exiting." - $HasError = true - } else { - $HasError = (($Build -match "[1-9][0-9]* [Ee]rror(s)") -or ($Build -match "Build FAILED")) - if ($HasError -eq $false) - { - break - } - } - } - catch - { - $HasError = $true - Write-Host "Build attempt $i of $BuildRetries failed with exception: $_" - } - - Write-Host "Build attempt $i of $BuildRetries failed." - if ($i -lt $BuildRetries -1) - { - Write-Host "Waiting 2 seconds before retrying..." - Start-Sleep -Seconds 2 - } - } - - if ($HasError -eq $true) - { - exit 1 - } - - if ($Package -eq $true) { - # Copy generated NuGet package to script root - $ProNupkg = Get-ChildItem -Path "bin/$Configuration" -Filter "*.nupkg" -Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 1 - if ($ProNupkg) { - Copy-Item -Path $ProNupkg.FullName -Destination $CoreRepoRoot -Force - Write-Host "Copied $($ProNupkg.Name) to $CoreRepoRoot" - } - } - - Write-Host "Step $Step completed in $( (Get-Date) - $StepStartTime )." -BackgroundColor Yellow -ForegroundColor Black -NoNewline - Write-Host "" - } -} -catch { - Write-Host "An error occurred: $_" - exit 1 -} -finally { - $totalTime = (Get-Date) - $scriptStartTime - # Remove lock files - if (Test-Path $CoreLockFilePath) { - Remove-Item -Path $CoreLockFilePath -Force - } - if (Test-Path $ProLockFilePath) { - Remove-Item -Path $ProLockFilePath -Force - } - Write-Host "" - Write-Host "Total script execution time: $totalTime." -BackgroundColor DarkBlue -ForegroundColor White - Set-Location $PSScriptRoot -} diff --git a/badge_fullmethodcoverage.svg b/badge_fullmethodcoverage.svg index f6b93c7c9..f80e7c08e 100644 --- a/badge_fullmethodcoverage.svg +++ b/badge_fullmethodcoverage.svg @@ -132,7 +132,7 @@ - 0.2%0.2% + 3%3% diff --git a/badge_linecoverage.svg b/badge_linecoverage.svg index 5f9dbf31d..24ecd11fc 100644 --- a/badge_linecoverage.svg +++ b/badge_linecoverage.svg @@ -123,7 +123,7 @@ Coverage Coverage - 0.2%0.2% + 1.3%1.3% diff --git a/badge_methodcoverage.svg b/badge_methodcoverage.svg index 7c1588d9d..f06ecb44c 100644 --- a/badge_methodcoverage.svg +++ b/badge_methodcoverage.svg @@ -125,7 +125,7 @@ Coverage - 0.2%0.2% + 3.2%3.2% diff --git a/build-scripts/BuildAppSettings.cs b/build-scripts/BuildAppSettings.cs new file mode 100644 index 000000000..b0ea8c79e --- /dev/null +++ b/build-scripts/BuildAppSettings.cs @@ -0,0 +1,181 @@ +#!/usr/bin/env dotnet + +// Build AppSettings Script +// C# file-based app version of buildAppSettings.ps1 +// Generates appsettings.json files for test applications. +// +// Usage: dotnet BuildAppSettings.cs [options] +// -k, --api-key ArcGIS API key (required) +// -l, --license-key GeoBlazor license key (required) +// -o, --output Output path(s) for appsettings.json (required, can specify multiple) +// -d, --docs-url Documentation URL (default: https://docs.geoblazor.com) +// -b, --bypass-key API bypass key for samples (optional) +// -w, --wfs-servers Additional WFS server configuration JSON fragment (optional) +// -h, --help Display help message +// +// Example: +// dotnet BuildAppSettings.cs -k "your-arcgis-key" -l "your-license" -o "./appsettings.json" +// dotnet BuildAppSettings.cs -k "key" -l "license" -o "./app1/appsettings.json" -o "./app2/appsettings.json" + +using System.Text; + +string? arcGISApiKey = null; +string? licenseKey = null; +List outputPaths = []; +string docsUrl = "https://docs.geoblazor.com"; +string byPassApiKey = ""; +string wfsServers = ""; +bool help = false; + +// Parse command line arguments +for (int i = 0; i < args.Length; i++) +{ + string arg = args[i]; + switch (arg.ToLowerInvariant()) + { + case "-k": + case "--api-key": + if (i + 1 < args.Length) + { + arcGISApiKey = args[++i]; + } + break; + case "-l": + case "--license-key": + if (i + 1 < args.Length) + { + licenseKey = args[++i]; + } + break; + case "-o": + case "--output": + if (i + 1 < args.Length) + { + outputPaths.Add(args[++i]); + } + break; + case "-d": + case "--docs-url": + if (i + 1 < args.Length) + { + docsUrl = args[++i]; + } + break; + case "-b": + case "--bypass-key": + if (i + 1 < args.Length) + { + byPassApiKey = args[++i]; + } + break; + case "-w": + case "--wfs-servers": + if (i + 1 < args.Length) + { + wfsServers = args[++i]; + } + break; + case "-h": + case "--help": + help = true; + break; + } +} + +if (help) +{ + Console.WriteLine("Build AppSettings Script"); + Console.WriteLine("Generates appsettings.json files for test applications."); + Console.WriteLine(); + Console.WriteLine("Usage: dotnet BuildAppSettings.cs [options]"); + Console.WriteLine(); + Console.WriteLine("Options:"); + Console.WriteLine(" -k, --api-key ArcGIS API key (required)"); + Console.WriteLine(" -l, --license-key GeoBlazor license key (required)"); + Console.WriteLine(" -o, --output Output path(s) for appsettings.json (required, can specify multiple)"); + Console.WriteLine(" -d, --docs-url Documentation URL (default: https://docs.geoblazor.com)"); + Console.WriteLine(" -b, --bypass-key API bypass key for samples (optional)"); + Console.WriteLine(" -w, --wfs-servers Additional WFS server configuration JSON fragment (optional)"); + Console.WriteLine(" -h, --help Display this help message"); + Console.WriteLine(); + Console.WriteLine("Examples:"); + Console.WriteLine(" dotnet BuildAppSettings.cs -k \"your-arcgis-key\" -l \"your-license\" -o \"./appsettings.json\""); + Console.WriteLine(" dotnet BuildAppSettings.cs -k \"key\" -l \"license\" -o \"./app1/appsettings.json\" -o \"./app2/appsettings.json\""); + return 0; +} + +// Validate required parameters +if (string.IsNullOrWhiteSpace(arcGISApiKey)) +{ + Console.Error.WriteLine("Error: ArcGIS API key is required. Use -k or --api-key to specify."); + return 1; +} + +if (string.IsNullOrWhiteSpace(licenseKey)) +{ + Console.Error.WriteLine("Error: GeoBlazor license key is required. Use -l or --license-key to specify."); + return 1; +} + +if (outputPaths.Count == 0) +{ + Console.Error.WriteLine("Error: At least one output path is required. Use -o or --output to specify."); + return 1; +} + +// Build the appsettings JSON content +var sb = new StringBuilder(); +sb.AppendLine("{"); +sb.AppendLine($" \"ArcGISApiKey\": \"{EscapeJsonString(arcGISApiKey)}\","); +sb.AppendLine(" \"GeoBlazor\": {"); +sb.AppendLine($" \"LicenseKey\": \"{EscapeJsonString(licenseKey)}\""); +sb.AppendLine(" },"); +sb.AppendLine($" \"DocsUrl\": \"{EscapeJsonString(docsUrl)}\","); +sb.Append($" \"ByPassApiKey\": \"{EscapeJsonString(byPassApiKey)}\""); + +// Add WFS servers if provided +if (!string.IsNullOrWhiteSpace(wfsServers)) +{ + sb.AppendLine(","); + sb.Append($" {wfsServers}"); +} + +sb.AppendLine(); +sb.AppendLine("}"); + +string appSettingsContent = sb.ToString(); + +// Write to each target path +foreach (string path in outputPaths) +{ + try + { + string? directory = Path.GetDirectoryName(path); + if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + File.WriteAllText(path, appSettingsContent, Encoding.UTF8); + Console.WriteLine($"Created: {path}"); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Error writing to {path}: {ex.Message}"); + return 1; + } +} + +Console.WriteLine("AppSettings files generated successfully."); +return 0; + +// Helper function to escape JSON string values +static string EscapeJsonString(string value) +{ + return value + .Replace("\\", "\\\\") + .Replace("\"", "\\\"") + .Replace("\n", "\\n") + .Replace("\r", "\\r") + .Replace("\t", "\\t"); +} diff --git a/build-scripts/BuildTemplates.cs b/build-scripts/BuildTemplates.cs new file mode 100644 index 000000000..82e25da6c --- /dev/null +++ b/build-scripts/BuildTemplates.cs @@ -0,0 +1,609 @@ +#!/usr/bin/env dotnet +#:property PublishAot=false + +// Build Templates Script +// C# file-based app version of buildTemplates.ps1 +// Updates and builds GeoBlazor project templates +// +// Usage: dotnet BuildTemplates.cs [options] +// -i, --install Install templates after building +// -c, --core-version Override Core version (default: read from Directory.Build.props) +// -p, --pro-version Override Pro version (default: read from Directory.Build.props) +// -t, --templates-dir Templates directory (default: auto-detect from script location) +// -h, --help Display help message +// +// Example: +// dotnet BuildTemplates.cs +// dotnet BuildTemplates.cs -i +// dotnet BuildTemplates.cs -c 5.0.0 -p 5.0.0 -i + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.RegularExpressions; +using System.Xml.Linq; + +// Target frameworks to support +int[] targetFrameworks = [8, 9, 10]; + +// Package definitions +string[] packages = +[ + "Microsoft.Maui.Controls", + "Microsoft.AspNetCore.Components.WebView.Maui", + "Microsoft.Extensions.Configuration.Abstractions", + "Microsoft.Extensions.Logging.Debug", + "Microsoft.AspNetCore.Components.Web", + "Microsoft.AspNetCore.Components.WebAssembly.Server", + "Microsoft.AspNetCore.Components.WebAssembly", + "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore", + "Microsoft.AspNetCore.Identity.EntityFrameworkCore", + "Microsoft.EntityFrameworkCore.Tools", + "Microsoft.EntityFrameworkCore.SqlServer", + "Microsoft.AspNetCore.Components.WebAssembly.Authentication", + "Microsoft.AspNetCore.Components.WebAssembly.DevServer", + "Microsoft.Authentication.WebAssembly.Msal" +]; + +// Package to symbol name mapping +Dictionary packageToSymbol = new() +{ + ["Microsoft.Maui.Controls"] = "MauiControls", + ["Microsoft.AspNetCore.Components.WebView.Maui"] = "WebViewMaui", + ["Microsoft.Extensions.Configuration.Abstractions"] = "ConfigurationAbstractions", + ["Microsoft.Extensions.Logging.Debug"] = "LoggingDebug", + ["Microsoft.AspNetCore.Components.Web"] = "ComponentsWeb", + ["Microsoft.AspNetCore.Components.WebAssembly.Server"] = "WebAssemblyServer", + ["Microsoft.AspNetCore.Components.WebAssembly"] = "ComponentsWebAssembly", + ["Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore"] = "DiagnosticsEntityFrameworkCore", + ["Microsoft.AspNetCore.Identity.EntityFrameworkCore"] = "IdentityEntityFrameworkCore", + ["Microsoft.EntityFrameworkCore.Tools"] = "EntityFrameworkCoreTools", + ["Microsoft.EntityFrameworkCore.SqlServer"] = "EntityFrameworkCoreSqlServer", + ["Microsoft.AspNetCore.Components.WebAssembly.Authentication"] = "WebAssemblyAuthentication", + ["Microsoft.AspNetCore.Components.WebAssembly.DevServer"] = "WebAssemblyDevServer", + ["Microsoft.Authentication.WebAssembly.Msal"] = "WebAssemblyMsal" +}; + +// Parse command line arguments +bool install = false; +string? coreVersionOverride = null; +string? proVersionOverride = null; +string? templatesDirOverride = null; +bool help = false; + +for (int i = 0; i < args.Length; i++) +{ + string arg = args[i].ToLowerInvariant(); + switch (arg) + { + case "-i": + case "--install": + install = true; + break; + case "-c": + case "--core-version": + if (i + 1 < args.Length) + { + coreVersionOverride = args[++i]; + } + break; + case "-p": + case "--pro-version": + if (i + 1 < args.Length) + { + proVersionOverride = args[++i]; + } + break; + case "-t": + case "--templates-dir": + if (i + 1 < args.Length) + { + templatesDirOverride = args[++i]; + } + break; + case "-h": + case "--help": + help = true; + break; + } +} + +if (help) +{ + Console.WriteLine("Build Templates Script"); + Console.WriteLine("Updates and builds GeoBlazor project templates."); + Console.WriteLine(); + Console.WriteLine("Usage: dotnet BuildTemplates.cs [options]"); + Console.WriteLine(); + Console.WriteLine("Options:"); + Console.WriteLine(" -i, --install Install templates after building"); + Console.WriteLine(" -c, --core-version Override Core version"); + Console.WriteLine(" -p, --pro-version Override Pro version"); + Console.WriteLine(" -t, --templates-dir Templates directory path"); + Console.WriteLine(" -h, --help Display this help message"); + Console.WriteLine(); + Console.WriteLine("Examples:"); + Console.WriteLine(" dotnet BuildTemplates.cs"); + Console.WriteLine(" dotnet BuildTemplates.cs -i"); + Console.WriteLine(" dotnet BuildTemplates.cs -c 5.0.0 -p 5.0.0 -i"); + return 0; +} + +string currentDir = Environment.CurrentDirectory; +string scriptDir = GetScriptDirectory(); + +// Determine templates directory +string templatesDir = templatesDirOverride ?? Path.GetFullPath(Path.Combine(scriptDir, "..", "..", "templates")); + +if (!Directory.Exists(templatesDir)) +{ + Console.Error.WriteLine($"Error: Templates directory not found at {templatesDir}"); + return 1; +} + +// Determine versions +string coreVersion = coreVersionOverride ?? string.Empty; +string proVersion = proVersionOverride ?? string.Empty; + +if (string.IsNullOrEmpty(coreVersion) || string.IsNullOrEmpty(proVersion)) +{ + string buildPropsPath = Path.Combine(templatesDir, "..", "Directory.Build.props"); + if (!File.Exists(buildPropsPath)) + { + Console.Error.WriteLine($"Error: Directory.Build.props not found at {buildPropsPath}"); + return 1; + } + + var buildProps = XDocument.Load(buildPropsPath); + string? propsVersion = buildProps.Descendants("ProVersion").FirstOrDefault()?.Value; + + if (string.IsNullOrEmpty(propsVersion)) + { + Console.Error.WriteLine("Error: Could not read ProVersion from Directory.Build.props"); + return 1; + } + + // Use ProVersion for both Core and Pro (intentional - they should match for production releases) + if (string.IsNullOrEmpty(coreVersion)) + { + coreVersion = propsVersion; + } + if (string.IsNullOrEmpty(proVersion)) + { + proVersion = propsVersion; + } +} + +Console.WriteLine("Updating GeoBlazor Templates"); +Console.WriteLine($"- Using Core Version: {coreVersion}"); +Console.WriteLine($"- Using Pro Version: {proVersion}"); +Console.WriteLine(); + +// Find all .csproj files in content folder +string contentDir = Path.Combine(templatesDir, "content"); +string[] projectFiles = Directory.GetFiles(contentDir, "*.csproj", SearchOption.AllDirectories); + +Console.WriteLine("Updating Project References in .csproj files"); + +// Use a 3-piece version for the package ref to make sure it references an actually deployed nuget version +string packageVersion = Regex.Replace(proVersion, @"^(\d+\.\d+\.\d+)\.\d+(.*)$", "$1$2"); + +foreach (string projectFile in projectFiles) +{ + string content = File.ReadAllText(projectFile); + string originalContent = content; + + // Update GeoBlazor Core and Pro versions + content = Regex.Replace(content, + @">(); +using var httpClient = new HttpClient(); +httpClient.DefaultRequestHeaders.Add("User-Agent", "GeoBlazor-Build-Script"); + +foreach (string package in packages) +{ + try + { + Console.WriteLine($"Getting versions for {package}..."); + var versions = await GetPackageVersionsAsync(httpClient, package, targetFrameworks); + packageVersionsCache[package] = versions; + foreach (int tf in targetFrameworks) + { + Console.WriteLine($" Found: net{tf}.0 = {versions[tf] ?? "(none)"}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Error getting versions for package {package}: {ex.Message}"); + } +} + +// Update template.json files +Console.WriteLine(); +Console.WriteLine("Updating package versions in template.json files"); + +var templateConfigDirs = Directory.GetDirectories(contentDir, ".template.config", SearchOption.AllDirectories); +foreach (string configDir in templateConfigDirs) +{ + string templateJsonPath = Path.Combine(configDir, "template.json"); + if (!File.Exists(templateJsonPath)) + { + continue; + } + + Console.WriteLine($"Processing {templateJsonPath}"); + + string jsonText = File.ReadAllText(templateJsonPath); + bool modified = false; + + // Parse JSON as mutable DOM + JsonNode? rootNode = JsonNode.Parse(jsonText, documentOptions: new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip }); + if (rootNode is not JsonObject root) + { + Console.WriteLine(" Failed to parse JSON, skipping"); + continue; + } + + JsonObject? symbols = root["symbols"]?.AsObject(); + if (symbols is null) + { + Console.WriteLine(" No symbols section found, skipping"); + continue; + } + + int latestTf = targetFrameworks[^1]; + + // 1. Handle Framework symbol - add missing choices and update default + JsonObject? frameworkSymbol = symbols["Framework"]?.AsObject(); + if (frameworkSymbol is not null) + { + // Add missing framework choices + JsonArray? choices = frameworkSymbol["choices"]?.AsArray(); + if (choices is not null) + { + foreach (int tf in targetFrameworks) + { + string choiceValue = $"net{tf}.0"; + bool exists = choices.Any(c => c?["choice"]?.GetValue() == choiceValue); + if (!exists) + { + choices.Add(new JsonObject { ["choice"] = choiceValue }); + modified = true; + Console.WriteLine($" Added missing framework choice: {choiceValue}"); + } + } + } + + // Update default framework to latest + string? currentDefault = frameworkSymbol["defaultValue"]?.GetValue(); + string newDefault = $"net{latestTf}.0"; + if (currentDefault != newDefault) + { + frameworkSymbol["defaultValue"] = newDefault; + modified = true; + Console.WriteLine($" Updated default framework to {newDefault}"); + } + } + + // 2. Update package versions in cases for each package symbol + foreach (string package in packages) + { + if (!packageToSymbol.TryGetValue(package, out string? symbolName)) + { + continue; + } + + var versions = packageVersionsCache.GetValueOrDefault(package); + if (versions is null) + { + continue; + } + + // Check if this symbol exists in the template + JsonObject? packageSymbol = symbols[symbolName]?.AsObject(); + if (packageSymbol is null) + { + continue; + } + + // Get the cases array from parameters + JsonObject? parameters = packageSymbol["parameters"]?.AsObject(); + if (parameters is null) + { + continue; + } + + JsonArray? cases = parameters["cases"]?.AsArray(); + if (cases is null) + { + continue; + } + + foreach (int tf in targetFrameworks) + { + string? version = versions[tf]; + if (version is null) + { + continue; + } + + string condition = $"(Framework == \"net{tf}.0\")"; + + // Find existing case for this framework + JsonObject? existingCase = null; + foreach (var caseNode in cases) + { + if (caseNode is JsonObject caseObj && + caseObj["condition"]?.GetValue()?.Contains($"net{tf}.0") == true) + { + existingCase = caseObj; + break; + } + } + + if (existingCase is not null) + { + // Update existing case value + string? currentValue = existingCase["value"]?.GetValue(); + if (currentValue != version) + { + existingCase["value"] = version; + modified = true; + Console.WriteLine($" Updated {symbolName} for net{tf}.0 to {version}"); + } + } + else + { + // Add new case for this framework + var newCase = new JsonObject + { + ["condition"] = condition, + ["value"] = version + }; + cases.Add(newCase); + modified = true; + Console.WriteLine($" Added {symbolName} case for net{tf}.0 with version {version}"); + } + } + } + + if (modified) + { + var options = new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }; + File.WriteAllText(templateJsonPath, rootNode.ToJsonString(options)); + Console.WriteLine($" Saved changes to {Path.GetFileName(templateJsonPath)}"); + } + else + { + Console.WriteLine($" No changes needed"); + } +} + +// Replace .razor files in content with those from Pages +Console.WriteLine(); +Console.WriteLine("Updating .razor files in content with those from Pages folder"); +string pagesDir = Path.Combine(templatesDir, "Pages"); +if (Directory.Exists(pagesDir)) +{ + string[] razorFiles = Directory.GetFiles(pagesDir, "*.razor"); + foreach (string razorFile in razorFiles) + { + string fileName = Path.GetFileName(razorFile); + string[] matchingContentFiles = Directory.GetFiles(contentDir, fileName, SearchOption.AllDirectories); + foreach (string destFile in matchingContentFiles) + { + File.Copy(razorFile, destFile, true); + Console.WriteLine($" Copied {fileName} to {Path.GetRelativePath(templatesDir, destFile)}"); + } + } +} +else +{ + Console.WriteLine(" Pages folder not found, skipping razor file copy"); +} + +// Build the templates +Console.WriteLine(); +Console.WriteLine("Building GeoBlazor Templates project"); +string templateProjectPath = Path.Combine(templatesDir, "dymaptic.GeoBlazor.Templates.csproj"); + +int restoreResult = RunDotnet($"restore \"{templateProjectPath}\""); +if (restoreResult != 0) +{ + Console.Error.WriteLine("Error: dotnet restore failed"); + return restoreResult; +} + +int buildResult = RunDotnet( + $"build \"{templateProjectPath}\" -c Release --no-restore " + + $"/p:ProVersion={proVersion} /p:OptOutFromCoreEsBuild=true " + + "/p:OptOutFromProEsBuild=true /p:GenerateDocs=false /p:GeneratePackage=false"); + +if (buildResult != 0) +{ + Console.Error.WriteLine("Error: dotnet build failed"); + return buildResult; +} + +// Install templates if requested +if (install) +{ + Console.WriteLine(); + Console.WriteLine("Installing templates..."); + + RunDotnet("new uninstall dymaptic.GeoBlazor.Templates"); + + string binDir = Path.Combine(templatesDir, "bin", "Release"); + string packageName = $"dymaptic.GeoBlazor.Templates.{proVersion}.nupkg"; + string packagePath = Path.Combine(binDir, packageName); + + if (!File.Exists(packagePath)) + { + Console.Error.WriteLine($"Error: Package not found at {packagePath}"); + return 1; + } + + int installResult = RunDotnet($"new install \"{packagePath}\""); + if (installResult != 0) + { + Console.Error.WriteLine("Error: Template installation failed"); + return installResult; + } +} + +Console.WriteLine(); +Console.WriteLine("Build templates completed successfully!"); +return 0; + +// Helper methods + +static async Task> GetPackageVersionsAsync( + HttpClient client, string packageName, int[] targetFrameworks) +{ + var result = new Dictionary(); + foreach (int tf in targetFrameworks) + { + result[tf] = null; + } + + string nugetUrl = $"https://azuresearch-usnc.nuget.org/query?q={Uri.EscapeDataString(packageName)}&prerelease=false"; + string json = await client.GetStringAsync(nugetUrl); + using var doc = JsonDocument.Parse(json); + + if (!doc.RootElement.TryGetProperty("data", out var data) || data.GetArrayLength() == 0) + { + return result; + } + + // Find the package with exact ID match + JsonElement? packageData = null; + foreach (var item in data.EnumerateArray()) + { + if (item.TryGetProperty("id", out var idProp) && + string.Equals(idProp.GetString(), packageName, StringComparison.OrdinalIgnoreCase)) + { + packageData = item; + break; + } + } + + if (packageData is null) + { + return result; + } + + if (!packageData.Value.TryGetProperty("versions", out var versions)) + { + return result; + } + + foreach (int tf in targetFrameworks) + { + // Find latest version starting with the target framework number + string? latestVersion = null; + Version? latestParsedVersion = null; + + foreach (var versionItem in versions.EnumerateArray()) + { + if (!versionItem.TryGetProperty("version", out var versionProp)) + { + continue; + } + + string? versionStr = versionProp.GetString(); + if (versionStr is null || !versionStr.StartsWith($"{tf}.")) + { + continue; + } + + // Parse version for comparison (strip prerelease suffix) + string versionToParse = versionStr.Split('-')[0]; + if (Version.TryParse(versionToParse, out var parsedVersion)) + { + if (latestParsedVersion is null || parsedVersion > latestParsedVersion) + { + latestParsedVersion = parsedVersion; + latestVersion = versionStr; + } + } + } + + if (latestVersion is not null) + { + result[tf] = latestVersion; + } + else + { + Console.WriteLine($" Warning: No version found for {packageName} supporting net{tf}.0"); + } + } + + return result; +} + +static int RunDotnet(string arguments) +{ + var psi = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = arguments, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true + }; + + using var process = Process.Start(psi); + if (process is null) + { + return 1; + } + + process.OutputDataReceived += (_, e) => + { + if (e.Data is not null) + { + Console.WriteLine(e.Data); + } + }; + process.ErrorDataReceived += (_, e) => + { + if (e.Data is not null) + { + Console.WriteLine(e.Data); + } + }; + + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + process.WaitForExit(); + + return process.ExitCode; +} + +static string GetScriptDirectory([CallerFilePath] string? callerFilePath = null) +{ + return Path.GetDirectoryName(callerFilePath!) ?? Environment.CurrentDirectory; +} diff --git a/build/ConsoleDialog.cs b/build-scripts/ConsoleDialog.cs similarity index 89% rename from build/ConsoleDialog.cs rename to build-scripts/ConsoleDialog.cs index c97d78e3e..1fca2a591 100644 --- a/build/ConsoleDialog.cs +++ b/build-scripts/ConsoleDialog.cs @@ -8,7 +8,34 @@ Process? _consoleProcess = null; string? _consoleTempFile = null; +string? title = null; +int wait = 3; +for (int i = 0; i < args.Length; i++) +{ + string arg = args[i]; + + switch (arg) + { + case "-w": + case "--wait": + wait = int.TryParse(args[i + 1], out int parsedWait) ? parsedWait : wait; + i++; + break; + default: + if (title is null) + { + title = arg; + } + else + { + title = $"{title} {arg}"; + } + break; + } +} + +title ??= "GeoBlazor Build"; void ShowOrUpdateConsole(string title, string message) { @@ -19,7 +46,7 @@ void ShowOrUpdateConsole(string title, string message) { _consoleTempFile = Path.Combine(Path.GetTempPath(), $"geoblazor_sourcegen_{Guid.NewGuid():N}.log"); // Create the file immediately so Get-Content -Wait has something to tail - File.WriteAllText(_consoleTempFile, $"[{DateTime.Now:HH:mm:ss}] {title}: Starting...{Environment.NewLine}"); + File.WriteAllText(_consoleTempFile, $" {Environment.NewLine}"); } if (!string.IsNullOrWhiteSpace(message)) @@ -155,7 +182,7 @@ void StartLinuxConsole() // No terminal emulator found - messages still go to temp file and diagnostics } -void CloseConsole(string title) +void CloseConsole(string title, int wait) { lock (_consoleLock) { @@ -165,7 +192,7 @@ void CloseConsole(string title) { File.WriteAllText(_consoleTempFile, $"[{DateTime.Now:HH:mm:ss}] {title}: Console closing..."); // Give a brief moment for final messages to appear - Thread.Sleep(4000); + Thread.Sleep(wait * 1000); _consoleProcess.Kill(); _consoleProcess.Dispose(); } @@ -198,9 +225,6 @@ void CloseConsole(string title) } } - -string? title = args.Length > 0 ? args[0] : "GeoBlazor Build"; - ShowOrUpdateConsole(title, string.Empty); CancellationTokenSource cts = new(); @@ -216,7 +240,7 @@ void CloseConsole(string title) await Task.Delay(1000); } Console.WriteLine("Console dialog timed out. Closing..."); - CloseConsole(title); + CloseConsole(title, wait); Environment.Exit(0); }); @@ -241,7 +265,7 @@ void CloseConsole(string title) if (inputLine.Trim().Equals("exit", StringComparison.OrdinalIgnoreCase)) { - CloseConsole(title); + CloseConsole(title, wait); break; } diff --git a/build/ESBuild.cs b/build-scripts/ESBuild.cs similarity index 80% rename from build/ESBuild.cs rename to build-scripts/ESBuild.cs index c014212f8..447e458b8 100644 --- a/build/ESBuild.cs +++ b/build-scripts/ESBuild.cs @@ -7,14 +7,17 @@ // -f, --force Force rebuild, ignoring lock files and record // -p, --pro Run the GeoBlazor Pro ESBuild process // -d, --dialog Show a console dialog during build +// -v, --verbose Enable verbose logging // -h, --help Display help message using System.Diagnostics; +using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Json; // Get the actual script location using CallerFilePath (resolved at compile time) -string scriptDir = GetScriptDirectory(); +string scriptDir = GetScriptsDirectory(); +string toolsDir = Path.GetFullPath(Path.Combine(scriptDir, "..", "build-tools")); // Parse command line arguments string configuration = "Debug"; @@ -22,6 +25,7 @@ bool help = false; bool pro = false; bool dialog = false; +bool verbose = false; for (int i = 0; i < args.Length; i++) { @@ -51,6 +55,10 @@ case "--help": help = true; break; + case "-v": + case "--verbose": + verbose = true; + break; default: // Check for combined forms like "-c=Release" if (arg.StartsWith("-c=") || arg.StartsWith("--configuration=")) @@ -78,23 +86,15 @@ Process? dialogProcess = null; -if (dialog) +if (verbose) { - dialogProcess = StartConsoleDialog(scriptDir, - $"GeoBlazor {(pro ? "Pro" : "Core")} ESBuild"); - if (dialogProcess?.StandardInput is null) - { - Trace.WriteLine("Failed to start console dialog. Exiting."); - } - else + if (dialog) // only start the dialog early if we are in Verbose + Dialog mode { - dialogProcess.StandardInput.AutoFlush = true; - Trace.Listeners.Add(new DialogTraceListener(dialogProcess)); + dialogProcess = StartConsoleDialog(toolsDir, $"GeoBlazor {(pro ? "Pro" : "Core")} ESBuild"); } + Trace.WriteLine("Launching ESBuild..."); } -Trace.WriteLine("Launching ESBuild..."); - // Normalize configuration configuration = configuration.Equals("release", StringComparison.OrdinalIgnoreCase) ? "Release" : "Debug"; @@ -103,19 +103,25 @@ string coreSourceDir = Path.GetFullPath(Path.Combine(scriptDir, "..", "src", "dymaptic.GeoBlazor.Core")); string proSourceDir = Path.GetFullPath(Path.Combine(scriptDir, "..", "..", "src", "dymaptic.GeoBlazor.Pro")); string sourceDir = pro ? proSourceDir : coreSourceDir; + string coreScriptsDir = Path.Combine(coreSourceDir, "Scripts"); string proScriptsDir = Path.Combine(proSourceDir, "Scripts"); string scriptsDir = pro ? proScriptsDir : coreScriptsDir; + string coreOutputDir = Path.Combine(coreSourceDir, "wwwroot", "js"); string proOutputDir = Path.Combine(proSourceDir, "wwwroot", "js"); string outputDir = pro ? proOutputDir : coreOutputDir; + string coreRecordFilePath = Path.GetFullPath(Path.Combine(coreSourceDir, "..", ".esbuild-record.json")); string proRecordFilePath = Path.GetFullPath(Path.Combine(proSourceDir, "..", ".esbuild-record.json")); string recordFilePath = pro ? proRecordFilePath : coreRecordFilePath; + string coreDebugLockFile = Path.Combine(coreSourceDir, "esBuild.Debug.lock"); string coreReleaseLockFile = Path.Combine(coreSourceDir, "esBuild.Release.lock"); string proDebugLockFile = Path.Combine(proSourceDir, "esBuild.Debug.lock"); string proReleaseLockFile = Path.Combine(proSourceDir, "esBuild.Release.lock"); +string debugLockFile = configuration == "Debug" ? (pro ? proDebugLockFile : coreDebugLockFile) : string.Empty; +string releaseLockFile = configuration == "Release" ? (pro ? proReleaseLockFile : coreReleaseLockFile) : string.Empty; string coreLockFilePath = configuration == "Release" ? coreReleaseLockFile : coreDebugLockFile; string proLockFilePath = configuration == "Release" ? proReleaseLockFile : proDebugLockFile; string lockFilePath = pro ? proLockFilePath : coreLockFilePath; @@ -152,27 +158,30 @@ if (!needsBuild) { + KillDialog(dialogProcess); Environment.Exit(0); } +if (!verbose) +{ + if (dialog) // start the dialog now if we are not in Verbose mode + { + dialogProcess = StartConsoleDialog(toolsDir, $"GeoBlazor {(pro ? "Pro" : "Core")} ESBuild"); + } + Trace.WriteLine("Launching ESBuild..."); +} + // Check if the process is locked for the current configuration -bool locked = configuration == "Debug" && File.Exists(coreDebugLockFile) - || configuration == "Release" && File.Exists(coreReleaseLockFile) - || (pro && ((configuration == "Debug" && File.Exists(proDebugLockFile)) - || (configuration == "Release" && File.Exists(proReleaseLockFile)))); +bool locked = configuration == "Debug" && File.Exists(debugLockFile) + || configuration == "Release" && File.Exists(releaseLockFile); // Prevent multiple instances of the script from running at the same time if (locked) { if (force) { - if (File.Exists(coreDebugLockFile)) File.Delete(coreDebugLockFile); - if (File.Exists(coreReleaseLockFile)) File.Delete(coreReleaseLockFile); - if (pro) - { - if (File.Exists(proDebugLockFile)) File.Delete(proDebugLockFile); - if (File.Exists(proReleaseLockFile)) File.Delete(proReleaseLockFile); - } + if (File.Exists(debugLockFile)) File.Delete(debugLockFile); + if (File.Exists(releaseLockFile)) File.Delete(releaseLockFile); Trace.WriteLine("Cleared esBuild lock files"); } else @@ -188,12 +197,6 @@ // Lock File.WriteAllText(lockFilePath, DateTime.UtcNow.ToString("o")); - if (pro) - { - // also lock core - File.WriteAllText(coreLockFilePath, DateTime.UtcNow.ToString("o")); - } - // Ensure output directory exists if (!Directory.Exists(outputDir)) { @@ -203,11 +206,11 @@ if (pro) { // Copy core Scripts to Pro Scripts - CopyScriptsToPro(coreScriptsDir, proScriptsDir); + CopyScriptsToPro(coreScriptsDir, proScriptsDir, verbose); } // npm install - var (installOutput, installExitCode) = RunNpmCommand(coreSourceDir, "install", dialogProcess); + var (installOutput, installExitCode) = RunNpmCommand(sourceDir, "install", dialogProcess); Trace.WriteLine("-----"); if (installExitCode != 0 || HasErrorOrWarning(installOutput)) @@ -219,7 +222,7 @@ // Run ESLint before build Trace.WriteLine("Running ESLint..."); - var (lintOutput, lintExitCode) = RunNpmCommand(coreSourceDir, "run lint", dialogProcess); + var (lintOutput, lintExitCode) = RunNpmCommand(sourceDir, "run lint", dialogProcess); Trace.WriteLine("-----"); if (lintExitCode != 0 || lintOutput.Any(l => l.Contains("error", StringComparison.OrdinalIgnoreCase))) @@ -231,7 +234,7 @@ // Run build string buildCommand = configuration == "Release" ? "run releaseBuild" : "run debugBuild"; - var (buildOutput, buildExitCode) = RunNpmCommand(coreSourceDir, buildCommand, dialogProcess); + var (buildOutput, buildExitCode) = RunNpmCommand(sourceDir, buildCommand, dialogProcess); Trace.WriteLine("-----"); if (buildExitCode != 0 || HasErrorOrWarning(buildOutput)) @@ -250,7 +253,7 @@ catch (Exception ex) { Trace.WriteLine("An error occurred in esBuild.cs"); - Trace.WriteLine(ex.ToString()); + Trace.WriteLine($"{ex.Message}{Environment.NewLine}{ex.StackTrace}"); HoldDialog(dialogProcess); return 1; } @@ -261,11 +264,6 @@ { File.Delete(lockFilePath); } - - if (pro && File.Exists(coreLockFilePath)) - { - File.Delete(coreLockFilePath); - } } // Helper methods @@ -328,14 +326,14 @@ static bool CheckIfNeedsBuild(string recordFilePath, string currentBranch, strin // Check if build is needed var lastBuild = GetLastBuildRecord(recordFilePath); bool branchChanged = currentBranch != lastBuild.Branch; - bool needsBuild = false; if (branchChanged) { Trace.WriteLine($"Git branch changed from \"{lastBuild.Branch}\" to \"{currentBranch}\". Rebuilding..."); - needsBuild = true; + return true; } - else if (!GetScriptsModifiedSince(scriptsDir, lastBuild.Timestamp)) + + if (!GetScriptsModifiedSince(scriptsDir, lastBuild.Timestamp)) { Trace.WriteLine("No changes in Scripts folder since last build."); @@ -343,25 +341,20 @@ static bool CheckIfNeedsBuild(string recordFilePath, string currentBranch, strin if (Directory.Exists(outputDir) && Directory.GetFiles(outputDir).Length > 0) { Trace.WriteLine("Output directory is not empty. Skipping build."); - KillDialog(dialogProcess); - Environment.Exit(0); + return false; } else { Trace.WriteLine("Output directory is empty. Proceeding with build."); - needsBuild = true; + return true; } } - else - { - Trace.WriteLine("Changes detected in Scripts folder. Proceeding with build."); - needsBuild = true; - } - return needsBuild; + Trace.WriteLine("Changes detected in Scripts folder. Proceeding with build."); + return true; } -static void CopyScriptsToPro(string coreScriptsDir, string proScriptsDir) +static void CopyScriptsToPro(string coreScriptsDir, string proScriptsDir, bool verbose) { Trace.WriteLine("Copying core Scripts to Pro Scripts directory..."); if (!Directory.Exists(proScriptsDir)) @@ -373,7 +366,7 @@ static void CopyScriptsToPro(string coreScriptsDir, string proScriptsDir) int skippedCount = 0; List fileNames = []; - foreach (string filePath in Directory.GetFiles(coreScriptsDir, "*", SearchOption.AllDirectories)) + foreach (string filePath in Directory.GetFiles(coreScriptsDir, "*.ts", SearchOption.AllDirectories)) { string fileName = Path.GetFileName(filePath); fileNames.Add(fileName); @@ -383,6 +376,10 @@ static void CopyScriptsToPro(string coreScriptsDir, string proScriptsDir) { File.Copy(filePath, destinationPath, true); copiedCount++; + if (verbose) + { + Trace.WriteLine($"Copied new file: {fileName}"); + } continue; } @@ -392,6 +389,10 @@ static void CopyScriptsToPro(string coreScriptsDir, string proScriptsDir) if (sourceDate > destDate) { File.Copy(filePath, destinationPath, true); + if (verbose) + { + Trace.WriteLine($"Updated file: {fileName}"); + } copiedCount++; } else @@ -440,17 +441,25 @@ static bool GetScriptsModifiedSince(string scriptsDir, long lastTimestamp) { try { - string consoleDialogPath = Path.Combine(buildDir, "ConsoleDialog.cs"); + string consoleDialogPath = Path.Combine(buildDir, "ConsoleDialog.dll"); if (!File.Exists(consoleDialogPath)) { - Trace.WriteLine($"ConsoleDialog.cs not found at {consoleDialogPath}"); + Trace.WriteLine($"ConsoleDialog.dll not found at {consoleDialogPath}"); return null; } + + string[] args = + [ + "ConsoleDialog.dll", + $"\"{title}\"", + "-w", + "2" + ]; var psi = new ProcessStartInfo { FileName = "dotnet", - Arguments = $"run \"{consoleDialogPath}\" \"{title}\"", + Arguments = string.Join(" ", args), WorkingDirectory = buildDir, RedirectStandardInput = true, RedirectStandardOutput = true, @@ -458,7 +467,19 @@ static bool GetScriptsModifiedSince(string scriptsDir, long lastTimestamp) CreateNoWindow = true }; - return Process.Start(psi); + Process? dialog = Process.Start(psi); + + if (dialog?.StandardInput is null) + { + Trace.WriteLine("Failed to start console dialog. Exiting."); + } + else + { + dialog.StandardInput.AutoFlush = true; + Trace.Listeners.Add(new DialogTraceListener(dialog)); + } + + return dialog; } catch (Exception ex) { @@ -543,7 +564,7 @@ static void KillDialog(Process? dialog) } catch (Exception ex) { - Trace.WriteLine($"Error running npm {command}: {ex.Message}"); + Trace.WriteLine($"Error running npm {command}: {ex.Message}{Environment.NewLine}{ex.StackTrace}"); output.Add(ex.Message); return (output, 1); } @@ -556,9 +577,20 @@ static bool HasErrorOrWarning(List output) line.Contains("Warning", StringComparison.OrdinalIgnoreCase)); } -static string GetScriptDirectory([CallerFilePath] string? callerFilePath = null) +static string GetScriptsDirectory([CallerFilePath] string? callerFilePath = null) { - return Path.GetDirectoryName(callerFilePath) ?? Environment.CurrentDirectory; + // When running as a pre-compiled DLL, [CallerFilePath] contains the compile-time path + // which is invalid at runtime (especially in Docker containers). + // Detect this by checking if the file exists at the caller path. + if (!string.IsNullOrEmpty(callerFilePath) && File.Exists(callerFilePath)) + { + return Path.GetDirectoryName(callerFilePath)!; + } + + // Running as a DLL - use AppContext.BaseDirectory which points to the DLL location + // The DLL is in build-tools/, and scripts are in build-scripts/ (sibling directory) + string dllDirectory = AppContext.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + return Path.Combine(Path.GetDirectoryName(dllDirectory)!, "build-scripts"); } static void HoldDialog(Process? dialog) diff --git a/build-scripts/ESBuildClearLocks.cs b/build-scripts/ESBuildClearLocks.cs new file mode 100644 index 000000000..948db0b4b --- /dev/null +++ b/build-scripts/ESBuildClearLocks.cs @@ -0,0 +1,72 @@ +#!/usr/bin/env dotnet + +// ESBuild Clear Locks Script +// C# file-based app version of esBuildClearLocks.ps1 +// Removes ESBuild lock files for both Core and Pro projects +// +// Usage: dotnet ESBuildClearLocks.cs +// -h, --help Display help message + +using System.Runtime.CompilerServices; + +// Parse command line arguments +bool help = args.Any(a => a is "-h" or "--help"); + +if (help) +{ + Console.WriteLine("ESBuild Clear Locks Script"); + Console.WriteLine("Removes ESBuild lock files for both Core and Pro projects."); + Console.WriteLine(); + Console.WriteLine("Usage: dotnet ESBuildClearLocks.cs"); + Console.WriteLine(); + Console.WriteLine("Options:"); + Console.WriteLine(" -h, --help Display this help message"); + return 0; +} + +string scriptDir = GetScriptDirectory(); + +// Define lock file paths relative to script location (build-scripts folder) +string[] lockFiles = +[ + Path.GetFullPath(Path.Combine(scriptDir, "..", "src", "dymaptic.GeoBlazor.Core", "esBuild.Debug.lock")), + Path.GetFullPath(Path.Combine(scriptDir, "..", "src", "dymaptic.GeoBlazor.Core", "esBuild.Release.lock")), + Path.GetFullPath(Path.Combine(scriptDir, "..", "..", "src", "dymaptic.GeoBlazor.Pro", "esBuild.Debug.lock")), + Path.GetFullPath(Path.Combine(scriptDir, "..", "..", "src", "dymaptic.GeoBlazor.Pro", "esBuild.Release.lock")) +]; + +int deletedCount = 0; + +foreach (string lockFile in lockFiles) +{ + if (File.Exists(lockFile)) + { + try + { + File.Delete(lockFile); + Console.WriteLine($"Deleted: {lockFile}"); + deletedCount++; + } + catch (Exception ex) + { + Console.WriteLine($"Failed to delete {lockFile}: {ex.Message}"); + } + } +} + +if (deletedCount > 0) +{ + Console.WriteLine($"Cleared {deletedCount} esBuild lock file(s)"); +} +else +{ + Console.WriteLine("No esBuild lock files found"); +} + +return 0; + +// Helper method +static string GetScriptDirectory([CallerFilePath] string? callerFilePath = null) +{ + return Path.GetDirectoryName(callerFilePath!) ?? Environment.CurrentDirectory; +} diff --git a/build-scripts/ESBuildWaitForCompletion.cs b/build-scripts/ESBuildWaitForCompletion.cs new file mode 100644 index 000000000..a76c72a29 --- /dev/null +++ b/build-scripts/ESBuildWaitForCompletion.cs @@ -0,0 +1,149 @@ +#!/usr/bin/env dotnet + +// ESBuild Wait For Completion Script +// C# file-based app version of esBuildWaitForCompletion.ps1 +// Waits for ESBuild lock files to be released before proceeding +// +// Usage: dotnet ESBuildWaitForCompletion.cs [options] +// -c, --configuration Build configuration (default: Debug) +// -t, --timeout Timeout in seconds (default: 30) +// -h, --help Display help message +// +// Example: +// dotnet ESBuildWaitForCompletion.cs +// dotnet ESBuildWaitForCompletion.cs -c Release +// dotnet ESBuildWaitForCompletion.cs -c Debug -t 60 + +using System.Runtime.CompilerServices; + +// Parse command line arguments +string configuration = "Debug"; +int timeout = 30; +bool help = false; + +for (int i = 0; i < args.Length; i++) +{ + string arg = args[i].ToLowerInvariant(); + switch (arg) + { + case "-c": + case "--configuration": + if (i + 1 < args.Length) + { + configuration = args[++i]; + } + break; + case "-t": + case "--timeout": + if (i + 1 < args.Length && int.TryParse(args[++i], out int t)) + { + timeout = t; + } + break; + case "-h": + case "--help": + help = true; + break; + } +} + +if (help) +{ + Console.WriteLine("ESBuild Wait For Completion Script"); + Console.WriteLine("Waits for ESBuild lock files to be released before proceeding."); + Console.WriteLine(); + Console.WriteLine("Usage: dotnet ESBuildWaitForCompletion.cs [options]"); + Console.WriteLine(); + Console.WriteLine("Options:"); + Console.WriteLine(" -c, --configuration Build configuration (default: Debug)"); + Console.WriteLine(" -t, --timeout Timeout in seconds (default: 30)"); + Console.WriteLine(" -h, --help Display this help message"); + Console.WriteLine(); + Console.WriteLine("Examples:"); + Console.WriteLine(" dotnet ESBuildWaitForCompletion.cs"); + Console.WriteLine(" dotnet ESBuildWaitForCompletion.cs -c Release"); + Console.WriteLine(" dotnet ESBuildWaitForCompletion.cs -c Debug -t 60"); + return 0; +} + +// Normalize configuration +configuration = configuration.Equals("release", StringComparison.OrdinalIgnoreCase) ? "Release" : "Debug"; + +string scriptDir = GetScriptDirectory(); + +// Define paths relative to script location (build-scripts folder) +// Core: ../src/dymaptic.GeoBlazor.Core +// Pro: ../../src/dymaptic.GeoBlazor.Pro +string coreRootDir = Path.GetFullPath(Path.Combine(scriptDir, "..", "src", "dymaptic.GeoBlazor.Core")); +string proRootDir = Path.GetFullPath(Path.Combine(scriptDir, "..", "..", "src", "dymaptic.GeoBlazor.Pro")); + +string coreLockFilePath = Path.Combine(coreRootDir, $"esBuild.{configuration}.lock"); +string proLockFilePath = Path.Combine(proRootDir, $"esBuild.{configuration}.lock"); + +Console.WriteLine($"Waiting for lock files: {coreLockFilePath}, {proLockFilePath}"); + +bool coreLockExists = File.Exists(coreLockFilePath); +bool proLockExists = File.Exists(proLockFilePath); + +if (coreLockExists || proLockExists) +{ + Console.WriteLine("Lock file found. Waiting for release."); +} +else +{ + Console.WriteLine("No lock file found. Exiting."); + return 0; +} + +int elapsed = 0; + +while (File.Exists(coreLockFilePath) || File.Exists(proLockFilePath)) +{ + Thread.Sleep(1000); + Console.Write("."); + elapsed++; + + if (elapsed >= timeout) + { + Console.WriteLine(); + Console.WriteLine($"Timeout reached ({timeout} seconds). Deleting lock files."); + + if (File.Exists(coreLockFilePath)) + { + try + { + File.Delete(coreLockFilePath); + Console.WriteLine($"Deleted: {coreLockFilePath}"); + } + catch (Exception ex) + { + Console.WriteLine($"Failed to delete {coreLockFilePath}: {ex.Message}"); + } + } + + if (File.Exists(proLockFilePath)) + { + try + { + File.Delete(proLockFilePath); + Console.WriteLine($"Deleted: {proLockFilePath}"); + } + catch (Exception ex) + { + Console.WriteLine($"Failed to delete {proLockFilePath}: {ex.Message}"); + } + } + + break; + } +} + +Console.WriteLine(); +Console.WriteLine("Lock file removed. Exiting."); +return 0; + +// Helper method +static string GetScriptDirectory([CallerFilePath] string? callerFilePath = null) +{ + return Path.GetDirectoryName(callerFilePath!) ?? Environment.CurrentDirectory; +} diff --git a/build-scripts/FetchNuGetVersion.cs b/build-scripts/FetchNuGetVersion.cs new file mode 100644 index 000000000..60f40f061 --- /dev/null +++ b/build-scripts/FetchNuGetVersion.cs @@ -0,0 +1,98 @@ +#!/usr/bin/env dotnet + +// Fetch NuGet Package Version Script +// C# file-based app version of fetchNuGetVersion.ps1 +// Usage: dotnet FetchNuGetVersion.cs +// Example: dotnet FetchNuGetVersion.cs dymaptic.GeoBlazor.Core +// Returns the latest non-prerelease version of the specified package from NuGet.org + +using System.Text.Json; + +if (args.Length == 0 || string.IsNullOrWhiteSpace(args[0])) +{ + Console.Error.WriteLine("Package name must be provided."); + return 1; +} + +string package = args[0]; + +try +{ + // Query NuGet API (same endpoint as the PowerShell script) + string nugetUrl = $"https://azuresearch-usnc.nuget.org/query?q={Uri.EscapeDataString(package)}&prerelease=false"; + + using var client = new HttpClient(); + client.DefaultRequestHeaders.Add("User-Agent", "GeoBlazor-Build-Script"); + + string json = await client.GetStringAsync(nugetUrl); + using var doc = JsonDocument.Parse(json); + var root = doc.RootElement; + + if (!root.TryGetProperty("data", out var data) || data.GetArrayLength() == 0) + { + Console.Error.WriteLine("Could not determine latest version from NuGet API."); + return 1; + } + + // Find the package with exact match and get the highest version + string? latestVersion = null; + + foreach (var item in data.EnumerateArray()) + { + // Check for exact package name match (case-insensitive) + if (item.TryGetProperty("id", out var idProp)) + { + string? id = idProp.GetString(); + if (string.Equals(id, package, StringComparison.OrdinalIgnoreCase)) + { + if (item.TryGetProperty("version", out var versionProp)) + { + latestVersion = versionProp.GetString(); + break; // NuGet API returns the latest version for each package + } + } + } + } + + // Fallback: if no exact match, try to parse versions from all results + if (latestVersion is null) + { + var versions = new List<(Version Version, string Original)>(); + + foreach (var item in data.EnumerateArray()) + { + if (item.TryGetProperty("version", out var versionProp)) + { + string? versionStr = versionProp.GetString(); + if (versionStr is not null && Version.TryParse(versionStr.Split('-')[0], out var version)) + { + versions.Add((version, versionStr)); + } + } + } + + if (versions.Count > 0) + { + latestVersion = versions.OrderByDescending(v => v.Version).First().Original; + } + } + + if (latestVersion is null) + { + Console.Error.WriteLine("Could not determine latest version from NuGet API."); + return 1; + } + + Console.WriteLine(latestVersion); + return 0; +} +catch (HttpRequestException ex) +{ + Console.Error.WriteLine($"Failed to query NuGet API: {ex.Message}"); + return 1; +} +catch (JsonException ex) +{ + Console.Error.WriteLine($"Failed to parse NuGet API response: {ex.Message}"); + return 1; +} diff --git a/build-scripts/GeoBlazorBuild.cs b/build-scripts/GeoBlazorBuild.cs new file mode 100644 index 000000000..8ed261266 --- /dev/null +++ b/build-scripts/GeoBlazorBuild.cs @@ -0,0 +1,1074 @@ +#!/usr/bin/env dotnet + +// GeoBlazorBuild - Primary build script for GeoBlazor and GeoBlazor Pro +// Usage: dotnet GeoBlazorBuild.dll [options] or ./GeoBlazorBuild.exe [options] +// -pro Build GeoBlazor Pro as well as Core (default is false) +// -pub, --publish-version Truncate the build version to 3 digits for NuGet (default is false) +// -obf, --obfuscate Obfuscate the Pro license validation logic (default is false) +// -docs, --generate-docs Generate documentation files for the docs site (default is false) +// -xml, --generate-xml Generate the XML comments for intellisense (default is false) +// -pkg, --package Create NuGet packages (default is false) +// -bl, --binlog Generate MSBuild binary log files (default is false) +// -v, --version Specify a custom version number, or "current" (default is to auto-increment) +// -c, --configuration Build configuration (default is 'Release') +// -vc, --validator-config Validator build configuration (default is 'Release') +// -su, --server-url License server URL (default is 'https://licensing.dymaptic.com') +// -retries Number of times to retry the build on failure (default is 5) +// -h, --help Display this help message + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Text.Json; +using System.Text.RegularExpressions; +using System.Xml.Linq; + +// Paths +// Get the script cs file path, that way we can run this script from either the CS file or the Executable +string scriptsDir = GetScriptsDirectory(); +string toolsDir = Path.GetFullPath(Path.Combine(scriptsDir, "..", "build-tools")); +// Build folder is at GeoBlazor/build/, Core root is GeoBlazor/ +string coreRepoRoot = Path.GetFullPath(Path.Combine(toolsDir, "..")); +string proRepoRoot = Path.GetFullPath(Path.Combine(coreRepoRoot, "..")); + +string corePropsPath = Path.Combine(coreRepoRoot, "Directory.Build.props"); +string coreProjectPath = Path.Combine(coreRepoRoot, "src", "dymaptic.GeoBlazor.Core"); +string proPropsPath = Path.Combine(proRepoRoot, "Directory.Build.props"); +string proProjectPath = Path.Combine(proRepoRoot, "src", "dymaptic.GeoBlazor.Pro"); +string validatorProjectPath = Path.Combine(proRepoRoot, "src", "dymaptic.GeoBlazor.Pro.Validator"); + +DateTime scriptStartTime = DateTime.Now; + +// Parse command line arguments +bool pro = false; +bool publishVersion = false; +bool obfuscate = false; +bool generateDocs = false; +bool generateXmlComments = false; +bool package = false; +bool binlog = false; +bool help = false; +string? customVersion = null; +string configuration = "Release"; +string validatorConfig = "Release"; +string serverUrl = "https://licensing.dymaptic.com"; +int buildRetries = 5; + +for (int i = 0; i < args.Length; i++) +{ + string arg = args[i].ToLowerInvariant(); + switch (arg) + { + case "-pro": + case "--pro": + pro = true; + break; + case "-pub": + case "--publish-version": + publishVersion = true; + break; + case "-obf": + case "--obfuscate": + obfuscate = true; + break; + case "-docs": + case "--generate-docs": + generateDocs = true; + break; + case "-xml": + case "--generate-xml": + generateXmlComments = true; + break; + case "-pkg": + case "--package": + package = true; + break; + case "-bl": + case "--binlog": + binlog = true; + break; + case "-h": + case "--help": + help = true; + break; + case "-v": + case "--version": + if (i + 1 < args.Length) + { + string version = args[++i]; + if (version.Trim('"') == "current") + { + XDocument coreProps = XDocument.Load(corePropsPath); + string? currentCoreVersion = coreProps.Root?.Element("PropertyGroup")?.Element("CoreVersion")?.Value; + customVersion = currentCoreVersion; + } + else + { + customVersion = version.Trim('"'); + } + } + break; + case "-c": + case "--configuration": + if (i + 1 < args.Length) + { + configuration = args[++i]; + } + break; + case "-vc": + case "--validator-config": + if (i + 1 < args.Length) + { + validatorConfig = args[++i]; + } + break; + case "-su": + case "--server-url": + if (i + 1 < args.Length) + { + serverUrl = args[++i]; + } + break; + case "-retries": + case "--retries": + if (i + 1 < args.Length && int.TryParse(args[++i], out int retries)) + { + buildRetries = retries; + } + break; + } +} + +if (help) +{ + Console.WriteLine("GeoBlazor Build Script"); + Console.WriteLine(); + Console.WriteLine("Parameters:"); + Console.WriteLine(" -pro Build GeoBlazor Pro as well as Core (default is false)"); + Console.WriteLine(" -pub, --publish-version Truncate the build version to 3 digits for NuGet (default is false)"); + Console.WriteLine(" -obf, --obfuscate Obfuscate the Pro license validation logic (default is false)"); + Console.WriteLine(" -docs, --generate-docs Generate documentation files for the docs site (default is false)"); + Console.WriteLine(" -xml, --generate-xml Generate the XML comments for intellisense (default is false)"); + Console.WriteLine(" -pkg, --package Create NuGet packages (default is false)"); + Console.WriteLine(" -bl, --binlog Generate MSBuild binary log files (default is false)"); + Console.WriteLine(" -v, --version Specify a custom version number (default is to auto-increment)"); + Console.WriteLine(" -c, --configuration Build configuration (default is 'Release')"); + Console.WriteLine(" -vc, --validator-config Validator build configuration (default is 'Release')"); + Console.WriteLine(" -su, --server-url License server URL (default is 'https://licensing.dymaptic.com')"); + Console.WriteLine(" -retries Number of times to retry the build on failure (default is 5)"); + Console.WriteLine(" -h, --help Display this help message"); + return 0; +} + +// If generating docs, also generate XML comments +if (generateDocs) +{ + generateXmlComments = true; +} + +Console.WriteLine("Starting GeoBlazor Build Script"); +Console.WriteLine($"Pro Build: {pro}"); +Console.WriteLine($"Set NuGet Publish Version Build: {publishVersion}"); +Console.WriteLine($"Obfuscate Pro Build: {obfuscate}"); +Console.WriteLine($"Generate Documentation Files: {generateDocs}"); +Console.WriteLine($"Generate XML Documentation: {generateXmlComments}"); +Console.WriteLine($"Build Package: {package}"); +Console.WriteLine($"Version: {customVersion ?? "(auto)"}"); +Console.WriteLine($"Configuration: {configuration}"); +Console.WriteLine($"Validator Configuration: {validatorConfig}"); +Console.WriteLine($"License Server URL: {serverUrl}"); + +string binlogFlag = binlog ? "-bl" : ""; + +int step = 1; +DateTime stepStartTime = DateTime.Now; + +// Step 1: ensure other build scripts are up to date: +WriteStepHeader(step, "Updating build scripts to latest versions..."); +Console.WriteLine($"Running {scriptsDir}/ScriptBuilder.cs to update build scripts in {toolsDir}"); +await RunDotnetCommandWithOutputAsync(scriptsDir, "run", "ScriptBuilder.cs", "--exclude", "GeoBlazorBuild.cs"); +WriteStepCompleted(step, stepStartTime); +step++; + +string otherConfiguration = configuration.Equals("Release", StringComparison.OrdinalIgnoreCase) ? "Debug" : "Release"; + +// Lock file paths +string coreLockFilePath = Path.Combine(coreProjectPath, $"esBuild.{otherConfiguration}.lock"); +string proLockFilePath = Path.Combine(proProjectPath, $"esProBuild.{otherConfiguration}.lock"); + +// Check for existing locks from other configuration +if (File.Exists(coreLockFilePath) || File.Exists(proLockFilePath)) +{ + Console.WriteLine("Another instance of the esBuild scripts are already running, please wait."); + while (File.Exists(coreLockFilePath) || File.Exists(proLockFilePath)) + { + Thread.Sleep(1000); + Console.Write("."); + if (scriptStartTime.AddMinutes(1) < DateTime.Now) + { + if (File.Exists(coreLockFilePath)) + { + Console.WriteLine($"\nLock file {coreLockFilePath} still exists after 1 minute, removing stale lock."); + File.Delete(coreLockFilePath); + } + if (File.Exists(proLockFilePath)) + { + Console.WriteLine($"\nLock file {proLockFilePath} still exists after 1 minute, removing stale lock."); + File.Delete(proLockFilePath); + } + } + } + Console.WriteLine("Lock released, continuing..."); +} + +// Create lock files for current configuration +string currentCoreLockFilePath = Path.Combine(coreProjectPath, $"esBuild.{configuration}.lock"); +string currentProLockFilePath = Path.Combine(proProjectPath, $"esProBuild.{configuration}.lock"); + +try +{ + // Set environment variable + Environment.SetEnvironmentVariable("PipelineBuild", "true"); + + string version = customVersion ?? ""; + bool customVersionSet = !string.IsNullOrEmpty(customVersion); + + // Step 2: Clean old build artifacts + stepStartTime = DateTime.Now; + WriteStepHeader(step, "Cleaning old build artifacts"); + + await RunDotnetCommand(coreProjectPath, "clean", + $"\"{Path.Combine(coreProjectPath, "dymaptic.GeoBlazor.Core.csproj")}\"", "/p:PipelineBuild=true"); + DeleteDirectoryIfExists(Path.Combine(coreProjectPath, "bin")); + DeleteDirectoryIfExists(Path.Combine(coreProjectPath, "obj")); + DeleteDirectoryContentsIfExists(Path.Combine(coreProjectPath, "wwwroot", "js")); + DeleteDirectoryIfExists(Path.Combine(coreProjectPath, "node_modules"), usePowerShell: true); + + if (pro) + { + await RunDotnetCommand(proProjectPath, "clean", + $"\"{Path.Combine(proProjectPath, "dymaptic.GeoBlazor.Pro.csproj")}\"", "/p:PipelineBuild=true"); + DeleteDirectoryIfExists(Path.Combine(proProjectPath, "bin")); + DeleteDirectoryIfExists(Path.Combine(proProjectPath, "obj")); + DeleteDirectoryContentsIfExists(Path.Combine(proProjectPath, "obf")); + DeleteDirectoryContentsIfExists(Path.Combine(proProjectPath, "build", "resources")); + DeleteDirectoryContentsIfExists(Path.Combine(proProjectPath, "wwwroot", "js")); + DeleteDirectoryIfExists(Path.Combine(proProjectPath, "node_modules"), usePowerShell: true); + + if (Directory.Exists(validatorProjectPath)) + { + await RunDotnetCommand(validatorProjectPath, "clean", + $"\"{Path.Combine(validatorProjectPath, "dymaptic.GeoBlazor.Pro.V.csproj")}\""); + DeleteDirectoryIfExists(Path.Combine(validatorProjectPath, "bin")); + DeleteDirectoryIfExists(Path.Combine(validatorProjectPath, "obj")); + DeleteDirectoryContentsIfExists(Path.Combine(validatorProjectPath, "obf")); + } + } + WriteStepCompleted(step, stepStartTime); + step++; + + // Step 3: Update library versions (if no custom version specified) + if (!customVersionSet) + { + stepStartTime = DateTime.Now; + WriteStepHeader(step, "Updating Library Versions"); + + XDocument coreProps = XDocument.Load(corePropsPath); + string? currentCoreVersion = coreProps.Root?.Element("PropertyGroup")?.Element("CoreVersion")?.Value; + + string newCoreVersion = await BumpVersionAsync(coreRepoRoot, publishVersion, false); + + if (pro) + { + XDocument proProps = XDocument.Load(proPropsPath); + string? currentProVersion = proProps.Root?.Element("PropertyGroup")?.Element("ProVersion")?.Value; + + version = await BumpVersionAsync(proRepoRoot, publishVersion, true); + + // Compare versions and use the higher one + if (CompareVersions(newCoreVersion, version) > 0 && + CompareVersions(currentCoreVersion ?? "0.0.0", currentProVersion ?? "0.0.0") > 0) + { + version = newCoreVersion; + } + else if (CompareVersions(newCoreVersion, version) < 0) + { + Console.WriteLine($"Core version ({newCoreVersion}) and Pro version ({version}) do not match after bumping. Please ensure both versions are the same in Directory.Build.props."); + } + + if (currentProVersion == version) + { + Console.WriteLine($"Pro Version is already set to {version}, no update needed."); + } + else + { + Console.WriteLine($"Updating Pro Version from {currentProVersion} to {version}"); + proProps.Root?.Element("PropertyGroup")?.SetElementValue("ProVersion", version); + proProps.Save(proPropsPath); + } + } + else + { + version = newCoreVersion; + } + + if (currentCoreVersion == version) + { + Console.WriteLine($"Core Version is already set to {version}, no update needed."); + } + else + { + Console.WriteLine($"Updating Core Version from {currentCoreVersion} to {version}"); + coreProps.Root?.Element("PropertyGroup")?.SetElementValue("CoreVersion", version); + coreProps.Save(corePropsPath); + } + + WriteStepCompleted(step, stepStartTime); + step++; + } + + // Check for another lock for the current configuration + if (File.Exists(currentCoreLockFilePath) && + File.GetLastWriteTimeUtc(currentCoreLockFilePath) < DateTime.UtcNow.AddSeconds(-5)) + { + Console.WriteLine("Another instance of the esBuild script is already running, please wait."); + while (File.Exists(currentCoreLockFilePath)) + { + Thread.Sleep(1000); + Console.Write("."); + } + Console.WriteLine("Lock released, continuing..."); + } + + // Step 4: Build Core JavaScript + stepStartTime = DateTime.Now; + WriteStepHeader(step, "Building Core JavaScript"); + + int esBuildResult = await RunDotnetScriptAsync(toolsDir, "ESBuild.dll", $"-c {configuration}"); + if (esBuildResult != 0) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"ERROR: ESBuild.dll failed with exit code {esBuildResult}. Exiting."); + Console.ResetColor(); + return 1; + } + + // Verify JavaScript files were created + string coreJsPath = Path.Combine(coreProjectPath, "wwwroot", "js"); + if (!Directory.Exists(coreJsPath) || Directory.GetFiles(coreJsPath, "*.js").Length == 0) + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine($"WARNING: Core JavaScript files not found at {coreJsPath}, waiting..."); + Console.ResetColor(); + Thread.Sleep(2000); + if (!Directory.Exists(coreJsPath) || Directory.GetFiles(coreJsPath, "*.js").Length == 0) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("ERROR: Core JavaScript files still not found after waiting. Exiting."); + Console.ResetColor(); + return 1; + } + } + + WriteStepCompleted(step, stepStartTime); + step++; + + // Step 5: Restore .NET packages for Core + stepStartTime = DateTime.Now; + WriteStepHeader(step, "Restoring .NET Packages"); + + await RunDotnetCommand(coreProjectPath, "restore", "/p:PipelineBuild=true"); + + WriteStepCompleted(step, stepStartTime); + step++; + + // Step 6: Build Core Project and NuGet Package + stepStartTime = DateTime.Now; + WriteStepHeader(step, "Building Core Project and NuGet Package"); + + string[] coreBuildArgs = + [ + $"dymaptic.GeoBlazor.Core.csproj", + $"--no-restore", + "-c", + configuration, + $"/p:PipelineBuild=true", + $"/p:GenerateDocs={generateDocs.ToString().ToLower()}", + $"/p:GenerateXmlComments={generateXmlComments.ToString().ToLower()}", + $"/p:CoreVersion={version}", + $"/p:GeneratePackage={package.ToString().ToLower()}", + binlogFlag + ]; + + Console.WriteLine($"Executing 'dotnet build {string.Join(" ", coreBuildArgs)}'"); + + bool coreHasError = false; + for (int i = 1; i <= buildRetries; i++) + { + try + { + (int exitCode, List output) = await RunDotnetCommandWithOutputAsync(coreProjectPath, "build", coreBuildArgs); + + if (exitCode != 0) + { + Console.WriteLine($"ERROR: Core Build command failed with exit code {exitCode}. Exiting."); + coreHasError = true; + } + else + { + coreHasError = output.Any(line => + Regex.IsMatch(line, @"[1-9][0-9]* [Ee]rror(s)?") || + line.Contains("Build FAILED")); + if (!coreHasError) + { + break; + } + } + } + catch (Exception ex) + { + coreHasError = true; + Console.WriteLine($"Build attempt {i} of {buildRetries} failed with exception: {ex.Message}"); + } + + Console.WriteLine($"Build attempt {i} of {buildRetries} failed."); + if (i < buildRetries) + { + Console.WriteLine("Waiting 2 seconds before retrying..."); + Thread.Sleep(2000); + } + } + + if (coreHasError) + { + return 1; + } + + if (package) + { + // Copy generated NuGet package to repo root + string coreBinPath = Path.Combine(coreProjectPath, "bin", configuration); + if (Directory.Exists(coreBinPath)) + { + var coreNupkg = Directory.GetFiles(coreBinPath, "*.nupkg", SearchOption.AllDirectories) + .Select(f => new FileInfo(f)) + .OrderByDescending(f => f.LastWriteTime) + .FirstOrDefault(); + if (coreNupkg != null) + { + File.Copy(coreNupkg.FullName, Path.Combine(coreRepoRoot, coreNupkg.Name), true); + Console.WriteLine($"Copied {coreNupkg.Name} to {coreRepoRoot}"); + } + } + } + + WriteStepCompleted(step, stepStartTime); + step++; + + // Pro-specific steps + if (pro) + { + // Step 7: Restore Pro .NET packages + stepStartTime = DateTime.Now; + WriteStepHeader(step, "Restoring .NET Packages"); + + await RunDotnetCommand(proProjectPath, "restore", "/p:PipelineBuild=true"); + + WriteStepCompleted(step, stepStartTime); + step++; + + bool optOutFromObfuscation = !obfuscate; + + // Step 8: Build Validator (if exists) + if (Directory.Exists(validatorProjectPath)) + { + stepStartTime = DateTime.Now; + WriteStepHeader(step, $"Building Validator project in configuration {validatorConfig}"); + + // Set the ServerUrls in the Validator project + serverUrl = serverUrl.TrimEnd('/'); + Console.WriteLine($"Setting License Server Url to {serverUrl}"); + + string devBuildValidatorPath = Path.Combine(validatorProjectPath, "DevBuildValidator.cs"); + string publishTaskValidatorPath = Path.Combine(validatorProjectPath, "PublishTaskValidator.cs"); + + // Update DevBuildValidator.cs + string devValidatorContent = File.ReadAllText(devBuildValidatorPath); + devValidatorContent = Regex.Replace( + devValidatorContent, + @"public string SU \{ get; set; \} = null!;", + $"public string SU {{ get; set; }} = \"{serverUrl}/api/validate/v4\";"); + File.WriteAllText(devBuildValidatorPath, devValidatorContent); + Thread.Sleep(500); + + // Verify the update + devValidatorContent = File.ReadAllText(devBuildValidatorPath); + if (!devValidatorContent.Contains($"public string SU {{ get; set; }} = \"{serverUrl}/api/validate/v4\";")) + { + throw new Exception("Failed to set ServerUrl in DevBuildValidator.cs"); + } + + // Update PublishTaskValidator.cs + string publishValidatorContent = File.ReadAllText(publishTaskValidatorPath); + publishValidatorContent = Regex.Replace( + publishValidatorContent, + @"public string SU \{ get; set; \} = null!;", + $"public string SU {{ get; set; }} = \"{serverUrl}/api/validate/v4/publish\";"); + File.WriteAllText(publishTaskValidatorPath, publishValidatorContent); + Thread.Sleep(500); + + // Verify the update + publishValidatorContent = File.ReadAllText(publishTaskValidatorPath); + if (!publishValidatorContent.Contains($"public string SU {{ get; set; }} = \"{serverUrl}/api/validate/v4/publish\";")) + { + throw new Exception("Failed to set ServerUrl in PublishTaskValidator.cs"); + } + + // Build validator + string[] validatorBuildArgs = + [ + "dymaptic.GeoBlazor.Pro.V.csproj", + $"/p:OptOutFromObfuscation={optOutFromObfuscation.ToString().ToLower()}", + $"/p:ProVersion={version}", + "-c", + validatorConfig, + binlogFlag + ]; + + (int validatorExitCode, List validatorOutput) = await RunDotnetCommandWithOutputAsync(validatorProjectPath, "build", validatorBuildArgs); + + // Restore the ServerUrls in the Validator project + devValidatorContent = File.ReadAllText(devBuildValidatorPath); + devValidatorContent = Regex.Replace( + devValidatorContent, + @"public string SU \{ get; set; \} = "".*"";", + "public string SU { get; set; } = null!;"); + File.WriteAllText(devBuildValidatorPath, devValidatorContent); + + publishValidatorContent = File.ReadAllText(publishTaskValidatorPath); + publishValidatorContent = Regex.Replace( + publishValidatorContent, + @"public string SU \{ get; set; \} = "".*"";", + "public string SU { get; set; } = null!;"); + File.WriteAllText(publishTaskValidatorPath, publishValidatorContent); + + bool validatorHasError = validatorOutput.Any(line => + Regex.IsMatch(line, @"[1-9][0-9]* [Ee]rror(s)?") || + line.Contains("Build FAILED")); + if (validatorHasError) + { + return 1; + } + + WriteStepCompleted(step, stepStartTime); + step++; + } + + // Check for Pro lock + if (File.Exists(currentProLockFilePath) && + File.GetLastWriteTimeUtc(currentProLockFilePath) < DateTime.UtcNow.AddSeconds(-5)) + { + Console.WriteLine("Another instance of the esBuild scripts are already running, please wait."); + while (File.Exists(currentProLockFilePath)) + { + Thread.Sleep(1000); + Console.Write("."); + } + Console.WriteLine("Lock released, continuing..."); + } + + // Step 9: Build Pro JavaScript + stepStartTime = DateTime.Now; + WriteStepHeader(step, "Building Pro JavaScript"); + + int esProBuildResult = await RunDotnetScriptAsync(toolsDir, "ESBuild.dll", $"-c {configuration} --pro"); + if (esProBuildResult != 0) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"ERROR: esProBuild failed with exit code {esProBuildResult}. Exiting."); + Console.ResetColor(); + return 1; + } + + // Verify Pro JavaScript files were created + string proJsPath = Path.Combine(proProjectPath, "wwwroot", "js"); + if (!Directory.Exists(proJsPath) || Directory.GetFiles(proJsPath, "*.js").Length == 0) + { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine($"WARNING: Pro JavaScript files not found at {proJsPath}, waiting..."); + Console.ResetColor(); + Thread.Sleep(2000); + if (!Directory.Exists(proJsPath) || Directory.GetFiles(proJsPath, "*.js").Length == 0) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("ERROR: Pro JavaScript files still not found after waiting. Exiting."); + Console.ResetColor(); + return 1; + } + } + + WriteStepCompleted(step, stepStartTime); + step++; + + // Step 10: Build Pro project and package + stepStartTime = DateTime.Now; + WriteStepHeader(step, "Building Pro project and package"); + + string[] proBuildArgs = + [ + $"dymaptic.GeoBlazor.Pro.csproj", + "--no-restore", + $"-c", + configuration, + $"/p:PipelineBuild=true", + $"/p:GenerateDocs={generateDocs.ToString().ToLower()}", + $"/p:GenerateXmlComments={generateXmlComments.ToString().ToLower()}", + $"/p:CoreVersion={version}", + $"/p:ProVersion={version}", + $"/p:OptOutFromObfuscation={optOutFromObfuscation.ToString().ToLower()}", + $"/p:GeneratePackage={package.ToString().ToLower()}", + binlogFlag + ]; + + Console.WriteLine($"Executing 'dotnet {string.Join(" ", proBuildArgs)}'"); + + bool proHasError = false; + for (int i = 1; i <= buildRetries; i++) + { + try + { + (int exitCode, List output) = await RunDotnetCommandWithOutputAsync(proProjectPath, "build", proBuildArgs); + + if (exitCode != 0) + { + Console.WriteLine($"ERROR: Pro Build command failed with exit code {exitCode}. Exiting."); + proHasError = true; + } + else + { + proHasError = output.Any(line => + Regex.IsMatch(line, @"[1-9][0-9]* [Ee]rror(s)?") || + line.Contains("Build FAILED")); + if (!proHasError) + { + break; + } + } + } + catch (Exception ex) + { + proHasError = true; + Console.WriteLine($"Build attempt {i} of {buildRetries} failed with exception: {ex.Message}"); + } + + Console.WriteLine($"Build attempt {i} of {buildRetries} failed."); + if (i < buildRetries) + { + Console.WriteLine("Waiting 2 seconds before retrying..."); + Thread.Sleep(2000); + } + } + + if (proHasError) + { + return 1; + } + + if (package) + { + // Copy generated NuGet package to Core repo root + string proBinPath = Path.Combine(proProjectPath, "bin", configuration); + if (Directory.Exists(proBinPath)) + { + var proNupkg = Directory.GetFiles(proBinPath, "*.nupkg", SearchOption.AllDirectories) + .Select(f => new FileInfo(f)) + .OrderByDescending(f => f.LastWriteTime) + .FirstOrDefault(); + if (proNupkg != null) + { + File.Copy(proNupkg.FullName, Path.Combine(coreRepoRoot, proNupkg.Name), true); + Console.WriteLine($"Copied {proNupkg.Name} to {coreRepoRoot}"); + } + } + } + + WriteStepCompleted(step, stepStartTime); + } + + return 0; +} +catch (Exception ex) +{ + Console.WriteLine($"An error occurred: {ex.Message}"); + return 1; +} +finally +{ + TimeSpan totalTime = DateTime.Now - scriptStartTime; + + // Remove lock files + if (File.Exists(currentCoreLockFilePath)) + { + File.Delete(currentCoreLockFilePath); + } + if (File.Exists(currentProLockFilePath)) + { + File.Delete(currentProLockFilePath); + } + + Console.WriteLine(); + Console.BackgroundColor = ConsoleColor.DarkBlue; + Console.ForegroundColor = ConsoleColor.White; + Console.Write($"Total script execution time: {totalTime}."); + Console.ResetColor(); + Console.WriteLine(); +} + +// Helper methods + +static string GetScriptsDirectory([CallerFilePath] string? callerFilePath = null) +{ + // When running as a pre-compiled DLL, [CallerFilePath] contains the compile-time path + // which is invalid at runtime (especially in Docker containers). + // Detect this by checking if the file exists at the caller path. + if (!string.IsNullOrEmpty(callerFilePath) && File.Exists(callerFilePath)) + { + return Path.GetDirectoryName(callerFilePath)!; + } + + // Running as a DLL - use AppContext.BaseDirectory which points to the DLL location + // The DLL is in build-tools/, and scripts are in build-scripts/ (sibling directory) + string dllDirectory = AppContext.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + return Path.Combine(Path.GetDirectoryName(dllDirectory)!, "build-scripts"); +} + +static void WriteStepHeader(int step, string description) +{ + Console.WriteLine(); + Console.BackgroundColor = ConsoleColor.DarkMagenta; + Console.ForegroundColor = ConsoleColor.White; + Console.Write($"{step}. {description}"); + Console.ResetColor(); + Console.WriteLine(); + Console.WriteLine(); +} + +static void WriteStepCompleted(int step, DateTime stepStartTime) +{ + TimeSpan elapsed = DateTime.Now - stepStartTime; + Console.BackgroundColor = ConsoleColor.Yellow; + Console.ForegroundColor = ConsoleColor.Black; + Console.Write($"Step {step} completed in {elapsed}."); + Console.ResetColor(); + Console.WriteLine(); +} + +static void DeleteDirectoryIfExists(string path, bool usePowerShell = false) +{ + if (!Directory.Exists(path)) + { + return; + } + + try + { + if (usePowerShell) + { + // Use PowerShell 7 for cross-platform deletion - handles long paths on Windows + string escapedPath = path.Replace("'", "''"); + var psi = new ProcessStartInfo + { + FileName = "pwsh", + Arguments = $"-NoProfile -Command \"Remove-Item -LiteralPath '{escapedPath}' -Recurse -Force -ErrorAction Stop\"", + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardError = true + }; + using var process = Process.Start(psi); + process?.WaitForExit(60000); // 60 second timeout for large node_modules + + // Verify deletion + if (Directory.Exists(path)) + { + Console.WriteLine($"WARNING: Failed to delete {path} with PowerShell, trying .NET fallback..."); + Directory.Delete(path, true); + } + } + else + { + Directory.Delete(path, true); + } + + // Verify and wait for filesystem to settle + int retries = 10; + while (Directory.Exists(path) && retries > 0) + { + Thread.Sleep(100); + retries--; + } + + if (Directory.Exists(path)) + { + Console.WriteLine($"WARNING: Directory {path} still exists after deletion attempt"); + } + } + catch (Exception ex) + { + Console.WriteLine($"WARNING: Failed to delete {path}: {ex.Message}"); + } +} + +static void DeleteDirectoryContentsIfExists(string path) +{ + if (Directory.Exists(path)) + { + try + { + foreach (string file in Directory.GetFiles(path, "*", SearchOption.AllDirectories)) + { + File.Delete(file); + } + } + catch + { + // Files may be locked - continue + } + } +} + +static async Task RunDotnetCommand(string workingDirectory, string command, params string[] args) +{ + var psi = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = $"{command} {string.Join(" ", args.Where(a => !string.IsNullOrWhiteSpace(a)))}", + WorkingDirectory = workingDirectory, + UseShellExecute = false, + CreateNoWindow = true + }; + + using var process = Process.Start(psi); + if (process != null) + { + await process.WaitForExitAsync(); + } +} + +static async Task<(int ExitCode, List Output)> RunDotnetCommandWithOutputAsync(string workingDirectory, + string command, params string[] args) +{ + var output = new List(); + + var psi = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = $"{command} {string.Join(" ", args.Where(a => !string.IsNullOrWhiteSpace(a)))}", + WorkingDirectory = workingDirectory, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + using var process = Process.Start(psi); + if (process == null) + { + return (1, ["Failed to start dotnet"]); + } + + process.OutputDataReceived += (_, e) => + { + if (e.Data != null) + { + Console.WriteLine(e.Data); + output.Add(e.Data); + } + }; + + process.ErrorDataReceived += (_, e) => + { + if (e.Data != null) + { + Console.WriteLine(e.Data); + output.Add(e.Data); + } + }; + + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + await process.WaitForExitAsync(); + + return (process.ExitCode, output); +} + +static async Task RunDotnetScriptAsync(string workingDirectory, string scriptName, string args) +{ + var psi = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = $"{scriptName} {args}", + WorkingDirectory = workingDirectory, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + using var process = Process.Start(psi); + if (process == null) + { + return 1; + } + + process.OutputDataReceived += (_, e) => + { + if (e.Data != null) + { + Console.WriteLine(e.Data); + } + }; + + process.ErrorDataReceived += (_, e) => + { + if (e.Data != null) + { + Console.WriteLine(e.Data); + } + }; + + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + await process.WaitForExitAsync(); + + return process.ExitCode; +} + +static async Task BumpVersionAsync(string repoRoot, bool publish, bool isPro) +{ + string directoryBuildPropsPath = Path.Combine(repoRoot, "Directory.Build.props"); + XDocument propsContent = XDocument.Load(directoryBuildPropsPath); + + string? currentVersion = isPro + ? propsContent.Root?.Element("PropertyGroup")?.Element("ProVersion")?.Value + : propsContent.Root?.Element("PropertyGroup")?.Element("CoreVersion")?.Value; + + if (string.IsNullOrEmpty(currentVersion)) + { + throw new Exception($"Could not read {(isPro ? "Pro" : "Core")}Version from Directory.Build.props"); + } + + // Parse version: major.minor.patch.build-beta-betaVersion + var match = Regex.Match(currentVersion, @"(\d+)\.(\d+)\.(\d+)\.?(\d*)?-?(beta)?-?(\d*)?"); + if (!match.Success) + { + throw new Exception($"Could not parse version: {currentVersion}"); + } + + int majorVersion = int.Parse(match.Groups[1].Value); + int minorVersion = int.Parse(match.Groups[2].Value); + int patchVersion = int.Parse(match.Groups[3].Value); + int buildVersion = match.Groups[4].Success && !string.IsNullOrEmpty(match.Groups[4].Value) + ? int.Parse(match.Groups[4].Value) : 0; + bool isBeta = match.Groups[5].Success && !string.IsNullOrEmpty(match.Groups[5].Value); + int betaVersion = match.Groups[6].Success && !string.IsNullOrEmpty(match.Groups[6].Value) + ? int.Parse(match.Groups[6].Value) : 0; + + string newVersion; + + if (publish) + { + if (isBeta) + { + throw new Exception("Cannot publish a beta version. Please update the version in Directory.Build.props to a release version."); + } + + // Check the latest version on NuGet.org + string packageName = isPro ? "dymaptic.geoblazor.pro" : "dymaptic.geoblazor.core"; + string nugetUrl = $"https://azuresearch-usnc.nuget.org/query?q={packageName}&prerelease=false"; + + using var httpClient = new HttpClient(); + string response = await httpClient.GetStringAsync(nugetUrl); + using var doc = JsonDocument.Parse(response); + + string? latestVersion = null; + if (doc.RootElement.TryGetProperty("data", out var data) && data.GetArrayLength() > 0) + { + // Find the highest version + latestVersion = data.EnumerateArray() + .Select(d => d.GetProperty("version").GetString()) + .Where(v => v != null) + .OrderByDescending(v => Version.TryParse(v!.Split('-')[0], out var ver) ? ver : new Version(0, 0, 0)) + .FirstOrDefault(); + } + + if (string.IsNullOrEmpty(latestVersion)) + { + throw new Exception("Could not determine latest version from NuGet API."); + } + + var nugetMatch = Regex.Match(latestVersion, @"(\d+)\.(\d+)\.(\d+)\.?(\d*)?(-beta-)?(\d*)?"); + int nugetMajor = int.Parse(nugetMatch.Groups[1].Value); + int nugetMinor = int.Parse(nugetMatch.Groups[2].Value); + int nugetPatch = int.Parse(nugetMatch.Groups[3].Value); + + if (nugetMajor > majorVersion || + (nugetMajor == majorVersion && nugetMinor > minorVersion) || + (nugetMajor == majorVersion && nugetMinor == minorVersion && nugetPatch > patchVersion)) + { + throw new Exception("Version in NuGet is greater than local version. Please update the version in Directory.Build.props to match the latest version on Nuget.org."); + } + + if (nugetMajor == majorVersion && nugetMinor == minorVersion && nugetPatch == patchVersion) + { + // Increment the patch version for release + newVersion = $"{majorVersion}.{minorVersion}.{patchVersion + 1}"; + } + else + { + // Version is already higher than NuGet, just remove build number + newVersion = $"{majorVersion}.{minorVersion}.{patchVersion}"; + } + } + else + { + // For non-release builds, increment the build number + if (isBeta) + { + newVersion = $"{majorVersion}.{minorVersion}.{patchVersion}.{buildVersion}-beta-{betaVersion + 1}"; + } + else + { + newVersion = $"{majorVersion}.{minorVersion}.{patchVersion}.{buildVersion + 1}"; + } + } + + return newVersion; +} + +static int CompareVersions(string version1, string version2) +{ + // Simple version comparison - extract numeric parts + var v1Match = Regex.Match(version1, @"(\d+)\.(\d+)\.(\d+)\.?(\d*)?"); + var v2Match = Regex.Match(version2, @"(\d+)\.(\d+)\.(\d+)\.?(\d*)?"); + + if (!v1Match.Success || !v2Match.Success) + { + return string.Compare(version1, version2, StringComparison.Ordinal); + } + + int major1 = int.Parse(v1Match.Groups[1].Value); + int minor1 = int.Parse(v1Match.Groups[2].Value); + int patch1 = int.Parse(v1Match.Groups[3].Value); + int build1 = v1Match.Groups[4].Success && !string.IsNullOrEmpty(v1Match.Groups[4].Value) + ? int.Parse(v1Match.Groups[4].Value) : 0; + + int major2 = int.Parse(v2Match.Groups[1].Value); + int minor2 = int.Parse(v2Match.Groups[2].Value); + int patch2 = int.Parse(v2Match.Groups[3].Value); + int build2 = v2Match.Groups[4].Success && !string.IsNullOrEmpty(v2Match.Groups[4].Value) + ? int.Parse(v2Match.Groups[4].Value) : 0; + + if (major1 != major2) return major1.CompareTo(major2); + if (minor1 != minor2) return minor1.CompareTo(minor2); + if (patch1 != patch2) return patch1.CompareTo(patch2); + return build1.CompareTo(build2); +} diff --git a/build-scripts/ScriptBuilder.cs b/build-scripts/ScriptBuilder.cs new file mode 100644 index 000000000..2337cdf8c --- /dev/null +++ b/build-scripts/ScriptBuilder.cs @@ -0,0 +1,125 @@ +#!/usr/bin/env dotnet + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +// Builds all C# scripts in the current directory using dotnet build. +// Outputs built DLLs to ../build-tools/ +// Usage: dotnet ScriptBuilder.cs +// Can also pass in script names to build specific scripts only: +// Usage: dotnet ScriptBuilder.cs Script1.cs Script2.cs ... +// or the --exclude option to skip specific scripts: +// Usage: dotnet ScriptBuilder.cs --exclude Script1.cs Script2.cs ... + +bool excludeMode = false; +HashSet scriptsToProcess = new(); +string scriptDir = GetScriptDirectory(); +string outDir = Path.GetFullPath(Path.Combine(scriptDir, "..", "build-tools")); + +string[] scripts = Directory.GetFiles(scriptDir, "*.cs"); + +for (int i = 0; i < args.Length; i++) +{ + string arg = args[i].ToLowerInvariant(); + + switch (arg) + { + case "--exclude": + excludeMode = true; + break; + default: + scriptsToProcess.Add(arg); + break; + } +} + +foreach (string script in scripts) +{ + if (Path.GetFileName(script) == "ScriptBuilder.cs") + { + continue; + } + + if (scriptsToProcess.Count > 0) + { + if (excludeMode && scriptsToProcess.Contains(Path.GetFileName(script))) + { + Console.WriteLine($"Skipping excluded script: {Path.GetFileName(script)}"); + continue; + } + else if (!excludeMode && !scriptsToProcess.Contains(Path.GetFileName(script))) + { + Console.WriteLine($"Skipping unlisted script: {Path.GetFileName(script)}"); + continue; + } + } + + int returnCode = BuildScript(Path.GetFileName(script), scriptDir, outDir); + if (returnCode != 0) + { + return returnCode; + } +} + +return 0; + + + +static int BuildScript(string scriptName, string scriptDir, string outDir) +{ + string[] args = + [ + "build", + scriptName, + "-c", + "Release", + "-o", + outDir + ]; + + ProcessStartInfo psi = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = string.Join(" ", args), + WorkingDirectory = scriptDir, + RedirectStandardInput = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false + }; + + using Process? process = Process.Start(psi); + if (process is null) + { + Console.WriteLine($"Failed to build {scriptName}"); + return 1; + } + + // Read output asynchronously + process.OutputDataReceived += (sender, e) => + { + if (e.Data is not null) + { + Console.WriteLine(e.Data); + } + }; + + process.ErrorDataReceived += (sender, e) => + { + if (e.Data is not null) + { + Console.WriteLine(e.Data); + } + }; + + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + process.WaitForExit(); + return process.ExitCode; +} + + +static string GetScriptDirectory([CallerFilePath] string? callerFilePath = null) +{ + return Path.GetDirectoryName(callerFilePath) ?? Environment.CurrentDirectory; +} \ No newline at end of file diff --git a/build-tools/BuildAppSettings.deps.json b/build-tools/BuildAppSettings.deps.json new file mode 100644 index 000000000..741cd3fa3 --- /dev/null +++ b/build-tools/BuildAppSettings.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "BuildAppSettings/1.0.0": { + "runtime": { + "BuildAppSettings.dll": {} + } + } + } + }, + "libraries": { + "BuildAppSettings/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/build-tools/BuildAppSettings.dll b/build-tools/BuildAppSettings.dll new file mode 100644 index 0000000000000000000000000000000000000000..e98050367808ad86d5b1283e5000451a17a23dd8 GIT binary patch literal 10240 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 literal 0 HcmV?d00001 diff --git a/build-tools/BuildAppSettings.exe b/build-tools/BuildAppSettings.exe new file mode 100644 index 0000000000000000000000000000000000000000..fb1f90b5edd4ea9e0ca1c544de57428998bad529 GIT binary patch literal 162304 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 Z-v>JfY~#hB%rsu%z*zp>9!M4c{SS7`=}Z6s literal 0 HcmV?d00001 diff --git a/build-tools/BuildAppSettings.runtimeconfig.json b/build-tools/BuildAppSettings.runtimeconfig.json new file mode 100644 index 000000000..30e44d148 --- /dev/null +++ b/build-tools/BuildAppSettings.runtimeconfig.json @@ -0,0 +1,36 @@ +{ + "runtimeOptions": { + "tfm": "net10.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "10.0.0" + }, + "configProperties": { + "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\BuildAppSettings.cs", + "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, + "System.ComponentModel.DefaultValueAttribute.IsSupported": false, + "System.ComponentModel.Design.IDesignerHost.IsSupported": false, + "System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization": false, + "System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported": false, + "System.Data.DataSet.XmlSerializationIsSupported": false, + "System.Diagnostics.Tracing.EventSource.IsSupported": false, + "System.Linq.Enumerable.IsSizeOptimized": true, + "System.Net.SocketsHttpHandler.Http3Support": false, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Resources.ResourceManager.AllowCustomResourceTypes": false, + "System.Resources.UseSystemResourceKeys": false, + "System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported": false, + "System.Runtime.InteropServices.BuiltInComInterop.IsSupported": false, + "System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting": false, + "System.Runtime.InteropServices.EnableCppCLIHostActivation": false, + "System.Runtime.InteropServices.Marshalling.EnableGeneratedComInterfaceComImportInterop": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false, + "System.StartupHookProvider.IsSupported": false, + "System.Text.Encoding.EnableUnsafeUTF7Encoding": false, + "System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault": false, + "System.Threading.Thread.EnableAutoreleasePool": false, + "System.Linq.Expressions.CanEmitObjectArrayDelegate": false + } + } +} \ No newline at end of file diff --git a/build-tools/BuildTemplates.deps.json b/build-tools/BuildTemplates.deps.json new file mode 100644 index 000000000..3e618ad81 --- /dev/null +++ b/build-tools/BuildTemplates.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "BuildTemplates/1.0.0": { + "runtime": { + "BuildTemplates.dll": {} + } + } + } + }, + "libraries": { + "BuildTemplates/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/build-tools/BuildTemplates.dll b/build-tools/BuildTemplates.dll new file mode 100644 index 0000000000000000000000000000000000000000..282cdf9ba568715f74c2722c8d1a2ec21ea2fc67 GIT binary patch literal 23040 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

-5W7S;oh`&in^7whj`{q@sDUGZ11F*6*Obw2Vb$`kY*14r<&RCHuI6DIzGCBhFW-hBwshP z4a7Kp<&&Zhbv3(#{)w-qE=5yEgst4bzZz*~FcHEaaW{?~a|nqLuGwo2mH+(#HU`2D z1Lc~%bBauTsR8zD{vWN;jc(1!p&Wh^Jph`$V1EHGu-jh(-+s88xj)gHt8Xd~`0s7C zUo+Ml6Fc{;69vs5S2WXMk;)uSTK*gVg(I5taVd+4m+$Lkx%aX_FRyqnm+0koy=4Cx ze_DB-5XOX~be~c`M}oM_z_WjFhD^S7vSszrL0ztkGCoZ@Qs%i*4gl{;gCxv8w@cEc zbC2wv>s$WY*e@7K*TOfY&g@dMY7P#J+Gc~*}XcxsYz?v8mlo2$aU{z zO^vF;Lr_a9n=-#wUi1hPe9wuYUK1K+PB!8l1Dn0ZJN}r3j%S}*Wcut2OwTeG4Xhw} z>l^@C4OPH+WqjquHT1z~LoH<|Xsw++Qzus9pSYX}b?O=P6 z+H~#;OXWmw2QwN+v+r1((egKSs8==X{I~s(_Bg2_EUsL~RSIZ9n@y|8d>Ty=+Ys77 zsdg7$j~3hi_zUh^%jc5!@y)@v*FYJfMy~U-F+H|~7VkGgdKo6f{UM#9ujDe8_s|b~ zGHhNMk?Nh56~=}41S@%cen+V$a%2z3Anw4~ZPOXeVb@>YgD5ZaE!?vNR&)Nr^Qo6Y z2~NF$nq^nuD^^Dh^yfS>&`?b)L)_nGyS^bJ5~m^l_`2L7zAA-0yPSq-go}C&SUTaU z%sLW4Hss!Ey5UrkOYSYFQX1w6F5aPzmCG0nMV+Tk(BMJA4z#Gcx_K-=&bdY`K2v}B zcgTK*CG8P7p?b}l?fd-|nN2OgxhnUhzkR^?hv4-kmdK^_Vb8}-s*%TwMCZFH+nX?4 zxcK95x>p%0g+pvz7#NoDUT5z%5=q@sPkDZyBEeM8D+QJyB_4QZg@>0{V)jwVm`E-W_HVJ@^m2ed2P| z=1nKip`h6*zQ&XMc&08l(}Pkcqm0)zo>`f)XMXz-&w^p}W|K4gcrz_aet-iC0LT{^ zL({Qvun`H0L|Obz-{)gEITxKKbi{lL!?3a1q^^oz$k$F5bF#-`mX~$H_;lrPwJQe3 z$MNn>+nJu|$CcbNQy2y5L@sk#@4u~9t=j8l3E@9)t>$(Pz3MC>vgK_1uGwBLs^D0H z-v1NGd(k7O8(6Woxv(;EUvf~{0PBzodk+EDhe;2OKQ1@$YP!;=;i+d(*8I6cxbjC;{kxC1c3i|NdTY~lo9S){vrSvML~A}^sIr{b(aT(J%|tR5jd3> z3JNHErwn$TK%k%;+h}0#8I(yF%Z@n>V4O_eT4-ifEmY;qpaQ%__Bbc~T|}py16Jm| zok{!EB10fPm#s>0m`F(-bFBQxKtpCUpwZF=8l0~?8hkKT4$E0H(}=yJkh$Osc#k#^{B(CL(BEuNwZRq03FvJ5M+6Oz^X_k8e(!c3W%j`VqM67z9MldaB> zknQTUR!$eX!SQVWZSQOSn02YM23_~QdD#`Se1;Hj>LRl`x`=c$bNc>8w6vSeXj?+G zbjMHuQhlOhGySCyGg&-kDDz!VXhtE|4~+uat!0|(rMbid#92)AS9tKkGhRtq#6#Vq zHIk_N2R~H_WVqzi2Z2+ba})l<%Y@M|DUovLd+zI07P`dd(Hgl{RpTw*ah`wA@cyw> z!~5iD*Ccj(fj5-QgxFJ?5803&{MUi_1JlYqw1S-rk5v{xBp~i)I7vozqTwxGD{dfH zByc`vB?FX_s}6!v_dqNp7|hbkW?q&#FY+CqWb=1}`MbvaeOiBW|B3%_&mY;n5StUw z>;s6$iC`hZG5k(xBFIlmsq<*Q=Iuhr%9JYS*LsnG%Pd&=eP!zGtPidFtJf)PSF-FG zeuRB%}d-weKhHru9)90{dw5y&)sf+?(_Py=%4A&M|i3JyZdtxE0*B%8o$8D(GT!x zH?Lm-pT_^^{-lSen}|X){EtiYH-0?|CH&Ct5t+w>hV_ z!@|>;ILv&6YFUYX;03v@V*h|%&O|imlzhRIM7;10m}cY3tjFJs3ROWvrUHy^*;>LC z9B%F9sfacYHA%qHaB*?)9Ksutdtsoj)Tgg2zvs0Ro$ZA2NNL%y%8DRhCcPESs`f zu2+_>c`nnDm}J?gk(p{H9hzsKn`c2b&({vkb2M@m^)zSm^fGxw5VXCvJtVjk;zHDJ z#oyRz6%eTB+2{~szx~Lsn-@nN*%o6TY$?}CqW9xFkF^Tgm1hv=iSmDwNA>RMV}0KB zNIrUn3;}fSqj9y_4Q6k;R)=!l-ia``a|+{ z_h5N+IJ-;L++pYgi|3UhWG?<>5g+_NYAM)|sxbCL9*#Cwi4@O0oKOYz^Li6>pfpv; z-(vC+3p{p$=iDRPk=(x)XkptXh{05NrjECGj~~d7UG3%D320H1H5k8H?Y(%;D*n;8 z6z~8odd-380RIz3gxThpl`oHDRtI9ciN)=2LgLkt&RQuzo~WI6&`NLgyk_C&V++U= zdna|h*Y-*>r@q&%kuyyrgXSSGST&zSkMR6*8{IQqrm<&Z?w+jAlPR+jPyxZV)vdRN;Xv=POw}Jah{WnZ8 z{Y8w`M5$AGE7WtlU5&K_=lBqCrtAoDBWf6{%d2%bB9sN~*6i>;$YhCsnvMw!vEOQ- z-;1a)9Cg*f*NVEK*ERCo7t$i)uh-!t{X%nc|0lV)xApESSCO3qyB(g2+} z<*0zPLjwWvx`Q{guRFM~u3W2j_65A2b@PKJdCZ0S-LiYv+Ba?)`JHKiG*!IrZ?CLh z_wno(eCs}+`?s}k#LnKj?r*QPu6^UWiS6rly|QuLXZ0;`C^u8fR8!%cHSsr#qPOT& zmlQZGXs&B@zJ5two+`agt^4|`na^K&ZrzKo`F8#<&mFtBuKRfI8|!w>e$hwOXJ1ji z_KmA1w%Hq3(BHgmJJ)^u$_uo#HQjbXd-S-E{7=KrggpXS^OIQ4ss37Xu;5kWhm%RC*@L5*3$*z z1md3znm1+Lf!*+foBd56QfZg-nx^CSvpPK3(oqn9V{H8O!Hna;^=*LRj4eDoyKdJ< zTh{GLiJ^==XD(tk`Yg_Pif}kTx}5IfsDJnjohMaAqJLN#UyJPqh{2-<$P`9Wd|?GMQ)A_JVye2*rEq65WeyHmbGhcJbrb){;ui8 zmlpcizV^*)j^C26zgv5)U31Ox?FDP!m8EeVhe>tio@aG^7;a|id-w1e ze%SW)3E{J7KO3&(La;3naZ`T@aTSEW=>kiC% zC2#GUR}Fq8KUBHVvmdN`J2q)2I$w>`oWoX?EEJ~TQZgf=+oJNH+RlKAVNg(_PZ zU@16t7h{TT1d+Bf_a_ZOPtf|2T8{-#Cr zkPoq4;;oPhOwJxEa=+1oJ<%r~EQ~(tjVe^RVTS*DZdm>nzq2-E&VxWL#B72$%Siy z5U)F2XDkDreLPSS6{5v3ASnaRQ-Wfpe5qf6i}5!;agMaa^GKp$>81Kp)4itJ>Vnv!UcuJ1#Qs9bVb-h8(DdQQD?+_ zGZLq#h!25UFIYXh*uUgFJ_PMah4GGjf72(x(>!1S%zIKwdv=#4;%q4EPm0Li*{fpb z=;m07|M7vkjU_Ms#<0{t68DVW>0k0X34DmZ;ddjmhSF<7jnIMCIadeoEU0K6y~w}h zY4Tte>1VHwzdp8QXK#B;Fx}j*oviUxeylxtTOJ_?#-veI`)|jRK^*4904~(-_?fA@ zudzr`z99a3k=5c9Y@_->qyDby!yj{` zr&g-+)iHC(wvyB3d(ys{*lT5rKISzsu=swQMvp+n(hGQvuNgt?m6)S? za?}Av)+$fnk;8405?cq_h3FiDP8!osIe65Jum|a@eF#jKICa;SdHTCXaAC zFwt~i{0P&7r0*7TB31_Ww&q7mR*h1(n3u_#7nd4VdG)*Vz$~nkT<h{2dS z3Y4bH-e+mZ_Xa==!lT)&Q9i<$rOVp+rqEBT<(1_;Cw0APeYvR?3)P`>Cwu`kz@TE1 z3OA$PxTc*ae{BmIGYgnI_o_I^Qvynm@zW5W70>q-Q2A}VKgriXe!z#-B%|f(nC8+? zgV**2I$#qmqV&@$?V@iE4lzF~g$#}lR0SHiGh<&fF@s0724rP%XCpxzucWU*jV3M} zoVc)DxU}@<3M(;S=>@2A%BJ$kc?;{P{G=G00eM%PS~TW{h?(ylF@?lvr0(^;%Sp<2 zPDAQrHZ5LUd@^$W2rr~?=OkPm{o+ZO%(u({bM_CxAv4YQeX5x$c|DBR!;g)~4~|%^ zzD*?PpR-#TTp)Ek3YSVfne`z2+o9P95G6;_(S!Yq7vcS|FrtNYKBX=DvVf+G0F6XE z19`rdMV>#*(dRZ52UAPA^UUB+y6nIBuu2O}l{_sdxKzobF&Ua_+20(MI-=GdPbXd; zxj{&pF1yrJdbHNk+gO*X)Fg)WA*%*!D6>=LD+?B1fXaWXXR|+#Fi<`nXYu%+c&5qo-Qy`H>kN<&-JU) zX?9Jh?FG8)EpL^W?${s_=J=DrXKF(~P1D+0`nPY?C}Cy0o^(Tf~9YwvJ=IDvT*vydoQX*m4bNxy z7ds0zQ>9LU*B~h*aLHAj0HlK|964v^`?x6y?yByx_&mNTb03w#DD;;)sS0J=;UB=k z>O`M3spG=L!9cFLZvyFXuIEs}$Eo!eiajtnt!Rwf(vMu``>`Gpa}2auj=( zy*bpfU+fB8%SD6x`+xUra4Em(R!)~mFG9R+hOwYsA!C_Dk2tWa2^U;r0I1UtR20F8 zy=8_jD2N`uf=OnU+vj~_=>Wreq%JW=J@_0;Ffi20OlZ&!7P83Y#j6kQq(jR_n3;y@ zfqq|WxS%3)nlXBqa|+=^vK$V*XaL#27|#gE1D?f(7);Z#kqi4iB%2Q{5F`li; z18;!hU}p(k>lxX^L#2lwpo{vg)-P`LtCssInI8Uum;STwx!<>#U-ukBq4YJ;6Vqic zkcmS@AD;^eO_uGo_#w<#qU0?lBnpvcS#-{>@gizH;6#0>aR(f=dp+5b4Y#t#q4#TZ zR#Tv6O|l_>K`(ndhhCO42DnOrI=~}aqB#+62nSw|nHjL`=M4BMv4~veBx1TOVERaS zOE+{d^FNDj)pr_$I_Yh)bRq?s_631+dq=NPajl&xnnPX@9O+$ zUzbV~BNN8MBXiPik8m!e4jMVmocR$tYn5{VsirMDXk_yq%m2rc<&zn}-#y?%K}G9*3BKk#`=LdSe+Zr!vY0lf1~~`&o0mQ?1H(v9z32J3WyZW{Og$y@>>aVI z;|KEReb?ClKt2M{5hyJpqDHer}u}=d-POV7%3a>@9(9#nttYpV+h&{a9Qxs)K`L7lkWV`=7V~8EN%k6!iWlg1yDThm-xEwGx9WLN!~W zgY8NE&Dmfql?5%~n&#PTSgS{*UW0TXa~LSaZ>q?!_FzZF2J;ab_#>EiDc(u64Vx49xNVLrn;e54W2wH)Y-TF=;nRf(SNv13wYqx zYc^8nG>SXB!6z2-H}(9$Xt|?0^LREn5`&#QIAnDAbDR_CChcC%kMlp&?W~3+q~PAM zX2!qaJWNH->n?WoC+9b)%-PCUXOx~s>d$#<46}W}mZ4c`Eez6<`PUV0q9$ z+*@pKrkR`-W5za(qGl0ut%cS^nsUw?HL6=9?RbP5h4ZpScj^S(L4Wj_YrHs{Ilv(~ zuoTs}^K%mK+-{d#30(xa@fhPP%VkolZz4&&h@`Cet^vUh`Eiak!;a!S&9{ynZiXA& z48_W@=R5=!Umr??f_bT8{F6;vOm#afxU&Xy7AqYe#np|HaE>PxcnpNH2b1-^#Ksk* z%kH^`x*o{M3*`mqW)M0!(a(8;hMWcbf!A<;YJLYh%lH-TwYS;D&P;4vOsm}TXkaRC zM=_uCHFAvH`p0}{2JIsI4LxX;KDi^HsvqD_?zf(HU#(P zaY5{sC@S?paip=naNqVYCbq`5@CjQ&jcd3$9*%i@shAx&;Jvl^1^#HM|8ag-BIKs6 z6I#LrZQ+r$wc)akp&V`(Ucl8{t3Y+kzIdKeuGZY(|M}t%u8&@I?cxuwx&Eq9zb&?7 zy0!SDiC0}8>$fdwrTss*55%qU7;E}e{W14#tIby_^>Aid9 zMUNXZOFu{X9y#z?I=;VrUWEk?dg$c;Ma!H)wZz7oKg*ly&x;lWg2^C)8a?=s4c5Qv%|3JbQLY!|{!wRC8VgEHxTvJ{iT~%d_SO{@ zz_rF%U<%dRI6e9hvXlB(y*r4jn&LZmxB5=*{B#VD zt-fLW?M+@X9qo_vLWC24emmit%dLLx@+K|k(@=l>GgT<_N=5I{z5Ppe@oM|t##H-% zJL7G|t-h^17Lb_mweu9*+fp9=cD${;)whyYu!#?{{jSW*D}X8VJ-~DA2}DKR`8nPE zq26jX#Bgt>h2vMByE-v4*Gf3iINx_fGf{sI9EU8&1l@Qn_!7bwWuo zMPZ@x`5B!*7ggr#&+z);>28H(bC9;^APwz2d`=&J&U%SY^y2c05l}C9-72jrN&ls; zp3KIU+W^Iy33kq+bMwnNpNZNmgnUP&$B29$JEQ{E#Z?EwNx1NKD1lv9STSSoc7v>S zM{fx3+fiH4R=Z?!VRS&4*z?jEy=2+XIcKucJe`r@v&CQQ+_K26dm1sbYIFD@)<&2O zGAvpe8Tm>WiEVJWvYq1#+pY@RLx)S;h}3MGbHt3`;y3d4M3VoL$EpjiFHmX><0NGn zF_wtY~+do~eZL9he<~6HNm%-d_;!CDi`W44cUGI-t z$$m+hU-F&Jw#b}|eeNXoojXzRIls}o1N~9V@b@)u$aMg^8Q}Wz^=|tv)lb5=ah%?a z)aTnw(N^EDNKqGBeGl-IPfe}9-*`{P@MnFmSzF=HRI;@&U#q7x-7X1Lsp4>9c_tA- zswA38q~PEOpx7Tl3YRfTPVomWyjV0Sz%HLID_}sD{pfxw9f@~)vpEdQgs011pUxM? ziUL6{smQD|#ZVjGI?T=oWU8bfdm4^T4Q%9Vc$9;U^BuD$P=@K>WZ zH%P<0jBLi!mOkQLzNXbT5SxSkdHO`+F+Effkn)2&ZAI*Nc+meE71N_ad*gE_t<-{c znjwPHr$qJySG0@A{9TY<^O`O@iOiP$6NhY8^4{%yWbPSZx~xcFsAsHYyXnc~PJKRf zbZAABjy`F8s#Xu>!lfstslFv``Y3VUN-R-J>WfJXuDDMP8x&Zwlt*WPdghft8ktUO z^<^*x{9dHtr_07tr@b98f<06yBuUoMBm!o->|8ZSOM!IRIXuF*l*B*Hj}|Ab0%w)c zEB?5m9bjRX6wC-#)G>CXfjM){+@Ke{g0Bqw+?6gjTO6yh8m-ZbN9P;v^@LR}_j*zO z;MkGzr}CTV(_wQvndftQh;t-%equ&`I3 zOfR53_13<2UO&<+776BIMP5LtEf>czA_D2*=hN(_O*r1jZ>^d%m#-X)PrMZ`u5jKF z9}zDma-0 zHO1I_XLq;+*?`!kZ#m_Mx#b6UE5GQ=%G+xdlSHve6r)73N-hN7rbAm=1KS0Dk{mwo zasH_70CHY0{ke45Bd8bT2RQUscdQ2(?{p;DL-(aShlGTh4l9^ggIIQ_e#P3 z>_E`zV0?pT1ep9aA%kl-k}+XRD3Py%(ZhnaMFG5M`{#!eeL}9!WDj$Zy*_@r;lN;= zYg!Nxjmx)b_DJ5 z;8Hko8JWw2c0nk{ho?H`_j@K>gL^Z4z{DneosDoOz=GIaHUbJFC%ig8A^jnAzH9Ko zLdDC8VQmlSbEW6ach$Th)V)&k22uA)%^T8Z)Vx8|y;AdrQ1>ofM9m~kCux>tFIwil z&higP=!=zDtP~nrG)!-GcSB02@cV$(ST`-4sQUwP^>5()fBlcwE##Mbd#u46Pbm)- zOe&5P;D+5;cQxtnhU{?xZDtH_+=y@@@*^ETOGKUsK@bvCp9$FmsqJMqJUrRTA>f;} zS#U3811;MTzdV_qeP4XR+MVJXd5^Gn9R97Qg`qb%l9ua@#PIC51|t)-^t5k<}n$S`@L#SF=Pv#*q1*v^hf z?Q%XrrgJOH+M%4YPBDClbV0A^vmKb8p{Yu1b<<{gX;~S>dDyK>nNc`(rvI0lt^%aH zG?%?}CVT2Eqc50_NXBg8d$(sj+p36dYv8Xe0hrdnTl#Gcyl-9;^^8B$jD5u@=UlID zM@RaM$xW0gOz4QPJ+T;9?D9PJi~?(Vo!!S-ydMH49$zeIpi_TNky&ijBh&;kp4fh~ zLXq+=MtN(n9fHJD+UEu*)13VEbP`PB%SiYS%0Jt02n%(qvu%YiNK%%R>1{yA~eD|k?K?Bsblx%l@bZh4vw&hJ4WSjxr|fn z&q)`X4iK6){YEElJ9kQ=uJC_&7lVHcO-P zpE}$rqtW>Ms=Ql^oxVJ#Ex-v(v&{I%fJ^!TjLOB1V_q6YIBUOdSbxbE&Nd~+o67;I zkq?yijGHzhH*J|$#`bNg#%ZDp@RH;!8Yoj(f4t42ussKpM65`EgoL#L)-gr!eRJ)Bn zfB?O#gH`?qnsZ@t!wFft$UtW`K*LB<zM__ZQl`?b?lnIyijW3Z>OGHjX6|6TvynU zbUWvsmfp?xTW?)_o>@=e!a_c> z2^Das_3`2&57SrDp+#ItX%8Y4=)^#%;04VN^k*Wo#>A$}{xXI7Kc+~!wWh{@8$qel z9e<{AT=bseCuHAH9;$r5;{l$DO%y5EFfKdV1ZjHHaOW%pQ039FVqLkx8h=~>16YW6 zFngHtDDc4%%3WH`|FM30?9XHWXp!WA_Su_i4v*=)S-M$J#rJSSeDs>UXsKPu`F|%i zO!dc3OdUxuS;iVnOtd(5yRrWt^CJaogXwmHLfHjDZpOH6Dnl@O6p`HkWVZ^Qkx-Iz zc+Q5Bly4S(js@H;hgC_7qEE-{ubFj}p>_HdUI{A)z~40!&0KappL0KkKo>#HdORFB zXg&H&nsbghV8B-;8 z$$yiVQy*8WC0Ot02}Y`jgHO^8#q;fXtH`01@iCWBLpoLnovlol-5gd2>PW(1@hoVB zjn~E_Yx}y>_Mj+e=bcF zbwvaT+XPX0hS3Hq?@XP zhF%K`Us`LIeo1beAmFhJ_H#J8V6|1i5%BG^E0rJTQ<%-38VDjvZ+kEOY+cQo*}r0$ z`DOEw3Swxh-7xXQ?Mq;Y<+4r=ss zCgR_Vn{ZJIzT#!}4S&;YIP-Ah&EEGD&G-K1`{ux?8%zC7xQXUf-`qder~2kXe-fQ7 zZ-oo`*yH zO0}h?Q?5A51%DB(Kz~!eOrBmQ&ta*tRGE(g!k$V7I=Wl)t4iMCA<{SjY5jTUXcl8I ze(N9{i+`o>)#v$}eyj)kuu$^iVrLu2v}v$ID#%ddm4lhQe$K@olbGyZARug}@z|N6 z>RU$moBl%u)q*G=xd*8Vb)p(ISpLc%Es!Ua@jMnhp=(n>qe@5WX+?t~kgLn3> zDBQdK=neaJq+9F*(x2L`u~{Uxs6XrVr-eVu zoG0~H>&xXWv-9rREj}Qm$jDcM)eVKW__&Zzs+Rf8(z(tHSRLa|esnY%$Jo^beq&hY zk8mDiwiVi;aqeJ-(Z?BMx<9lkXpFbUlwm?Zj5&${S7nRc+O1e`uUKb+JPIuHh>cMK zaDfyfl-Y-_rggFUY&DxFR;-$6Y%E@+jmvC$`dHh zLltex3K7R&m!;CK5Y>M*8sWPtq=K^=uPC)|EVfT~CVhn6`L2rnN-W?$ye1PhHezpH ziU!-9qPxqqt589fxPSmW&?uKBfDfX1v#B~Wb_*MRT(Mjgp|i_9+YR466$3+-2}wT0 zg#%a@)T9k7Ruq4aTgn{q!EHfH;Ni-xu@Q1c~9`yjYgan&VlRpTddjmb09Z zOQz>Jhhr81->p1*Pjs+z#Q~;u{``afB`aWCgZ5l2{`X#~VNRWw9v$SI%cDJOzH+6Ecc?&oVKKssZ^Ew+rlTi^8mE927Z=N4!wAHpQTZMb%oh=~D%*`ZQRoXh zgh4DX&*h^1OWtH4L|Q5IFOhZLp6Ce+hh>BX{~av`S_`Z4{7W9^(OHhLg(Fuv{L_CH z@V-p%_WW|^4)ZW<zrO&;Tm~B%Dnj@LhVdP2_f)jSW|mv0>TfI%N~=gKElz=XcI> zo5J=#);Y=4-Z083HxI&Zgve3!D9@?JAOZ7M9sJZ1ZnGyJQSMMIk)<_tZT`4yV72yD%fiWH>|Y*C&#?TrZd6dk?^uZ| z7WqrZ4^|2;g>_4bE^#-i^E{~(nX$Xed5+i$0Xuc6Het4c$E=R?*= ztz9vg1C5PWt=Hg;7N@Zn$10X(bEDJt4;f%3lD>12scD&00!{QFF@Q7%{RNy zxQUETA8n5D`5cS58l9uL4CLbNBrRSm0@g|DIQYi}!o&w^6E##&sTz<7?k=!bKfF(7 z!ESPXN-T^`&ZF8Qkf5F4>VadKvoMT|a2A`7Z?jt*LN~9iAbQvPqlCP+?>hrCM03RA zYS!W+ltIk#3OcME!hU)=PbQo!7^6#csDA2Ff74P{igON4*4n>%ge*G~$yE9Pzs%|Ka)-FEJ=m$nGKF{b2&Xl=&rqTLPEux8{p|B#J7aCOwMLb;E z^R_}v_?HZ#P3e|^0i^w9r?6NHpNY8rD6Lx+VEK{7g?gQA$dP5v58pLwep&Z5PdJtu z?(&E~4J7P3A?c5nA57Es^cf-ltXu@nVoXBZB{Kkz=X5B=*nu`t^v` zyu8eWCokcp2hKRvtfO~8kJghDr(ufPNnjfEmATLRe^tQm6F>m(}6x+RpTD~8*fUK4rHf7``|AA!?FgI`QcCsva%yUS{FUd6|vlef$24b7c{I?dJi z%|cjt9klxpRM)}%t<0?xeNUvdEnKkCjhJaQURh|^+{^foWky|I{$~`}+j|kFKiGBu z62tH|USGIm7hLhlCi~D4;)-8$&fqQ7cz&T(&}P-_kcQ8z)n~GuY?$ZWFusLOkxAi9 zNRDq_3iCljID2PQNAAYqeFNs)MFubx27UoGs*J|0Lg)MBKA(j7j}X4u7ETJzu*jzULt|v6dNF& z&4+G45_dxUv%K7!18|NY^?G)>+af%D6j%ZD`>Q^Aj zT#TB5)U-n9ZziP^Qaj-{JV+7H>B>Sut0>wJbzHQH^X-Ld;G^K)!V1By0PT{V1-OF3 zs6W_LSn(`lWFreThb# z5wD}FYh^6zqU&VCZt^%exuCT^1~>!$rvEi#9T~d@h!@OmTzqr+@c?}8r5KZ|!i}>G z!bY5{@Tdse?U90)q5=Qou2>YdpNBk+im;kIaf;2#Sj$89YEs&$nGA3Tc=cmzPnXR* z59Z=L3$e)+zRV7&3P@3I%4KV|@7o*|#!*F4;8c{9gVmjoJ?Ghvmf** z6ftZ91;MQGf2kvhCe5uKWOA;Z6#PNo%QAc3(?bhuG4~U+bf~Z-EE3Qb44-rKCQAb_LYS3yfcG0=lj|_B|*&OA)J^w!kNZHZ35lK#XNW` zUh8e~+C_{ahqqee!~ux(W+R(n951=|V49`xuEwDpZ^;kOyTH!xaL4^v~y~4>!+|v>m5xjGC zMO6fMGRpsd?7e$jUDcU4zRu=wI1mDd2noboPBe)mCMh8pNn#WdP*7r#poumL2RH;O za8BVsi1mWTOCqL29Xm~}&M$Rr$M(}p>R6lh=gdn?Y-4Tvqt>?8vGzE%Z%Eaa*V;Bt zt$DxSbvgSINbIyTfBZh(u=cZ`b$Qmap7pF}UG_R_2NUZq3iXF-TQh6%wcOf06~Wp) zH6@2HLT~ynC}?e~uXgWMGDC!6hP?r=L(wuTg2zV?jHD%8ch+s+Re-wlk76%Kjaqn4 zdz$%?1W5O9V;bzi!ZvGZT24*J^=+oun{APw)8^rhTdwT{4lT#pmwdBW$&L<{wkESb zjvpQt`YR7|!1o|A!$blUyCTNT~k@yANY0}Rho&`$wd7)rL`8(k0z$w zen`Hh#!sihwYzqf;MaoVA3!e%&1VwX7pc^8Ef!0Y@ z86O!ks7v+ll zt8CwcyfyP@ur=dfeTBLW`yxjx&y6p~T#(;r9H`+z->`*J4`00N zH(c!7s=cw;w+WBKgM;JMfVx49ufg+4sKu^tp=Wwx;SgBC;y5W2NH*Mseqd`x>p` zBWydcnRWP}u%na4#8u5#&8tgaTlMCerMVyDVpYxXrC2W<%pQOG-;pWS5Npy- zNIz6rhg?YfJOZkQFDgX$aqD$8t>%yz@k7cJIfyV)+A{2IZK-c#JisFx>EmHG)0Xu2<6zjYH!u&#&CGA%tJw zCC-LIC1&n=C#@ep$+7r(K-9t>Mk$1Sb9>Yb&p1P0Sc}7R_H3AQ7;+kZx)x`ZoJ^wM z#jahvd&SF{YJBnm`+e$$U#{KrA#6XqA`DXy@+b`Z;fm5Xt4n`hi&alf=U=Vn>u>Dv zjH9sctyy#H#_HkLP$dqR;~U6|ulXw1{i#2IbH^+3yFYyEGQAqVx|>ZifM)aD_z$4s z-2ZS(hE$c;za^VN?XVxcZen3je(@Cx-TdBb4Z0US&A>Ob_YA5)>?gef0niI<8Vz|B zBc&5~AIHw4M846(nOr9UrNcKb?EJ_Izv&J^wp3>ki$r z9E*4sk6^}ec@4pVE7)=|$i{B$@mX@=2t&S;hilec7TodL>o`d2r@5gF6@5*8Z~$MX zNkt#W6o_c?$>(a;T#4xTsbLy^08G{^s6RE}9mfQzaXP-7xwqh|0{;39YMA|LxbMiH zxsTrr^9x1HJDGkRf^kyPAAP+)lyB#;0;t~3%MMe~8J=5)Sg+&DSLtbt{+uR;!&v@^ zoogqj7r+<4TmHFxVei>;2JNta{{-Z;xHK>9JqoK}baATrA&wG`r-Lb(5^CqVh@&g! zci~Xfc|J%78!yg{*5C_{CDQ!t*+;OhCe$0iJvfl@jp^|C-V(ik%&~tj^-2%zoj(U# zpF8~C$=Y4tr+U`P?M1c2cb=@ro1hUMY<}mLNtg@5oTG1AcSxNgHrx-p{?H%F8I5}^ zr`4`|CHJmFi1PZ4n}(nI!_cp}e*^P>4F6$nuutxMT1oEw=)d)3!Rt#gK0mRge|gp3 zjTu~u!0%*t!r;I4&(dRx9MK+d(WLR?;5;usa^L*?p-u^ zo9=l+@|}7q-Nl#EFp4fkhcP$|Dn(8z(2-0uFzgdSZde z*52cX&*;tp&#Rur=wcckP=;)l0pgVV-te32=a@5pkS5R4)z8O37xk%i4qr8${w5}e z@>Mk`{S?oj^b){$B`ARgc*r({zPTL1n$X9vZsnr$HPS)9FF@xriq0dX^A1-O+;n;! zbgq;P*<(f?p0aoP5K`jp#NL7(q>6?_s;wmV1=%`(h*|?@I2vg&XuXbKsJsV$l$i&E z>bHsLOEFy2_9R>hL$Y`JB_xa-(pTUC{SC5M#w;)f5#v{qRrxX#wDFm_Z=EdoHrgJ^ ze?3JWb;{pAsyyt5^8VYON@K^D`=`+5V}yj^6We43x(H0x#~biV$&+K_9|eFK@Hcem zzh+b(q?E@mpzkj1l$<*K43&PJiK%jS$M;bE`5!e^yJYV8d@+O-9*nrr4Ux$&F$K(J z1vveId{&%lHa}(vo?P@p$nfN%pUHbn-oGL5|0M69koSA!y;k1S&}vUE>Xy$xfts9L z^sKyZmiIU1{R1*|jeI^|-sj4DuDtu?{kJkszr6ok-hUwPhvofi^8WwG`^V*dm%J~R zX%(Ll>9bkhtL6O<#pLHx^8O3yvq;`ALn>Qz@~N)1@*<3A>u^8=-?DtYBELHK>sxVR zz-S@%*m5h>yy1Erg`TAZKPd(Q603tHJB3lSkp#|7-k^tQP00_Rq(`jfq?p zo~^?1mJf0}dvw=}Cl8Mxl7+WG*uA|D6h6cuTFttuydXZp#$TS`G1R{vkA-|J?8j&2 z4~1(_KHLAj+Fi-{I+MhwP5QGD9AxmX5uEY*E}|(noSjvZi;pehvyO*U?w$hM<@1(z z%Qdu%!*A6NAN}p4cv*x-UbnZP9XnnihTPnHvN3aM$CW$(PH3DEmkr-{M{>R;Hl=;1 z^5mIMsGt9DmdcK%P|Y!sO_QfHf7 zb%qjs@^TDL#qOG*Caq#0*7@tKCHmwBzod?Bw!_#(5Il?l{O%xv$S66?jtR)U<3G^4YHvRw z!a`uyiU(0Bc1-_$`j7lL;2`&|KJ>si;M6+unOkFBR+14Q`rNw@L+Dul#<`_99sPK? z_WWn@!yoS0HxV8|1WhjYp7pxAQuPIrS#S+u+^(y@t)=;yKi!5SS8uxtN7&wWEe_(n zEz%7Cdxt;=@c#V@J~*o2BT2$P-L_{)!H@4(@Kd7-ekKW6bNeB3TXXx<1hu!1E1-(7 zYmg(Ry*1$f)g;c|tv&R5`enlpJs1vCjb5re`3si$zAWxg#nWx~W$GvRg;Rd|34RqR zKm7#1=9Hg)iq&Nekyu?O0kHiFBLFt4FbTSRNt{W|v!V~#3+0Kiv6xnD)xgI6QI3VY%g8b1R@MUV{-5Q81723bD`KFr(!e0z(?fy z`m&|v#u`F+xGs!a3s<0UXzy)TVR7fSYs0ujc;@-#_y}#Rp`Ov287+>0+6u<2XS`;{ zi$hOI8+u9rJyk$*)b{{%6s){Dp>)(w9qmZToa{rV*wi5-g^ehTfEuPS0$>LeMnHX2 z7y+;`g%JQtDolbd9}S8)oNB+hp&9Iw(vITipm`HGRWDS#YdrM(L%E4U2oGz`6S*OT z`SbAE+)S*@*PTDA`i_jmM{<|=UZ1I|$ELRg@6ncIN^1CgQC_m<_Tv;n?vl!Q?vh&k zrn4#!zwxZgt3YQ1&w6-P&=V_xb$Ma|j#4|gtT`bgm0m-q;8jN&6RRK(Y4a<$=vTv(|@w%-N#_P7qX54OPl@spQa8$!2pf=`iE8h3yBo=%u)jDWS z?=*HBPulw6N!uJeX-jikl{Co!v@HPAs8l(OFiT+be+>K|Bmc+9|1t7^O!I$C^MCAi z#s9I}|2+QRcJP18F~dKf6#slu{PRiif6Fn+KLPkBaPprriiUqw&BuSG?BN^l$~s+& zd8ew)$?e`1vI0$dm@S+~ep@AtT_ufOWeIOIY?U-@l{9RX#;|!T+S8L*w890Z*OkgB zO&Ka-L}B|Cpw(i{C?L&MRi-ph&|YbvR6E65(cXLOp)<$JK8XVaaRKKt(ebzO%249N z_f`PsQ1y5cel;n)`1qI$uQ@(SeDA$+rhmeu*YqE?and{ffQ^q3zthIUXj8`%HhzHN zRS%^2t6=!s*f*p3t7muui~5@XX5wuc$M5N}dQ~(0t8db~W_WKBVEp+n%ZYOsA5+%eR&I zow|G}eut||b|rBxIKJo?EqMpTZ}IzhL8I#E;l`Ir(`)KQ~AsKT=+;zpQJqVaYmj)zmC6=Zsh{81a1?ePH{AC&QNa=NB>LdLi87l}V$E)7yc3N^sj~;$AZeLXKyc07XqJGJT!a=#xTVLPPf7D!Lif(E3d1= z&uA*~1uVXzs$kkZ;A%D+GpaL=?fCJU;eTam8}Gu45e7ncjSyhjH7qyK-!&wCuSS~8@j3Wa!T6_1 z^4k@0_=|5>v+V%jL@2CuS64w=6;0R6?R)IEiWSc#L$_=di7qgP_iR`s$FAz(>f+nW z<&Uc&lj>re4(;#9TQv9%hUEs-*&12E-KaQ&K!$LqWdFkPLbAYLA>tq>gn;PQ;CPxU zYVr8bv1M%J+tp!k#9zpOrDDku8L9w7<3Bx|+G|06ofS}rU$a!<$TK8`tz|{9&E0rDw-S$1{nKCaP{D({DpZ<={A3H0iCr>!?*O^14l{)jInD8OpZl!Jr!(F}@Phjw)!cca3aG<6P5;?(hC4rCay|%5^#PMy66f17 zsjtPaFUC&Vf01luAHwkoHG9$@ei?6Y3U=g>syyTFWfTzax$lBM+DTUL_e^?x#{?;l zckJUg8vgsQ#5Rn!aph~cP{TG28#TO0L&FiybCHiD+JC=>k8Aj}hRy zsZM9;{7U1m=y*?P_@IXOYB-|l-m38i19kcqjT^fAbbbc^mQLTI;Z_YV*YF|@7i&0A z!;psG(fRl_{+gzLM8hv?xLd;k4ZAeFLBkCiF4i!pVWCGZ35`Fg^J~#~g@#|&aD@(^ zt?Oa2h9w$~=y*mB?`b)`tzk&VdsoMMUekNQglqmx`lOCms^JSB`lJ0qjs*>@_^40f z%^qmzjohrl4W3-1@Uf7h6V6jGq~V127aGTiL(&gvSfOED!~Gf>`UZwfJ_cUk=EKB$ zzwloCPE>pVLksc0_(CDV$=_0bRAg;6Zn^lrmT207+qs+tKG=!dz8G%T--H`SO#%fF z0^AD$)`bAyLX7b?!5fN;D7--+_|+C~`*}OS7x1IJg)YFYxtzB(xW#!ZS&Q2QZ{c-B zd8=5DTb#EM-UNOdB;vdc@ixX=lD8841Vjw+7OvnEZzYwuB{$#}-iX`iX51=bxW(hR zg?e!t;w{M=Q~>mNOY%0sTWEk!yp8R^Ej&n+x9~@CJHT7`?{F*Ot%A3D-X{1{_;3ks zV;A7IpC2Va4Fcs2I)i*E?6FI56B}_mz^TY6zAq&z@S!wupaHk$4&D;D4e>T2pKj(8 zZ{c0Mjo`MQxA4dL#9R1&KJj*dx6t3?R?piAZ~A&{fmJ~al_DW(NW#H$CiicNw1p#G zU9r|kqBGWmbW_9&pF4T_$ENTvSvYz8gH!k${)Nv<^QQ+gG{_JN%}^kaA$&48Ljm9t z4P;1wbV$$SNKXJ-;4|`Bi=>xTJ4z4GDDqD%{fXH6&2s%HL;j4FOX5EB@0|ewKm+ zD!sye2GfDTvwK7(r*&^4^;U&`N~uH-Kv>tD*76;JsZTtfm=ei@Dm zm+>_u(B+r@sDFiP2mlhg{$>58>GTSs{!RH+dV^~SVA88_OUKs`K!+=TpTRXuca~q} z?^pb%Nr>{B{3VX^D_lbWlfMeLbhw59I$Zht46dQykw5c={ww+#0_gP0-)C?Q)9myz zozK$oHMCOU%HL;j4Vj^lKcPZp`va=AL)H(YsrnBPCkjY_f8G9>Uir)R4}YR6T=}#8 zOI$;MRQ{4a8$9W0NFd|0;lrOm;u->&^eP+;UWRK3pu?3v+P}gzObd`_ox}pk~TXob6wiUqYZNKUO@$0d)B#1ggW8Kk8rM8v4_1 z`K$D4I=zCZf1O_8sDFiPm}aM!>0tj=xQ13LT>1M9u3`El<=67}6M{RFzr;~~oxg%< z{uKWz+|uD1TB&g5?=!fD_$-E|uOLv(zk*hp30Jt!;2Nf#l3vHR6tukI9$eY|Kt?bF z#xD?n35OP@r~3`$bGqN3=EaRa!~AJ!)|tY+@l86WO|vZDUz+|*^u76+e3`d}4MHh7 zWM)mvo}QDdq!-j!POgvx7aON;7>x0m-u7X78&lzK+{RRXDt|*!;R-k%uP}92<+sCGes{PVH<&wrXL^6SJG~n>m@~aI zzLlmhJKT*c%&rAf{$M6cYs#-MyZkn;>YpKsk}AI)uIk?z&b(~gU^ai$IA?l;8TxMA zV9xYT`mBHEW{10Rg`HY{rlC{%Z}Y44-^N*fVm5u2*bXH}+wqd*ev!*%gpBUrX?O)+0t+)P7d{zI%O#LZd3~n%6KC1rh^sHfL zdN*z`XL@IR)&8CJqe4x5g*oM;YTTJW+o<7JmEXo$eqx56Y5yiZ%kK_%;|lZUZ__6? z?(}Y4Vea(K_-y~~`gh~ROdYEFRpk$6I`yBJsXrCl;0AM--;S^9-zgvRYU2uX^Updp z^p!T)@hN|2dWE^uJHuK3?((~FVw08MnSUU|oxc-jS~q=`*p9C-Cx7nv#7@oMncko7 zrtijydDA=NTWQ{KH*PGPv;Lg)j5e_L-R)oDc3h($s>V%x8#CcX7790*JAZ{SKUM#X zYtpM0Z*YS-)2n9{-}L`>xOy_Uf`$t=*6w6Jt!<{u^ASb(T-nxCu9yv;3rH zaB|}0NA*8;eyaZM_^SQeIP2e=-br8e|8{wW&mEuGWaYQ{XQ-W@vi~-&LY?$kVmn-6 z&Txj>II&anccy0#Z^vi;PMnxGy)&HszdPKGXHR#waA*Ci`nE&e^`A9O;fA)UPo@9F zOnSw;9qz^z<}9D8aXY606GdN)qYo8B3p?cW{l#?bromOH zEl*SbCS0|DXE>j2oKJ54RQ=oOS;KaG=I_LbdDA~ME^%(}@`;okg0IXT%m+1Xii*;!dZ z1Nod43eG^DMLKBCyO#UXEVW$iC#t&s@2eX4gKV6WA1L<`# z4gU5%49$z}TLQ?I?*oZTK%6Kb0p$+)sc-_~8WN~*<^Q+$VSjrcCiUTO@5AK#8^{79 zAK8BJYD>P4`rG?3X+QquZO4T0i z8?{-D1&qB@;|nuBP|(a141K0o@f9@l06X01hZ}|q3qysWP>_zi;YSdsz1+-Cf}Iqu zKQA$Fiuv$3og+i1bLETFzAkL$ll#iBtIY*>FV^A9lt1?S$#87>lW-~W=axOgC-5zp7p z1%T7wir`3lu7>k83jg1U=(lzU;=O>-~eD1AUAkc1AZ9rQot_2%K*94vj*@ZfVF_P z0@eYt+?xPz1pFW%<$4t$>&#q3KT`Tk9(e86ICGdhp`t?LVU5>ooMqxfrUL{;5jkEppD$zLG1g{E>(_ZkZ*En^RSF^^cd%WTr zr|$6@(l~XJ*NDccgS;Noc$PxNL5Iz)g^C)D-=^_qjqlO;pvH$azFXt8 zO}zGLe3nARV;ZNe<#kl!?Av)IHQuXGF`@B0H6D6d@k^V_E3EOp{?^uLU!RDyweyqmj0q;nrAB zPqbAhrho7D{_bc`BHY#4mk1|fv2a(c2gWMpAL~zqW9{L#Sa+loMxcfJ)D=%;SK{rR zUD0q`w6C?dGoFa4k}_U57>{gc?ugeLyD{1mj(5ftuKB=T_i&^oRT?3j{+eYJE#4d3 zPBFN`d!y|rvXp|yzb|UcfoScGL3(Y`fzH+_%GhJ5e)?FXh$V-_y!p0(fh@BZg|~??Gj@cIc{=@jKg4iJk48Q8L^e z8!&R|?COeck937wb|#|XJ`^z8)5;n^+2fFEytgxgfX)~dBhee{3diEnUi}*c67K9t zpdkHmqcNR51Cg#y=z!K6nYoOo{QII&DPmAm0?-jU`@)fMN_ZG^DBTG6b>1Wuq9>Zz z5$nAXdbUG$H3oZQFM#qNtoP%_}H9i3fmR2kWTbpG&{wNDspz0uV+ z7zO@@C10W&h~dTUt#-`5_GM*GeO;Q``aeY_TLffN42)F_P`6&1a;m9o2D3( zl=}MEV$c#g4I3g=Sy~%YxTherj;K4BSSjJYoqdTY$6Tq_&#a{8C_ZAXt^Krgsqp@u zl-`6BFb|RK(q1CGzY7*rS<&7|kG6+>3AQ^j0egbx+N&G0R+dC(cNA$brj8CK6id?l z2nK*r2FZ)2q&w21*zRNN?FmETDgGx3cc){kfJ&y~_3i9#iFI|h%H|U8iVj4(sIh3> z{n|)L!?mLq-Gto~5<9hB@9(*>2X&Kb{DtSKdFX!6@1XWi;jc=C*Da|BJf#rhIjNT& z`2T~a7mJnL@B_XI7Jo>~uX)Mj{uA0Czwnds@tZ#h@v}b(@w-3?@vA@y@e@H6zEsgG zsZ_Xkod7=!l=1K@K?(62K?(6QK?(6AK?(7TK?(6wK?(7@K^1<9g822I!YdREYZyF# z^71U#by%{pbXC~}t1m2H6KQE}i?(m?==|`FUEMvg_(yvC68!@^26yVA_kx1Foax!q zre$Si@(QXe!+C+``=?jAWWk)GSu+dr&zdnKFE1|?3gzO;QP*^Nf!<}&#AazL8qqN8 z(Uv>=qLqD@qF1K}BIx;#ndg}Cy3pfRGhPnrabdBBoZoSd#Bn~y=G1|OaMR#;?bmX{ zPamaRlXoaN4((F#o>f@I8sGD{m8WQmCnq2$26Xy*?&>vnHnG0xS98z@ZiC5MbFHO3N>!z zQ><}AuT0}+9#`QBulL~19z3pb!|$NR4S%~eZt8!ZCw=)z#jmNYM|HSgdmPZXp?^^0 zMhBkKxTWKddhjEj_(whA-}T^Q9{fd(oBDap6Q2B@;@|Ky?g@XxgAcvpjz6KpP5QSz z_z8`hdGouTaBuu^Wfzk z{2~ut;lZmkZsb+t!RtKn>pgg*2j8l3(_T6}_@Ks(ehz8e=*x)4%{s?pp74VjH|u6& z8aL}M6B;+`Orc+?`ZnPu8aLtfp76NF&(-Z?pT=iv{Gi6e8c%B6tOJPGReoljtytqG zeT~MAec7sUBmZq0PuKK2Jn;uLZuomh2KcVq+G#-9ajiUI_7?j8+&~~ z<7VCSsK$-`^xDf8J@F?rZs>=8t@tteRjhF%pBjyuPSZ=@Yu~)~$=klY_CRR;HTKP` z{~bDivrgL7)Dpqsh!LM?YQpHLwF|H>(bkHS2DBWTni3tIeYQtaQ+uQ@;lu~zdWZ38 zYKn78-a8O&>WTG4Nw=$42R1cDBQ2eZF!I^a*`8=xnaW4ur5=1$3XdmxSC@ev$R~O` zTlEB|sRN!Y=i;x!4#KnNi0E?HX_Z2tb`DVDqNOUtE zmLmLoxaDvkfLjE2F%n$_0*mo{Gu#bu%>(UnmFPUA<<&gU;=w7*^KdK$W>m3u6HPSp zXo#*br;V7KZSRltw#l$&3ae+k9dCg34r#!@p9@twq*+y?5)%@5V>DxI9pOwB>p&)H zxV0BYxXXETf`nboO*6 zI$<$x!txMSV#7u+OgNTZ20IfD^>@Ysos{yNHoH{3_r)B`eTp2MX*|Khla6^ zt-26rcx7*IWT#H3lhk10InvwOvD1-Q#t3hWb;oI$!yjz`t*9@2vZ9-+|{Iz*Z3xy?7739Pg$(MGKyK zWq6lZ2|wjz@x__a_hBbM59oCuol0GbrxKMI_Zubc9^AXcD!ChBGP=r-bA?O0`YL&> zkMeQ(U)mex0)g6ZfOuF+xQ452Dw6HL+3C;zpLAH0N^}h!dM+_>hJ;w@KnS(@8=c*QC-9XnzfH@RRh% zDNqvPs3#TQa}F5Jcar`lKLc?Bl=L^y6&vpvzl3W0fNuP5K!@C8{TG$bm*QlH|`5Ncl+umtpPK!&UkSBh%H3qxb+-+`x2 zXk{4jV$iYeh}8>>Arau}i8Q-`4+2IIlW}(-W*hJ>K&Df)iZMoMlY3Ig-(SK{5AsNW zeiS*g?X=;K_Z1|pum2i-w#$C-P3}!D%pol0mB76d80Ezn?Z9K;!Inf6a)_ce_Jh9& zc%uX;MM{YBvpKBx@c!r3%vw-A5Ay7jdw5u6zGrJ6>}}#(&!(3Cp0=(iM$Qq8J>s1` z?Xgri-cB{iR|`!$&<>+~B_J> ztWU5E)ChHTAhZvm?T}zEsJB6OX3WnR^^y|lCJ>V;shQo7G*gA89 z(9%-2dS#>}($-=)E?Hd`S=qjFP06a&t1paP5G`pdzc5XWeKP1xJ7EBt&an!?=I-7vPG)pxvj^4hkmexr`oBN7@Mq+&djVSEg`Oz`sZxX zY)x$2s#l@)VDHlp8`1{9ge;A1g_KNsW$RS-SV@@Ur?|8NPFrN#VU;`PzsM^Kf0Z)6 zvQ6}&yHzx%U;sSj~yoqtx;J~TFh=) zYUY*&`U(8SrBpwFIe!FWy9i{-k>v*<6WU;o^Aa+QJaI%AkrGkkL#G8|S*ws{2hxxm z+Aq5wvpH1~r48?vrOuL)T8#M2!IZhlQ|9$DmXR&trAT3{pRq8MV;}PF(jyRKy`3YF z7;LW17kk!TDgPdnlOur1`rFBDe3g`pszGJ>HiIA9Yg**x;7@U9`e9|=Y3Uhmw~xv7 z$&|>+4_g~+g=Mry6O2L4Ot{*{srpz8-Ug8RM$IMr9*(ixGGmJ{rL{Fs^`TADez1&9 zvZpd-X_C3Kf1@sQcG4sJHC0GXw|VH1`kzFl5LOO53|w$4!Ez|J2Mc&oz!m{WEYf4*7+as&WSGAQzR;^iGa^cFd)=0Fyq_wQw z-8mvj>#9ggd3*cHRTq|)M9U*>Yf8#4Y-?M!rfl`G;>YkQ+tQJ39=G{}~2 zdJvN#?QtLKh%+jCRzNvc!r7^(vbWB@Y(*+pV|Qo+y#1@n*~}xD6R%B@5A0i&BVyx= z`4lwd{q?ra)f~gE-RoW=a}mfbEcNNHP4{%;6J~8jGvOUV^=R&~ zZv=8m;MXbCY}(QtsJ$v+v?6S2w4!WZ?s^GhMS=ab8oRN@(#EUSqGo<>ikl&KTBR;% zz$Vm54{~US5ACD-+9-2Yf}J>$+eSH zd2n;^{wQB0^}Ytb1FFVYWWC^f#dGAF9F^-u7}ZreaLTevTq5_KJkN2J9z;f|+bg;DEjjl;}I?X?b$d}zO#;LO#4`g4xEjOA3;1HZ45R^N>8 z*sAUE9oNt7`B4~JOkGyvO|HIB2l2pRBGBwHOA>eJ5rXDqlu~7&tJFQur{}#yk<>wr+ijpY`$4Ax~h5v=S#oiGh{ODyYjji1 zrkp&gK5e~Y_G5DA?>9O6WY5AHB8N(E)ZEM4$J#VjpbRWUHPR^kVx5}#)nqe9>Wp)o z%U+Q!!`+IO!?z!;NWDu^wpXoNsMTz0EuY9M^@lddtZ1m%YA&GqTDCQ=!+LW$wH%bI zJ%?AT;wq&nlPR$+J3hI~pOCFw&2F7mWvba6Wny&F*ekV8Z(A*{!?JfVe7N(!TGpMa zGrRv#t1_JXcvom_I&AsWRb`*exc1Z(wyrYg$?{`caL>U0dbv9D^lB)O6tsyYbr6&q|H>dV2=P!mD7JsvXko%^_#r}b%Q0O2An=` z&Jud?r`}*F9U|{$Udgt>nlvk2MvGMYFqpkQ#5({6D7!~}wEK2%D`RWsJ4@2#I*=`K*8W<_SQbJ!H|1EvJG-RS zwtF_!Yj8x#6#V1mOh4J%S1(VKr>};lzMq!tO)bC$S0gS;X}VfnyV%1e`vvFtmt$Pw zQ>8X^P5BxiyX}w#+nkc8T9NavcDrRm`AnSyLk)fQTF&-;CaI~ky#G1l^Hb+HXMUHk zqCe4Ij(oiPExhwGY?^4quQ2N)iH_1Oh`$IeJB)e7CP>+NT?%biE0Ahkp6@(aTD4AZ z`ZTr*HD}z69;Oa7*aDOV*y3(PHLJmv6Ju(=82d6gpKe6TYdxIQh$|3I-;Lm$ zv+HW`&GKB0JUQRqCRy4Bj3ZaRx!4A3&iT+I&_#edlSIL_ta+aJWsYV@n>wz4(-}V>{oBaLba_E;@Zt5PL+WqCJG-%N{-}q1}Emygz7u0cE=j}IJq&-=CHEW8T z=P7$KRc;*l*dsi(Lcp=zRMu_s{J6(~qd=1zXKOdXkMEM5ZxzoxN<5WMr({)4(dL~e zCBl74T+`l(k>mR<$7J&I^6$>`uUCTi&!y3R%G=(t;FONt>z`SwPF?Itv~_i@fYVtt zB)Yi2FxtzXNW)K!-Y!frpm6rM>N2=_)1+_{I=Oz3Z`GepK1Q8vhV*`WUZ?glAJZF9 zDqLTh>|M8^O|IF7)Jg&N>f@Q~4c-~AJsvo3%5leevdt_)T6NX-ZHetzT~@D78?aw9 zZIt~ndm}aasRhSe`Pm_RZPiPde!f)lZ;wydDoqZ0J928@p}o%uKZkdm!qAs+;-~)J zT-6`nOW^kj4(rPi248L|XpblqJ^*gjMcHt+yIscQ>`BGt_`Ov=b2VCk8pn367*(tA zKJ1cRBS%n*jv2M6-q+~ia`eV3zPlH0K+nNms}?;5*Nbam>D5(*e4HZ$zF$^j2UF{l z%_8ivj3$!;C3vS=3SP@_ve;^zDpn4zd3pI!BN2*{rDGH+CxAV2Ph zGpit{uC6Xl$$!1%VX>5W8)hTwT8vuanuGUpzL5%x3aS6yGIzBnpiGv$6s0eL94Lh~ za2MjK6!pq+T8XSj%82V5QH0T_4K42i$d0|qYMGk8scm&BHpYw8?|COQ6tfi`(y&;= zat&)V+^S)-h8*iug8OPsxe?`$K;MiVpye^^FVv3;*_OCMr!G7FrO+n6g;3WbNNpQh z9pB9_LTOgWarAZ>7{T36*Mu<dMdo6~3ur{FnTLCe>(M>50J&ta()Z9$>46H-A>)tP6SdSMn$H|6|t!%M_m#nvZOq zbG_!TS;Gzu;~EZX$mp+DUnGA$XW@A#+_DvxST>WG9Y(tOaE~GEF;CcZ_`jSc#8U`+ z$`i&kez?(6ON`F8#J}Ma$B*9P6DI&a0Qd#Czk?fs6L1g1Md7Z2OCnAmUku&f?nueN_59Z^%Tzu@bL=xfn*10o^>zN@Z9O0owlj}tVXc^kh{7K(= znK<-IB26>s;jCU~6xTE34?4nkJDwSlG|c79mvp@sX;H369bw~mCe6^|Q{yvz@TSS- zdcZ-0@k$Vn7dvJrALUcfB`@`kux7_I=@@!^J{>)$Je$G80nowO#!Pm~#klO_jyl38 z@O&m2kPvB8cD$VYFhA$z-~=Kqj)|OFC;+Plj$|{b6!q<#v#kXrIx^%V$LY8XNHs@ zj=5^^?5z`qk(QzDln3cMFB6A;;g4EkAHw6FI3_;hro$a@geUR*eszy@m zbzV-sLXc(2`If+$WzHzBXYy6!2p`1r`>iVyVjh$6#eAKYldl?-zVPB zj_?V`Gb56Qxt#JKUFYS@w}bX?8FU41s*5389pQ02PiA*W%g}b_Px|I6#6#Lp+Rzu_ zSA)oJFGm}I-+r9I@p-s0xF5siVu7y-2YSp{Cd5xyp?`-9;Z+&Vwi7u2Ud%fv#83Q3ZDeTmitKy&Cs*9{@cD%woqfqwtjnsk z+alYVc&zKTmD~EZ_4T%H>+Q!WwcXKe_#tg)d!#kdw=LH4;cYuQdzKHbE?d!n!$oim z!M4^|ZtYcXqTCsu$XfAA% z^Xdv51~dWLD!*|FVHfI_?{Bmf-CvJu;RGgh{ zq$T$IL=776iq5u3BC_xTdSRVH>gbA+lGb)CCk+AT7;44FhQ@_kH&!yvZjT>5N8m?& z*YP$o-ed6NqK5XXqu)XJ72AGS(=X|!cOCu4U4FGP-wBT&Jx_T2WX7L$@?0yuf^I*V zN66(@C-cC3)luF$887VetC#VL-F`A&iOa81#w&OG$#__Ek!SU+*dFcRF~%$})`P?m zA7r(?y|WEVVio@k9UcVU%esM#=EGhxT;i;C)D7miQkKfEk#snhegm7Cbv(J<8f!gb zpPhCf)|Kd{0&u$3^;c4HvMl5k8A9!37k)CJ1f$U#&`2r|Usa4|3@{6ppfXFHh z#C?9)`8yO@`Md$&;aC_HGs_Ca%(t?~vPOgPjOIZ77h&IPAa5#5@l|-Z0nVQ#=D|Xg zj?KYjBl{(BvGu!jf6^Kk<5tnqX<|;>#9m_V2~B@6;`#Fa8`!J5!ntb-hp^?0DZNY_hM9r`HH zYyJ{$R;ef|Vw@Qw>-j*OGCK-yBo)O!z{87-lSLs71!}~Xt?#1Vq|D19^A(fIJa_@p zLy3y>@NfxSj!a)^ttA;%jko(Hk}N%Nwh)J`wefSoYx=+(bm6lPScCqrrUieHpY{1b zc1_N*tnX!H4*^`@57wqz-w{O%f?`JFSz-owp7A*9JU*@YfptEy6+9O$$`rGFGsU!t z%w)!BdfeZfR$|pFUDyv+9$~pYkB2AW{MkyccpuH$V~LfP^|rst>4M~gN#BJ_sOU%gGPc5pz*rj6i7#>$7d7I!(?8Ys`TNt-5Su9;J zA>Il-IpY&nNa%J_@5>L0{5H7843Ural3yB%E4|B*ZAa=>TR;q5EW{_^s*tVJEhkR> zL!2c1e&>ke#C<`(2;T3Hr!`w83uXqy%(sIg=e10c-k2kXE)n7%;Px5X4!o!Udf#i6 zP{t*caZ$R+x+9QOlrXl@{tNOTH_!|=hQv?>Y#m(E&~xBLbNwQxBSU1qWtC9h$}iOV zR*8oiI7_zop}>AoYQ2p79Cn2AZ$p%hZru79H-}QSV77&7OWAf?qD)?!Cc@}-m%|Mr zx|Ai_4)G7e?WP~f%{!FYsLJstzy3K8WDm{l8>7a^%2A=z6%fcF`aC4$-s2Hudr_C)Jpi~ zWQ#d%Ibu%Zbl6NhHxy3HOy-Zx7!Ac$y8(Zbw3`<}ZU)=)t9Uq`qJ1bWke)8SYwby6 zIm@Su^E#G*uN%Nuh{5G6yAYJ7pfX*7fCPsEYn$6)EFPiBIFzms zX{8SZJ}mt*erFL@W~_M2T4V*@Obaf|x<7b}mAx=$QxMAxIYYb^rH58pIUi4(F*|30 zKYL!zm$I|p2>jB@eEmHKE8l@-IjrVBOpd@ z#CQ}gjHJ{@7oLOml0Z9!jR6nm;_XMA?>XW*@w{`h#JT7b&MlokF*kYk zSkdUL_{`>ldg|UN@-KcCxBm^7lM}{NsW_*Z_x5_+SFo`)mSD&;7W}+r6{Kb5XLHCQ ze5=yLsy2uW212#5G*J-~;uzf9x=c>ow=P|*OTey_rHMc@($C5gv!I)^pqsNA&YH+e z=8jDtofen0psPs?2SianV$VHvzqE2&5r^UVc z6~0KvUxEkdt<*1%eXBBY*#2=9%?^s$&(EC5PtF(%jpoFsH)ofyuDTGfd?#*u;rz&XT_^4<%o2rd*`lybaMEV$eRp|aXL2=G&0a0`$N8}|Sv&L)@+J*B>;oi`Bx^c)1@de@w#223Untn1x z|J@=koe?k@Ze?_%9HT)3_i2YqLJXW5=Y`sPEpSr-dmC?Gt(Sd>^r`505RorSU043YnQNcORhA$s}OaC;W+B{V>ZY@w+S;2A;`dKD-7O;IH7%G>Ov-yCUH12{T5>25Q4wCXO1>{TE$f0b|5j_I zKhF(_f5Q7mdfW z{~&J#cqoAj%DUGYHzaG;r>cH*##3U@-yV24!~d(mNN|%C@C8IE>Cc62#k}6kGpJK- zAay_KcH`kDI5o~vlgebU7H_Pr-TpsuNQ&}P)_IV12(r!<`HzR>{Pr;! z{@+_m(!>UxsvBbx$M?_KS zG_jzqSu7}P5(|7=Rar*uvV0Lq9!DNhcfJNBd$*`fv#=7->9>BFA?6^gsAL-KOb6`D z4U^iL2_*Xu(s+mIt6{&TJXBpY%PLOh+$?G{tWWs;of(0LE&r>2QDLdR*e}L@jAe5$ z9hPHR5W=FG(@(FrxW>u#KgGURI5SRm;E;gN%Pc8GqgqFIeczamhJ# zgBmd{I16K?x3PAEIVaa{Mt+WQ65Ja)Pd5$)M_hrpT+4BWrN$J=v^du;7O>BMLHGHX zFQ%7ei;`DyCOTZjrK&t`99;$C%P|Gw3s3x_#X*d7W?_s|APV17D;sQEqoCDG{eBh? zKZaBKt!i?AR{;-2W7&j-WG%y{SQxRQtS&>A!64L|k8Hn#lAm7FIK4vN#|XCl+G;ZIK9;Efu4$ z!$!kxMRd7NhA@FJ;R%yE0=tUwt{Q(PGQ`*$s0z4;WLivZTsSiJ#8K-{1(?(4iy6qfY2ccyoF$0D#p~iVc&LC=_B$T9MwD3*zbIOPwF}HS!=A3aPd4%bA;^BU{U{3fxZAW}o3wzh0`*|M?ec9?v_g`aG`M(=@z-kG8%}=IO zI}C{C-wAOyoM}@|T*-W)uwc6u1d#(4Ryr2devBfW1% zI`%QjIZgev638hGysQ-K4J9G~-KSi)!m3Mq$u*V;5dTptiWQBb(&=JhVyRe&^_7KK zUs>ooN2FFXblL|HJquM+{4gH=m58)a2TDacUc^a_j7$3+u^yD;o*CDs`75o!!-3#u z&=I9)?FWW6$2v48-z*>cX~==|wM4q`mj&<(HjF{xUIgg{kf{rI#7iQM@Y(U4c;300 z;@qd*bMbu0g7&BWa@e11achV3OB+8Tc^?XX18+>MUt0c8$hvgqg?Ft2b5z4q(ut>Y zo!T$r2;T*#Y%k`y4!me7+I9l=p>3wJ5xyBBFRAL{HL!69b?!|(oP<+0e^g3xX!Qv6 zFY5_WXO;Qq1q#p$7oE*EJ40}8#JXH~g(LlPAX#@K_F5g=v=i8r=k4*wRz!o?MR5cV z-Ee+e&xf*FtS_Rsyk2#gSZ~XO?#ytmW68NJ^WKl7lK0Q!;VW=f&VKM4@TFm0`{6XK z9b*jw?;~bCf9g8l%ZUDA^6*PMyalIh+K4Q7eQ-&-ILCT3UB228Md-Y-wi!2T(hDxk z78k3yJ$SLCAjGkEwOoLY}xU~Qnrj|>RB`(Db&&sfhZAP4AUtLqVP&d;#U z9q=y{|C)wdo*%clX@Q&hlH|4Q|6}FM%f3BLRAkS#7Gvr_-NGK`rC6u(oiFf4L(SE& z0#8{$#Y6>U7>4uB#e0*%pvddU6w}d%1mfu>eze)5MbpI0j&zatv};Bo>yR{A3>DnXBn>o zeU49LZUDc8Er2M5{}GJM2;ooKZzF0k*Q5W$G|IIM}9~Pm&tVJ zpi8OuN&F`lVy^-AIdnnPggy(4y(mwnTt~9!0E}-T{i3y~E6Cwa)*0XpaB&AN)0ZGG zInTiRghtGL%hE;u49qh)&cQlj5#}pJc-K$_`&Cq0kd$Sbfi$$`y=t`WD@ez@;hUns zcTn14-*i9TQ)OXo9qU9a3@$?7SwV4D0&}LeG%>Bw5*es}HUH7NfK3lMzB#f?tfMie zS&}1`ppNGz&JuImW{A017nqB6fw_+tP0UIbj4IyUHosYHuj$Ft(EOI8YlUZZIQM89bi?*O%kxvs~H5{SA zGv)hQ&Y?3<7nl>5<|U0DeG>7eZ&h*6B@Aa{%ry&Ru9^7WM*+rN`6B$5;$y0{4(fFr znaMQ;#Gn1RYpu3k&6CeNWuDA*#Y`vP%iw(s)*a`dd~-@|U83wVr7ctM(GB0rp%>S4 zab-k9M#MFNeLB4MVUL3MqR#}{XyMhThM9C@lceKhdIJ81nE-Kjb5w5i3GP{srV5rpl`AL?tmXRdyPB%CT_smIsC>PX|tOw z5k}gP>+G~^o53UePB`LigI^8&Ui^?9?`HTFKZ>!P!|x&ZjrT`!EdrF!7}2?*KnbRZ5lRec#(#NMop_qH=_ObYxuZ^ zPiy$RhQHGAT@6FmtMv0UEYYw^!)+SIH5}6L0SzD3@S7TrX*jN-g?i$Zqv1jg*J@a& zVVi~t4e!+OAq^kb@Q8*lX}DIGf0>414NtVFe8)BXv4&4;_=JZ4sNuaD_GoyWh8JlV z)-YScw@|;lUeWLz4a+pVRKsl=-lXBZ8a}Au7c@Mgp(KhM_v1OQ_jGxUUl(+pR{*-_ zygmmVhvudH+1*u{0#mr zoxVlGtr}jg;YAuQ)^MJNAq~Hy^TE3yN%A#K|A>ZP)Nr?k0~&T|c!P!;G+eAvA@d^#UtlxH!wjzmmQ&dHJPYn?tWqk9MGsL@__y^x0m1d{8!(lojq+0(LT-A zwlsuqfmdutUsWf*)Q+#v?F1JuGab+GsBCM)*F~}G^ile3inaB3MQgC{yo+V}p^u+y ztLtpRXYO{2-=)>XB5fKY>*5ia+ohfOC_O*^F8!|YRrf$Ro)5GMaVP0t+TYd1Q_HTz zsqskvFEag=*sRXvTSNupZ0zstg{bx6BEn(`HYeH?Q$qZcmrt4Ne%qI%H2vSC)kPx% z(NlP7W$fx6d{r~n!%t~m6Y1@Yw2*^`BuBD3M2xXWtule{E44r~`oQx!{!RE|Xy=BV ziD+YNOJ`ejV@IS{EM(k`_=;$(D+(b-h3GmpwdC}-PAOL6T|i(9zoDhmZV@YdRq~^* zUZ$@In9LeuDGtQpH1}C7LR{|uV1FXspQwtq^l#rRKMVz~Dt3Ha{ih8Xp7b9IB!!?mIbN3g_hj5h6vB>H%iPN8U*AM(R_&fB~BS^tc%cXzMuLB*mB|CxSuPlq&)ZPn%ziXhKy#n;pE$;v5%f0Eu9?d|UDf$27e zO?(|~S0l0BOJV21S3Qg|43hW?!ek5H9_=-LpK?fWa~-;%nrNg=%p{+RLC9qWvHI4= z7)#A?u=YuRL!`40*10trm!F3dJIJe}*Z72kvd8XJ_Oxxr$N!{s#qspU)R#S9=QE6+ z`g-S^#6VPGzal2T^f_Iyf!(NES)a%i__Vdlr$}_;yS@BY=viz{N^eB~Z9Cq|&p|6Y zVgYaJYSna__|*{=AZ-pqs4a0AFXcT;v}&q2X&;Tatv@c(NTa)@skNV9I2_dJ@8(x7 z*~G;#pYZWZEY*uh3%Y#qdD;Hy6@Ck2g^Sv{v-!$0x|U z(R;$OVeK2~V?FJi+o3g0JJ1g`MS8bm@8kb%@7$x~sO~#HHiqf|X*bxRYETXn;erU3 zy?$WJLAKTp9GMt<6Z23A)GJFXuN?_5dKfv7W_gr~;6pZnlPHbpnSE(xBkgWdauAKv zY?DBAh$-771*L_uP!1K~;4Q}_N(-c)@64>dHgbSN|7dcM&)1)?u6}dp&Yionvpe&f zd+~9tv;Po0_D)CYFGpDpgaq?S&JRQer?|B?s)o`A?qgHlw z+3$C=w8!XRTEV`w_aDFAXgBIZwAEQ=MMeKO^ZPoxRGaPgjNQ>&TiZUTynA;Woltjd z&~sWZ`(lf|YQ8hnn(em_z4J0xX!*5f+-dLK@NT_1op6LyPgWk<7)ko9txuZV*=YYb zXU*;}?*Zk{@RcmD%UMTNx%T(8%0=;K>c4SOxvF>1$F4Jf+VS(>{S@y(F-R1U| zYd-Pscbzr!p&hMeL-$Sh%$)P2wP^Nh54~_Wv$*<|OX~k=?%(ama3}BE%uM-iXQV8* z}lt@b^2ahKkbVf+S(cx zEvpYMUeZy&WXZ*g>zB88EU8}@T(*2^aCyhVcJDGLa{B*Cx3zzUpK9f9%PfkAH$>W*qYC9(@`a0!k=ydfuv!ov%I9=S%zTPc6JGOMUUcW6^u5h}z zt*z~x1i7c^Zs5t{>{HuvWo*iHaVOTLEuJn;>uuHC@Ae6mvsLA)r;FDNew=dp%5(RX zV^3DU`%(C~j+(CC9{VHPabYKIujV3ryY+6_{MHJmTkn>2t!r{@HteaI=QZ@ zYp`?h;$CFOz^7bag#U$94G*Tk2raSes~0_ zT&dCBNco19x$Meu|I2fUqg?zORJDZrexdTvtMQfj=*nR~Z1TyLa`DuUa<494JOlOO z#SgmWCR~W@et=&?x2sP0s_Ttf`u04&y{26Gb6rFJBd*8F>$>c9t`EanuIH++yzo=Hwu_HK zUFX$45)ZlMC3wyyPK?r=B1qdPF6Yt1KVrQ;xE0y;z}Jy?Df?n2`whug=7K9H`~dP( zE;D;NBaeSDu!jQD3Lk2m2iRKQ1I4k^c5 zoV|)`XLzw5d6rQ>yc?UJ5_{uz6<=<`$)1FI6K8E^+Y7RaO zXLTFKTzq9Nt#WL4pbeCZr}y!C!B^(XDvx#oMJN|vLKeOj5MxF zP`Rpp;wy7jmCO3d7dZ}6E*?RXc=5l{6yAt9`KQWH{TTilq`XwI`WB99cyS)`|`KJSx1RcVQ=b>3m zj6L|^os27d9{$yr+}At2^e*~@az702;kAYj!&!H;@9`eE8BO8?u=>mV&4-8geVsPr zm6jM9bdIrMc*+QEpj_#UcOtzvMd2?-IbN+|+hI9hPu!Ye|57ftp{MZTZgdDAg}$7@ zM4^l;c-prZV|WkzYgB`eLgU+vF}xT@K70`+ID+@WpM9Tg zR5`rh2c(Lup&Wkkhs5I}@a!M6-|;5AYn*;q%X;CbA0-|ifQiRBzTk84(I?n0d}Yp* z@~JwIc_}Fa@C#@OUddsHk@~6x|6#&ue;%&;1@#kCnM-veWe1R-a`6!q!WZDue{;rX zWe$~ct7bn%+lUbtAq($=_dM+!S1owwGaM5rugrH+j?{V2@>-)@yb#SH{YYGZ=Hk7u zobM#Q@EmQUTs(xrc=1&f!RvStwC%?8oMRxp=lbD`FVIfnOX7bz<5v8{ zON3JHhY!8Xz9cuOGRH`{M$tpO&r&WbXDEUf%eh42x?l3Trd-^N4&cQubPykg&%MIy zA76t1SYq4Bt0}I_##|q%rHXu%Dfgk--Yrb(|1^k=j{+A@WXYs7Ks`R4#tU^<(f=*B^mrEO+Ykz(4=lRn;%{94 zI_$rMeL?*Z_*G<5zwUkimg^sYa~gSV5+m+g$$rEuXX~OS?)Sv|;N2*P*E2PLgzWXg zgwN@>B&=S={!l!;Yc+BBd*KU6>owN!x~?No z93uHSa2`^;sGK8t@yyG4O;M-#C8Tk+2R?ullZQ(-axW|~4R9M$`5yQx(t3};(>6Kl zs)8SOy&fNPzUzJP8rNS7Pw~@7)ailqkx4yX*y4Ke2G=WR;jT~f+8{m$A4iHWz!zPA z2!3a?)BZ7d>J?7gs^BK1ct7lOeFS!0$+r0ETNu2We*Y9>7+%=IeaQHEaOP(?{@`c9 zOa6l6A-)l=ZspicPQzN*ww3Wuc{@zB(O>u^T;DOnIDp>(zmATuu0ikF z{tUpsC2uA|OkF4QU?7#}VF{_9#n*STjl_um5$3gze;#(;;B0$cH*;*DYRaeJaF27$ z6kkEAvji{bb=M1TLV5Z&0&j7B6n@3^2jMxpsGsevfvrgOw8QR-ph zEij74*)H*oTb*+AHrjwDC>O`>aLV-%zC5a9{Of^fyO6vdV0Af?*Yl752j%!or{}qR z6Uo~TV8J)?nL-a@_!Y93-7~{jhwNqHBd%AzP7Kz3#qlQG>v{{;eAO+7 zdtIM{r`_X>0T0}WOvZyB-i@B;J?Q*`FLpMw5d{D>oJf|EQ%NJ`OE;(e>6UaL9ZE;i1LgdxdA6}NIy{;i9UIM$j*k{bCq|6|uUB^IpfzlbS>x7(HEB&*Rk7+=U92J29BYY% zV*Rm!*kEipHWnL?O~fW+Q?aUeb-XU#5O0pR#6$7^_&|IxJ{%v5kH;tClkur|RiZjk zmuN^dCt4DrM1Nu+F_;)mj3ves6N$;hRH788cIt z@n#w_zD#q*pJ~YiGNDX3)1PV1`m-(BKsJ;OXZy2Ob~u~Mj%AIa(+~Yt#2T=oR?f;> z1*>S4EF!k-8v!ih*Cny?bNL_SeS6ceR{k@O_Zq&MkfuLqLhWQ09# zvA6T==^}gDNO@9b%A4|~{HZ`HoQkBPDJzvrG(WCk+POg=lFEo3LM#q4CZl%2{N zCEhnQgsm#eV^v$GRcCpv2FqtPTYjs>3Rod4Y?XUy(6SgeIYv&Nu~T657#@zVEPiZ% z^^ZhG21cSI0~sqboXKUp*@o<~ePEcJ3lJY+j71q`Jg>@rc6W#oTuN6D`-Vfq(c!V- z;;?6*Z(nF%bl=#%;=Zc=-u;37(fwolC-4C~MLjA%NV)%%CAh1YVXr*jp61%yWNfr&f!t`U!|UgJvkt$> z2X>sKABRoOFLwLNe{qY9wRY51hUT~|&j`Jq`TI2Yo_^-qOF1(OYChynA~hqU=D&1) zaPZoxn{i7yqIsTX^$P_Weht1mKa;@@wk$EKlv0*eVW&{m8EyHU7DXdXji|Q zIUqGxc{^X$J9FPUEzqo|`dMc$UtXW)aMz5RYKLaYJ=V^*tH;Y-g`6GO>k6JQ)3esI zkf;B8k4o#EO}u)_nT=jE9(Go={CBOda^ChjLvuZBpxv5HwA1d1Fnypc*k**N-7rkF z(O%ysw_Lrf=yH4Yo6}?ObiGc$J9DqL)5n@m{oVBYt<0RtnIP@i$-Z%xKYo7f%09b@ z`%fEKM~AVLE%mbR7xUX9$`(?hc{4T7Xe;HKJ=2NO2x%osvu|oHPR$M}F6Qs8^oU-2 z+GnfS<30RMbDnq7bLLz2-iiC}@OQu8*wo+EX>uF8rT|`1yKug@)(q-abM9bYQG4YT z>*^b7&0{kytf<``?5S;9`GM0vaC&2FPfxIGYv*p0Dz5KYQQOyj{l|OSLcy-qp8Brs zZQVP2c6RjEbKmL5TYI|Z?^;-Eawq!sj$luD%3)`HRA!n-D_h^rO(@%YcOTcL`Che4 zcQvo5y?pnoaJX|jSMF)?eC`3RUEtKv+uhgGyPhlP@31|KYVGA%cMo|@B$@1Xf2X87 zctaoU47U5bx9{Rs@omALcUbGPgFIiFB(c0M)bT`VbWWhA8DK~w=acys0aI_N$Xk1X-s!SCVC0j$})gzXX=7cx5{wqU*Q2PtwM_ z?`__DYfG^WO2S7=#|&RXAYmpUr3o46)D+sLDW%X(%CwYenGVyTxNcGyJ_&pjXao_pVwCf@vB3J_5c?~NNo&!OaJM8ekwOK5J| z^n4S2w(cvNpA*NwvUz$w?`S34nzQwymeozuaM+r95uj?~% z%in70qaF*rZ-nRs*Uu9DV~8s^JxfFlAk7>g==du<+Oq1hQv~?2n(hhLSa5;=0CZ^! z+v@9$ntU{9m9QN<3ry;E78Mn5#d)amGlJiQZ4@jpvaYm*mu20Fx8@lkI#`3s>I)$9 z!@4OHqM;p7r;SJe$IGMrN>6JtNbf>N{KlLB1VmM*l_+`{grIuIWstalc3ePwP+fC5 zjH0c+tEhw@Ylzt3EXD6YpPt5ujV2H2-l8hu_In;{3B*@%TSUFc-MU1b?2e}TuDE)U zCHB;*5h=Q>UG*q7x|AYu*cFux%pF$VlkdCY_o!FxHDK`+@@Q{u2e%c3397T2JE9s? zFEZRTbblP|QEM%L+IAW9CaAuuM#1Z>11Y{9V0)LXUSxB(^#r%Kb%o*^Kt zW8FtvLoFd2Yqu2d1=hH3tsJ*iZBgw5 zJ$+)qct21@hKo(-uvr|h?ywSwBfRSMXt-Nd;9HA%>#}L7>er`%b)wzkJpu z6~ZX;i4U-pI!M9HRJ+#4cQYPQ;+VW@S7Uq+qpA`|np3X_wqNHpE0D7INhB!H1hh37 zp>G3+R)`me$9@LZ*`EZk_Ci23;5jc4=nBbsT;CGVo36+KlU{649L(V8HfJA0TT!6ZU9#GMYQ#PUD3_i!#ME|c zn2R=RKMD(JH7b*W@AMJi+u;MY`Q5MplX`{C$630x**=Y`YQHVuORu+|K{ad#fs_1b{yEqb+idbPi{Uh9%7O(52o6R%gVwO6p@#kMxP6T?2Wt=&E>%hmQNS+21i zE*sh!_x=zDN9rEq>>!!FEZ7Zx4iUcdc%MDcdJYtT>X zv)U_VO6{)qkweVAYWwvTa5LAnnlvLuU<}3RiK|{7P*8vBGnEt3=cwa)h5k9(_L4_e zkda>eo|lSRk%y392&pF4Lh-{G>N4_Gu!WS%QCY6KjJyN52F;uv+5)*csw)MA>sdY1W95jCh9>OlgJK) z5H4&@(QsIv1j6!+5QlZDw;5hM15Qs*6v8{d((4Y8*$x=$&33ZlXVbf!eXt zi`||Pf%p`+;xLtZ<3S-$O5VBa{H{bY(Vy(^MLOgRQ2_iFRNnGdqA5(`=Mac3Dc8=M za}IMvkld%Z{ZxwX!4}PFf6LKRBjFf=55Si&0;DiVH4O8BC}5>|)1Ls9y++KKv?#U)5sEhYa`h+8)* z-H`Ks3D?M8-w6I8=vO4=EmFeICFki7bG{-epOln|0Ly$f$aISs?v*@8QE#GvlyFv3 zhM_|XZBlvkpNOzf>4hM}rv>-g0-h*666#dj=q_lumd3+Blumh7dc=!uGp$362H`zH z0Za)@CW!?kwg%373p`v8Km9{+4zj;5#!$bm-jDhZRTJ=&!Un8Yn7%1oM*WW!hJO=U z0DN4%Bm|Anl9Anm z?qg+OA^PxEukBHctx|HEhyAIX7kXSnnq%x0>J|~w;*7l{?hUK3u6u`v zl@v|RCP5#<%n-1NXXQ8H1Fv2S71+x3B_&8YytYOa$X{&D8o(&+0BojS2?r${m2h0b zyCu9=LLE?09#Ey<16)PV0EDw)4@meUdOEz5eo9X$1N0+`g@*wD zBs@kB$yOousYg(MB{YFGvqqhvPtyaT3@uV#m=wcWx53{ZIuH0c^+9l60DZIA8h)5| zh*tH3)GH|bI1P%=2W`Y`jrt_ui@|0Z6@MU}M*RcgQ-F^_!k{>%JdeKPQf4gtJo=Wx zUx4K2#N+f4x*YyHz-NMAmc8H;kwNPYjP=hnF2doj0mcNw52OAgx+-3Rp6rdgg$H9w zGwS~hf8H(TgWmysNBBG7DTjUlm*7 z_tKHFnLXRPlHb*B*JnJFH*?m7OT9F1y8V5(vU%-JMeJ=jCiHBjwg1-s$Ma@+q0+u< zMf+I6a+dWSs5WKN>D@5i%9RVoeo8Gmu2D>kpP+FEL!C&0v0^)O?$1?Nrsr)#&tW@F zcr_Zmpy%CFrlZdqC(JRcSSlEWoiq@jtN}GA%Z0)T`^-G#rAka1tC2Qsoiogo zRklGd8jhpS8I;a?QJXf3r6c)*QL)JP8@YKGL!e;Z=n!H(okzv@&&jgsGI|m& zfX@v&V`F$(V|$^gti$RIw~miGi)J?ELJFKZ&!m*$uE3qz#?yMCY)mhfFfb+};zrZ< z;*@TqG6t`^2BuqYIxYLqA%h)F>|v;DA2m$F21{<##c3x~M$;i9Q=XgCGX}{%oG-<+59TwEvi?WrgaIO1alx|BRU5nk4f|L=mov;Ny)p#*^|WC-2=}dx zY#=P#z?n5DK}s0_e5 zTBc#TSpG&~rOZUGP@p&E0pJt9Q>GIoo>^;rVRUh9=7=_5iVqhFSD-< zLt+Yk&Aa*YV88-%VA!s7+QsdDMf~zaNwDS)9e$v!7nWOVbb~1A(&af(!LzO-oj+>N zm5Yc!WGv(z6yuJ+1@UCa>Motg+>dY)=XU0C*+C}_2fpR_`nAL6`MhnJEJ@}eIj2Yl z5}rG6O!9rZm(E8Eg=xlQ!mJ?3BI!x%f>g;%aFdp&2NaTf8fQ6uk*rc$8jB@Ghl?dZ z3iZ$h5{*5?rH+%TOCq2VZ8}N@zEBS0OHii=QL{+{Rt86ba=1L42hFP)v>^M@jyc&U zQ`09+4*1IGokbhBo0P_NAiiAd65z8yqu4Rr;qRj&e)fSMADDsrpxIk6B8B!b40MtR zbrRt4R`6QjaVbHkXdLh)G`!%~&p;Cs`dOe%ORWkRQ=?(L=pF9F2~H!ibma_GVq*;$ zUJ=MFw=+9cV}d3*O!Tuctcwz?9EDzp~fb2k1-r*b*L)U z*?D_y;?QRpuZEjdjRq)*4-d)T$y&M?g(aHO3WhxHl+&>h-l%lZ_~1&qSei9 z(o`&O0pmHj?le zbnUB89RJR9gGV3z-7l5~B9Uu)er(hfF;~bBM>v zN3I@7zb*E)=srbVA5dF{@s290qNtI88hZd(14;ve#0F_8?18;ak%*92K|~w*W^7t% zJ7epmNy}V5Z{dhwU2p{W6aXGi6kU6-LZU(_rHDl zyQhx3Xw1?gsBz_ylNxXba}wVkI=)II(u*5d{1EjEN=T$@U~hJIw~@^BXZ!Z{?#|8b z-lJ!FQ5d^2dUjy2Zy;;*4fN0ISj6(e4-oqH3F`3=on5#49Phg2n-o_MFcQ}CHSF?p z-{p>23JK@^rWa?1r-~Pz@{$OA8 zv5&VseeI{yb4PgGv3)Z*(%a4q4#QJrJ6A5wz{mJz)Ms!A*9$XzHlN8^u4%Y4b{QWo z1!HD~H+!;~U3>d8gR{EPx4SQCT_zbmt6V0KXN?aOBR z29vV@eaZf0Hk+K?-9KYx?w`TGA#gNSicXYr8A=@+?HkxlzVg5OEnj&!=)t#dcsGTD zU;oB4FYkQzFGi~7{tMT&DqdTAVWbvIV^ZN$hVM_P=wva&4Egck^W4}*+6w;KzQ3(6 zdq9!%O(R;ue>~t2Lrcp|vf|x{$@r=d)v>*q*_bjfxP*$Fy z0RF^Ir*Siu20V;&X$t4l6FC2*QBLAWDF0iB{wnw~F6mj0C#zCodC4bO)8dopkffc) zzGOp=cQhNvo;-^^iJz^+y{6I1hcXAdQ}t{h8R%;8qgcoSI=S)$U}AT>Rnmgw;e(;~ zvkN;gQW6bO6Z(1wzmgnd5fto1_!sM&z)6WuT10UqQ$fcu)*LLw_dP}{ z;n>dSr#T#$UGQjlkIS)6`1H!zt70#Y%;%=p@={*#h0eT9jB&`^z7}>aEE8+aED_W!ySu;({W&bW3(|kr2Cg~8bp}Ra7WoT z_c_^lqo_MQ#eCMb9BbC?$y&vIx>HP?@9ofvx|yHF#c5?{m*YX0rY#E_$7LKYHy2mv z#9MZUW@5J=?wDA_zE#NMyC3&A3B6S6*y%}d?Xn{;X0-ZdIDK5m>h3R;2TaEI=Uo9A)+Yj1TYNktVC!(&zfKJ8S(yR{9T?vzkUASdEoy5>K@eb literal 0 HcmV?d00001 diff --git a/build-tools/ConsoleDialog.exe b/build-tools/ConsoleDialog.exe new file mode 100644 index 0000000000000000000000000000000000000000..67de680ee0ce0051aaaa8ee1d166af9c10ae028c GIT binary patch literal 162304 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

Qg6E`>MG1C|# zil^__ro#y^c?K;PHru}ZL}oqV&3?d2MBe4F6UegLd19?pV|FAhhG&wF&2^41S+^U+ z*^SRjQRl&w1=hjKiJ+dwRhL3!$$sJlkLA@A!&SMiNQJFrER*BI;4@NB(vZIi-)cBb zwp{~KI7>FJ7J0!Zhfc`Yx1V<|4XXE$#x?$?qg0~OTz0FYn@xT7-na#~BsR#YyO(U3 zf3(}11Bz|7dPZ&a==xYOO~l{JzwvD&Ow{>3N8DlI#+Fc;@bGm+!yQ+rr9&r8LG(cp zzcb)RE>wmw1k@JK&N?{*8-5`rB%#jl`5LDB*V*_cQLg%4dEC;@fFk^qhxrFg zDW!%YgT?4ivsesVvrc$D`)RKNQqB<(jUN#+Vy>6}U0AO_uGlFkx^8!7)57201ve7{ zDA-VMc{#`361Kf*F-5TYnyFxMJ}Z8w3J5~@>RuKTKEn07L@t>M&VmtMuNU>)Yp&p8 zDfFN#^xr;#4~MM5z)JD3|2-miQ_bKjD{MMAdd2M?jv6Bh=c*3qoJn^FHqU>J-uG|@ zMXEOR&lqZC=D3^Txu%aQXZdSN`}a5u>I9MJFo-*ZS&54g#&8%sz6ZNE*42`4p9Uo_ zDbrD;P8IC`-@_QYo)B64Xp%?Pq)0^zdI#@49mZgP4qOaD(4-rc7ecgrAQ%B;tEQa; z@!ncoyjFRxgq-|Xo@%@tn$8m7EjLt`ZiFiTXZDw7hXOK>w{^Zx32+s2wI8m)wCFImVF* z)n|@#Jw^h~*Z+fYVzCMs%d~r*1LC<~Qy$;}enpEhd2-N7(rZ%Seg766im#A=7}MJ? zUG^?RM(2pLr)KYOvG;;2`vVh>;l0RMOhrz?F3(H4H}|KZp_uD>N%wZWq*3SQdP#Gc zjn+uRp@xD$4$=G~LqRvsw-T37z@z5=>qeiR zUYvz|gE{wkzzhGS;}i8@%rcF3l%QDenwUnh?K?+coFBOh+GFg!qvV9pbihC;n;C+v zXApz^bE4swxYuA`hF>~Iy2vcQ^t@Auh8_BI<)itY`V^UAvvUxEg_K`XH7J8e*vB~j zX!8_yrpu=N(RetWT+O#A+?f28F02IG=6+%*BTJ`jJnyQikqZo2~( zW6yJJ7DO&j`u6{6j#G76I@lmOxRCcRpo5t?*8CdzgGIIgA;bvl@J%ZrlfaJRz6}e# zIj=j%oPLOGMmf&*+UhDNGkWphis8ziEISE7!+GHc>2zydE2N4lI0K-t88~5A;>=H! z%G0?Jn<$l>7QmHP+%4p!2EKnvaK#9>lFv?}l3_MbL`6O?b&SzX4B{Km+{rgLL?z

Kkbb@Py{U%=eWpQQ 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 NyvpD9K>8p2_um;t;5`5U literal 0 HcmV?d00001 diff --git a/build-tools/ConsoleDialog.runtimeconfig.json b/build-tools/ConsoleDialog.runtimeconfig.json new file mode 100644 index 000000000..27bfc6111 --- /dev/null +++ b/build-tools/ConsoleDialog.runtimeconfig.json @@ -0,0 +1,36 @@ +{ + "runtimeOptions": { + "tfm": "net10.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "10.0.0" + }, + "configProperties": { + "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\ConsoleDialog.cs", + "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, + "System.ComponentModel.DefaultValueAttribute.IsSupported": false, + "System.ComponentModel.Design.IDesignerHost.IsSupported": false, + "System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization": false, + "System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported": false, + "System.Data.DataSet.XmlSerializationIsSupported": false, + "System.Diagnostics.Tracing.EventSource.IsSupported": false, + "System.Linq.Enumerable.IsSizeOptimized": true, + "System.Net.SocketsHttpHandler.Http3Support": false, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Resources.ResourceManager.AllowCustomResourceTypes": false, + "System.Resources.UseSystemResourceKeys": false, + "System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported": false, + "System.Runtime.InteropServices.BuiltInComInterop.IsSupported": false, + "System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting": false, + "System.Runtime.InteropServices.EnableCppCLIHostActivation": false, + "System.Runtime.InteropServices.Marshalling.EnableGeneratedComInterfaceComImportInterop": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false, + "System.StartupHookProvider.IsSupported": false, + "System.Text.Encoding.EnableUnsafeUTF7Encoding": false, + "System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault": false, + "System.Threading.Thread.EnableAutoreleasePool": false, + "System.Linq.Expressions.CanEmitObjectArrayDelegate": false + } + } +} \ No newline at end of file diff --git a/build-tools/ESBuild.deps.json b/build-tools/ESBuild.deps.json new file mode 100644 index 000000000..a0835a4a7 --- /dev/null +++ b/build-tools/ESBuild.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "ESBuild/1.0.0": { + "runtime": { + "ESBuild.dll": {} + } + } + } + }, + "libraries": { + "ESBuild/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/build-tools/ESBuild.dll b/build-tools/ESBuild.dll new file mode 100644 index 0000000000000000000000000000000000000000..a35a5cb126ed2079af555a525165156f36f739be GIT binary patch literal 18944 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%0AULT>p2cNw&akN zj*~YYeU33mF`rY0(P@+gu(_Y)EbMSWXTiM6RDu`1^G*`~@qpOy6xG}auh7~~;h)N6%zbfUa}bZ6 z#9Shgwz40~Q>n8eB0FKN%mB1@E?2ef6`b$gBl_Ur;F&Kcm|RGib@_}%C;QM7`-Y>(K`ZW=lMClLsi%z$SDp&hIZQ?# z&tC4;M86!9GN%^|L6n6MlKwHhm=#=})K>~?IiBn$(DXsf4!SbX+%m=IEZDlap~1rO&O_T@O*@KT<@+ghq`!Bwt!z*e+ibP^(uvtQ*5 zU>hg=QM+M3+E&Ztl~nqndX~!($9JAWCJbAvt4ekh`b^&W=5c*Dn=6gf|;q^IAl^lGUxhq2!5KVLF-+UWQATnnc9 zE4~){$@q+#(8(y9}oG+>QFtovQ;F8T%wezYa(28Ns5L~_v$l(i+zgBp`q@Y zJ>c^5sy|cZI^c-bJksU9<(w&Nc$o~p^VdoI)z*ly4a>C;`h_QY>X85na5&FmfHt@lVpIH*S=Yek$-s37E42DvJf?+TkWl+O-b5y{Z zox!$fG^+9u>qY6(LtS9ZSE8Y4NLvu=Q=$S$Xbi@NbbLsNBS1wLy(-iUX?mP+D*A%hj2cyI5~{LvVXQ$> zQ9t{PvW%F%j8rY6MDb!bss}ap0((gfLRxQZ_Su>Q)O{`<490FSOv8)=&Z zP~sF<@B%k>L)5SW2{KG!SA$`~ACX89)^GzO%Nm5>8~8sO4@N>Ep=UGP8;u%+s26yc z;4lzoU#Wp6aeVlt!8{esjKL_nQNcQ>cPR=ifa;-8FaY6sBg-DigAzeM5D*Rqz?p}5 zZkmsXKk6wlvloT40>On3o+H8#1!B@SDQ=Eu+x9 z21Q{W_8=25Y-oTnZHQ9{7YxMzQFRUKN1L@Um>ZT6{ski74L7JjnW9JF{AEfMg2f;U zo)9xB5zu6tQ0R%BqqiB~jBE@2_38M<=Q_?`12d6k^jI&>g+Xs{bzBjjur$=naU)$0 zcLmrL93pCzKY`-`1``IifwZ!PQMe?8(2_#fg5GEY;)H`wC>x3Zm3oH|D~is+6uTva zFYH(y*g*=7sEtP)b8^33C_N;{8w>lSiw|$S_xn2)TGY9JaHJoPbn$qs-FtD-JKf#Y zi64!QMCX@YI(hHl`CU(#n`K1s^H zgXoeT$9WXL$2iI#!+Hnz9mlx_XM}&Fu?vNYqoJbA#Y4jb!(G>(f96{sxNX-LZv903 z>|4*bu#Em~NAb?dagRdngHujsDt{D1z>oTm?zQo%=je!)pFEneiv_EA)S1HDxtw*> zb9TqpjJdU^d&Bs8Ys2`4t(md(_{J_Xy*a&pYi3h=W7h_2!{%`_y?(=Ht7rZCOqb22kV!&mjK-?)i9h2Q+Sr!btd?3V-g zIcGLKHhJ3V{_OQI+&^3{Cw#2>>i@7@Qt@p99x+?|{Rib;eve>@w@hA}i>;K{Ro(vI zuzv*);LBX}n!p1`d`gZT3C-eCafq2oTP{Oqrr8QkS(Nec_l>tPiNPyn`B#6sa&q=-P!z`i zpaQA9W7*^F3x}|G;d^C1RuQ)vK`rmNT+KBJr*8}qXEnj=UZNd_N?E2t$erAyee-55W zAo{9DqpSyy3DLPU(LYoK?i*kH%k4W)<#UN?`H@F&3zpNCgjGo6bF0EcZ_DA4Jsn$G z5_oBi7i&4YVD+}lSZ>SC9rcm=$ad5F+#~@J1-G|l$|-Df)5op6>2~C^X~%Z$@nT2X z&Tli_eCKp`O9Ee5WykRj+}{w0{va%oCqURCMD>wQb2fK5Vg%f1<`XSpn1 zJ>o@ur#U&8=o zrPLl@Y63@Dj{N=u8t=8Htz06We@4*TGLE;tmS>a@vhFh4 t_^Pj~(tZ27k`utNeVso-J4D$0%L62N{>i`x|F!!6m$&%edaUrk{{#L5jM@MI literal 0 HcmV?d00001 diff --git a/build-tools/ESBuild.exe b/build-tools/ESBuild.exe new file mode 100644 index 0000000000000000000000000000000000000000..ca0e02ca4177f76aba729c41f4088a641b7cdbc8 GIT binary patch literal 162304 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

-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 KKlXn)0{;zO*sI0> literal 0 HcmV?d00001 diff --git a/build-tools/ESBuildClearLocks.exe b/build-tools/ESBuildClearLocks.exe new file mode 100644 index 0000000000000000000000000000000000000000..14ba34676365d048d75a683af5040b02f2b7ca5a GIT binary patch literal 162304 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 literal 0 HcmV?d00001 diff --git a/build-tools/ESBuildClearLocks.runtimeconfig.json b/build-tools/ESBuildClearLocks.runtimeconfig.json new file mode 100644 index 000000000..b836b4fc0 --- /dev/null +++ b/build-tools/ESBuildClearLocks.runtimeconfig.json @@ -0,0 +1,36 @@ +{ + "runtimeOptions": { + "tfm": "net10.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "10.0.0" + }, + "configProperties": { + "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\ESBuildClearLocks.cs", + "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, + "System.ComponentModel.DefaultValueAttribute.IsSupported": false, + "System.ComponentModel.Design.IDesignerHost.IsSupported": false, + "System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization": false, + "System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported": false, + "System.Data.DataSet.XmlSerializationIsSupported": false, + "System.Diagnostics.Tracing.EventSource.IsSupported": false, + "System.Linq.Enumerable.IsSizeOptimized": true, + "System.Net.SocketsHttpHandler.Http3Support": false, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Resources.ResourceManager.AllowCustomResourceTypes": false, + "System.Resources.UseSystemResourceKeys": false, + "System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported": false, + "System.Runtime.InteropServices.BuiltInComInterop.IsSupported": false, + "System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting": false, + "System.Runtime.InteropServices.EnableCppCLIHostActivation": false, + "System.Runtime.InteropServices.Marshalling.EnableGeneratedComInterfaceComImportInterop": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false, + "System.StartupHookProvider.IsSupported": false, + "System.Text.Encoding.EnableUnsafeUTF7Encoding": false, + "System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault": false, + "System.Threading.Thread.EnableAutoreleasePool": false, + "System.Linq.Expressions.CanEmitObjectArrayDelegate": false + } + } +} \ No newline at end of file diff --git a/build-tools/ESBuildWaitForCompletion.deps.json b/build-tools/ESBuildWaitForCompletion.deps.json new file mode 100644 index 000000000..4e271f070 --- /dev/null +++ b/build-tools/ESBuildWaitForCompletion.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "ESBuildWaitForCompletion/1.0.0": { + "runtime": { + "ESBuildWaitForCompletion.dll": {} + } + } + } + }, + "libraries": { + "ESBuildWaitForCompletion/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/build-tools/ESBuildWaitForCompletion.dll b/build-tools/ESBuildWaitForCompletion.dll new file mode 100644 index 0000000000000000000000000000000000000000..8c6cb1724df625d5ddb9bf374498bf923f320db0 GIT binary patch literal 9728 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 ZbJYAY{lE4A7BK(ZicR5{=@-xg{|E0Sij@EW literal 0 HcmV?d00001 diff --git a/build-tools/ESBuildWaitForCompletion.exe b/build-tools/ESBuildWaitForCompletion.exe new file mode 100644 index 0000000000000000000000000000000000000000..e707c8c899186d5d096352b387ba67aca945eadf GIT binary patch literal 162816 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

5<a?d+ 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 literal 0 HcmV?d00001 diff --git a/build-tools/ESBuildWaitForCompletion.runtimeconfig.json b/build-tools/ESBuildWaitForCompletion.runtimeconfig.json new file mode 100644 index 000000000..0010c1e92 --- /dev/null +++ b/build-tools/ESBuildWaitForCompletion.runtimeconfig.json @@ -0,0 +1,36 @@ +{ + "runtimeOptions": { + "tfm": "net10.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "10.0.0" + }, + "configProperties": { + "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\ESBuildWaitForCompletion.cs", + "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, + "System.ComponentModel.DefaultValueAttribute.IsSupported": false, + "System.ComponentModel.Design.IDesignerHost.IsSupported": false, + "System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization": false, + "System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported": false, + "System.Data.DataSet.XmlSerializationIsSupported": false, + "System.Diagnostics.Tracing.EventSource.IsSupported": false, + "System.Linq.Enumerable.IsSizeOptimized": true, + "System.Net.SocketsHttpHandler.Http3Support": false, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Resources.ResourceManager.AllowCustomResourceTypes": false, + "System.Resources.UseSystemResourceKeys": false, + "System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported": false, + "System.Runtime.InteropServices.BuiltInComInterop.IsSupported": false, + "System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting": false, + "System.Runtime.InteropServices.EnableCppCLIHostActivation": false, + "System.Runtime.InteropServices.Marshalling.EnableGeneratedComInterfaceComImportInterop": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false, + "System.StartupHookProvider.IsSupported": false, + "System.Text.Encoding.EnableUnsafeUTF7Encoding": false, + "System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault": false, + "System.Threading.Thread.EnableAutoreleasePool": false, + "System.Linq.Expressions.CanEmitObjectArrayDelegate": false + } + } +} \ No newline at end of file diff --git a/build-tools/FetchNuGetVersion.deps.json b/build-tools/FetchNuGetVersion.deps.json new file mode 100644 index 000000000..079217a0b --- /dev/null +++ b/build-tools/FetchNuGetVersion.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "FetchNuGetVersion/1.0.0": { + "runtime": { + "FetchNuGetVersion.dll": {} + } + } + } + }, + "libraries": { + "FetchNuGetVersion/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/build-tools/FetchNuGetVersion.dll b/build-tools/FetchNuGetVersion.dll new file mode 100644 index 0000000000000000000000000000000000000000..1a602c49563780c9da4c04459f00b8076266f076 GIT binary patch literal 9216 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 RXB#hbV66OZ52UL9{s%OZ>p=hj literal 0 HcmV?d00001 diff --git a/build-tools/FetchNuGetVersion.runtimeconfig.json b/build-tools/FetchNuGetVersion.runtimeconfig.json new file mode 100644 index 000000000..568a9e54a --- /dev/null +++ b/build-tools/FetchNuGetVersion.runtimeconfig.json @@ -0,0 +1,36 @@ +{ + "runtimeOptions": { + "tfm": "net10.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "10.0.0" + }, + "configProperties": { + "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\FetchNuGetVersion.cs", + "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, + "System.ComponentModel.DefaultValueAttribute.IsSupported": false, + "System.ComponentModel.Design.IDesignerHost.IsSupported": false, + "System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization": false, + "System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported": false, + "System.Data.DataSet.XmlSerializationIsSupported": false, + "System.Diagnostics.Tracing.EventSource.IsSupported": false, + "System.Linq.Enumerable.IsSizeOptimized": true, + "System.Net.SocketsHttpHandler.Http3Support": false, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Resources.ResourceManager.AllowCustomResourceTypes": false, + "System.Resources.UseSystemResourceKeys": false, + "System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported": false, + "System.Runtime.InteropServices.BuiltInComInterop.IsSupported": false, + "System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting": false, + "System.Runtime.InteropServices.EnableCppCLIHostActivation": false, + "System.Runtime.InteropServices.Marshalling.EnableGeneratedComInterfaceComImportInterop": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false, + "System.StartupHookProvider.IsSupported": false, + "System.Text.Encoding.EnableUnsafeUTF7Encoding": false, + "System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault": false, + "System.Threading.Thread.EnableAutoreleasePool": false, + "System.Linq.Expressions.CanEmitObjectArrayDelegate": false + } + } +} \ No newline at end of file diff --git a/build-tools/GeoBlazorBuild.deps.json b/build-tools/GeoBlazorBuild.deps.json new file mode 100644 index 000000000..d70590fb0 --- /dev/null +++ b/build-tools/GeoBlazorBuild.deps.json @@ -0,0 +1,23 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v10.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v10.0": { + "GeoBlazorBuild/1.0.0": { + "runtime": { + "GeoBlazorBuild.dll": {} + } + } + } + }, + "libraries": { + "GeoBlazorBuild/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/build-tools/GeoBlazorBuild.dll b/build-tools/GeoBlazorBuild.dll new file mode 100644 index 0000000000000000000000000000000000000000..943fcaf7a8c47d948b278a14e4b05310b7b2cfa0 GIT binary patch literal 40448 zcmeHw3wT^tb?!cAMl++)^UUb!m&USXkFAIGupPu9fMPlWA0! zH#}J`9xHx+@#EUg=NAtgPoyK`X6l$38;cCblF3viG8B)P6Uj&-8QHd{KQfjYiMN%N z1(#Z+_x1^~Q}c);Kk5G;c5g3jyf=jfO zNgET=kqO7-5lPU8y&2I}fP11)^kA@|T=r9=y3rb{tbQ~TY+Cd+t53~DLmTFcg4O1b zX6|xeh584F^C2%CV}+VSo*n46Ra+@MJ@ab;jS)qw>-Rwgu z$wW7xRM7n~?o03)Bz{HkUMvL^lKGt34F7$asA0(H%xlaTk0{jKV_y0~Tg7#_iF;9>X4ZxCB zOH?-vkgAPt0b;PGq`B1R|44Kz3jW%IC4S%g5}p5e$+Jw778=|RJwQ{d@RWld?Si`M z2R-QTHnf_8ZcDp>k>Ki?s+L#pRE@k=Ple_6tU`-IV`wKVMYp3lbxF~LizH2u4^F}U zCCv(X^-Pt?t9J@K0A4*+BClr^S`?Z8mgEy+!__+l&6hMG zFI>+mv?wG-nk*@M&hiN%lg}H-CyWPe^eHGWuAV7yf~$85qr|m(3Tle$S%nsb)JT)1 z=uV4Ik9Y@=FdjoUt1&N87(g)Saq=a;)NX)U0)BaIE!I8rqVV;>mA=$oTxwHL`Cw`v zk|<0*SgOEvdEhbyuFnI9y$U{0!DUZ%IUq@xUa7@X(_AyNihYKQ`~`Ul`xHE%nXq5M zXK;f-a!fhgE}V_Y1TylI_ci<*L!L!u%?5ES~)4%P2G#nXlnu z{+x~J?$Wm)d26w`(PODv*lT!|Vj1TB02W7Y&7$e3Dx_jlkdW7|%%9sSXnD3We}boA zbu>yyH57) z*C%P~Jrz(3!`D(`J`dR`;bte`<6b!d{~ecbvH7pK7{%s5ku?+Hpq@SqQBT1~d4;c~ zSD$3g2&RqzntBV8un{t%gUGb@>NQP4=}mOQn1ToL>dL9Wt3#yC7k?Lg=##7n8~RyZ zFIQtC=Ihl~J5Y*&QYdt}dKnzK5sD76hmxvrsZqj^D;N%k!scnP7b=U6pxkp896j=J z2W@oYEGNzhiNl&G++uSSw%80NOO=wBm~RJ*O43HD`6|Upm)TTMQ^Vy7p0A|g z3W=Vtp5aQPT%V+Nw|CmPuAot&PePX7_C;A(gAMDdHY)W=YIR46d95$YnMI~6kwqM| z5xe%+)u*FiIb0R0QoX4ltjZPqpn_c%tYB}o2dyd@B!vUbH`zq1L)C7g)h?o_aERtr zkf8n{)VwAM_p&&Atxl{*8Sm|j?iMm>0PL)*S?$@9)hOcKDmxki`YLqph z8aG2VE{0IyFqBu}FqBha6e%ui%v=4K`jwDlsK!9(Vu5XW9Iv0Jx~~n@y1TD+b&m?C z`@9OL`d6R{T&fS(=?#~aeM-AD>Y_<-cBv{C?2o1Z1<$>(8>}kg6(kF| zyug`MqRcF$vQB~crqGX9pJbZ811+ZD@4Z%-oPbDGn5<7Sx{be@RAdBm+Ao-a8DV)7QUV*$?zl#tqW^w(-Ul9V!Fmt zCy`B`LQ-atTbG)2vS+i|5WHs#y`(oa1z_qN zlCqE|`Zio!H%nhkx$4DJAzoA*>d~W+S@XpQCFiUt)6ep9xw;v&q$g%8&^e#&DfM=l zK-a>kg07thash>^My*?+ zxIZ|D_{^XXd1997qlM@?$6GpD5?UCrqR zIj7`b4@|+ZFsD^WL%JTt(3&ru(kBTm)z9+cnou?Y5ezwasas8&>=Tp5t2Jp}&WEI4 zHAS$ZZg``=$#(M!)<)l@M4X+c-=bLY(d%TEh1D(b$ z^CPMELu}zIKzd*FohOzbQ6xdw< z8YlrWvHo9?>3&p_sddP-uHT?AN7nBkf%oV4GrayTg>Y>B?L0DO%0lZ2J*}W0$U-X! z9a7MbWuZ@zhn))gyIJVB30s?d zi-LY63;hM5+Z6P{EcEZGf^7==SQh#d;?^nX*Rs(6MqFJ%|2PYMjL;vW0p#$fS?Fd` z_zMO7UKTn{+@}@vl`NEo(fzQ3mX_F(yq-|%v0f{ENB6r_o(`n@tjg1ibdRe%T}d~E z2YmXI?t>~%r_#L>`P#B>oF0qXu(x|7u128tpmG@ROKfN%uH`*y4>pAZ9|@NkWets~ z4?<_S02s$=;$bePRI<=|}1$Dt=}Zq31I$n7c=jD84$XbI>>PEU_wjNY7O${#dZnHF zqik;4uwjcscJ42-xrf3w?0A)xt0}p7H=-mpwPoE^a=|dXCmgZ8hfZX2BE%q_KIJYWtWRl!lT*JdbSJ_2a{-QX8D@XW_i zc(AF~d{JKO%zxySdmUfux6vewBb?}c$XLgIi`kh`J++Znb-%G%k0NkrzW8lKclsnN z!qxg&UN2Xd+sA%v2TC6XrDcj)eUgmx-iA*B!X>&-3QO_0F7pPQhib9zIP&H((j+;!s;mffC9YgCOsxmEz{-lEFcxTGZ&Z7z zuN0&DI(`gMUdK|l8F5Y>lxZ*^#6Ke}??gcU2~6lb%=X2Q5N*|v+6Aya>UY>Trt_y7Bqk@^73zr&!*tTu;4Vwl&g6SZ;SZUU84D+`Sx9+d0A=BpXwvB zvb*_uG)%ku7~F?G$%^oN{VcDpyF}9N=F7W8;d#0-Z)zI}$WWuFg;t_Za`P>N&8h9I z(1UfysDeJ}&{=gL0^cR-ROq%Kw7~oXbpuuv3@uRT>H(Vt=2Pwp zNdcM(Ec0cj!U=j5KUP=w0uhg){O$ts$)@Hj$f^aIOI7ozS-#L7gSky+We>fmREwE= z_B_j)SI)Tc3}Cf$-`VQ;0kl^Wuk<1HaRRE8MpVi9Y%X=nNJ%x9?cG^^X0rW0S;v`} zg>9EL&CYgquam>Jv`4vTQf$i*?#fY7l``TgWr9_fRdAhG&uHDIPs+k4DA!LS2`>yS zTml8aU)9sm3k1tp zR3uwM|1h8YED9}(K1iay`hu((EtL$LehYZHD5f7FhieYMR<{Zme;Q%pdZD(-8VZ+;C3`dRK>qo0BRQ=g_3Z$9b+t{Ps)ZtT1fteYf*MK3U0V=K`=g-4Oi3T?|`jv zWb$`;S!_gFHZ-iW?4&W&Xnp{LPKY^ETqp zNFBRY820{^qj9&{RD2nGxVjeJa$1Qv#s)3+cqeG=lB$JFXC?QKg^d^vqZQ>deovQia88O{lk4l6h*D z9&DO#x%F_XC20C)qqWdM7*sEqRlS0a`I!J!k0)SPJ_(Z!IbZnS0g3;$?A4M{U=rf9A>1_1bX|1Ylp*Hhj zG60Vj47C|iwTQL3R@F9Vfw7~#GTEnef_c&B3S)&GeXb}Nef}#tGge$B`YcQ%8+{He z2g8tlHu~ffoLiR`j<@MStza zDnx%hmY#NmI?O%{L+NRUu}bM_hf7a896hZKuSE3Me(olW*5y{PN3^3q)~M)jrLoe9 z{yNbz8~t^Kx?GW2mpd}+az$pSa3ZrV(~17Nj80ed*X6M1ivCuIR=fJZS&9>3u6Ff- z3a5|NuIO*IL)9J0{aVqVpV8k+>1XB1mAr{$MSs%Pc~0n#{?-_4T+!becl5U}SMm*% z{KK%=rfJrw=&wH)CqkUhN*va>qQAAqT10j0kaIz=sQc2`(HQE*y(G0x{O9 zN3f>;FZFLdx_T>lyyhXk(J?a`NszmEvJrR$+9(>nplzRH;N zn8hpLxgNuOwU&C!^(e?Nab@kwMV|B@0E}zu4|%;3?v?8D>8$ib{|NN34_N8S?(?P| z2ehR`U8R1nEC_@>;Qg{{jM2dV6`Hx9BX|Oh`2yyXWVOaqb=jldX{78z!1FY;)}+3~ zem?@NFC)`hTvJn%ev0_MtU!L-Vq<}e4P8FRs{ry@<&|^85?lIj*rKUvmhZowT;0~* z*45tCfxQx+4I4#zx>ATG=Y;qHu8}bE{TVZnJeDSg7jt=h1z`L8#po{eJo%FA_V3t+ zy0a+bX*scE%V=td$oPYPXa^efU@?|L@k^~sKEua+#R^oe7oOurDkTu~u5povd3mRv0LiQT0? zMf~;KB~1HeIxf?Ignutc_#a3L_XSB|pYZ@7JA+JLlaRM*Zw34l8fzEJUcM&bLD_0a z1>qNpiT_mD17$(cW?ZiDiDl)494uqob*0QdFY!OFKTuXKKCkWdheT=F1=L{G_bUAxDE_?r4*^?OQ8|CEW zc=FD6cV8Pm}aA-@E-jbZ?!XcWI+LCB9ntla>} zGSMF({TfgXiBE(sREESC%E|dIv982d_byT<(AN@;&aa&?E~{JWJ8lyQESbE+}#oaIXKUch=}$%EHL7eUM3 ziBdV9YOEB`0`r}s1XwJ6LYBhN9+rM4OY`t_lA;o`tNFb*E9+ z1AUA_bKVwQQH1eUv>>eytwwrJ`87yGW!DsG;x>H+(moHY!W;wUJBt-%ri$`xnCx8>X`Q_v^e}Dp zGJQ#=A1Pu!>SOw0nU?yQUn(Y$z9=}}OB&NZ*O}h!VH)!?jTABcwxqCLw*9yW*()a7bNRNrTkXC7=wph|R;n|FQ znTPNfSevS<&7IlttVF4g5>=ey=RuS@$~Z zOBWwgb%A#O%SF2QvMk*z?iP3AJ^9MTXeRCzZQ75DykgucZPZ@}-5*<}g`S`m5Or8f ziTOj%v+#k(tMs`R_VvS7GIsX z9?^{uf1}+H@?kChS43qjH3eHxDs6S@=8NO2oVxkqv{hoe1){RUsaqf-R*7{BMIE9d zo903hwMwj8B(@!L>K2K8vUE?~&nq56Eb$guQW9(sM`h_9A}n6?Hi)-drEiK(Uqrmy zDm}0D_!f%~Sf%Im7rl+*_pH)c&x?4N=UY~3ueZ~;RQ#z`swnEgi-a#)r6-GC^ez)G zTctkqw_NdZLtOm?(FFn zS^Ib?aa5`xGvPPD&uT)Yy~yk04`nNN{s-V+6Q{tBow{r7yhq%HXPWLpq;MC!^j(Ms z?t+cKj?W|*Na3rI2E_`bmG~k7(;k`j%5;ZJZ<6UDnZ}T6h;iBWJkn}$KhpW)f=oXn z;eR93e?S_M@MXe~7Gy}v*`cv*sW=_njI=Sd1L;87&EgK(s!C)k#$Ypd8)wD+nif7U zE@<0~^Wrnw`-|@sk7`ea-h=$B<-djWWu*6Oe-Zcq^1Xjn@HLYg8hAXX!7HzBk15>lMEc-^5sch14{PG;;DR=)5}^)V{AB3;N(S z?klgX@-7(=~qO(ZU!IL>h-sj|GrkQ z-4b{iX=Uig+6w(PjUHX8P|90u4 zs6A(VS8owZ%3nfypYaM(`qsn1@j*)8D=YEbq_y zH^n1?6`pU3kI3}L#Xii!_htH4f4k@V;J@2*NF)DCCI5%CyA9%K#eMox+51x2`%>9^ zLgN?{8o5en_W?5@^|n;DEtUAC62Da9Q}=&MTJr(?wXH?2FBjuT~^!%R69`6%kpt2X~qh;5559#xY_jniU50xJC)@xrZ zt%Mc4$Dcy&d8wraFc(M))S|a}WBSiA*Y|60t6=)QvOB#a;xX-Rq@UIA@%HMEg+Amx zD<%IMGEL~Gp@#{52R@$0&R#t55Vt-#cfFEi?<%~7H-70>D^hOEq zN4ixEiyQsJG93|<;$UC|E6$DnX}pQohm^JNkm)BS9aC@N!Gq3^M5B( zp^<{nNWml1h=fG66JoDFA|Xp;daZKP}W+wJq9V?WlH2drbSWzTI=gGvWDx_jRuao_hsW#zmMzuZSS;#n-l) zvHC1UzDO)X-iQ6d3ZyHM_lp+f{epAejp+5HxK2Bv;o)a}kA7bN9lgj?;|X|cy`S+u z>Ge)?rE~v%9V;Mrxb|OV(YLrk&V$W2X2PD9tA1|V3k6{RIHPTS(FUyg`F%WC0Jf_D zFI&KIe%o)zwjQkUUi|P4CCEmHOmuwTN5@*NV_m*U^ouXycTv1YbZhsB16qfOY4-_J zdqy#f$7;kO^ZBlt~t`?ZJA=8N9% zi?4eBQatYkOB;5@63IqvM`P)9`=E=?vBAOX z;+cNgZF*b6j1Om0=9#lOI3wUL%XLRS*8t#qagtMHEl%^XIsq7(NQ{o`i{sQLE_owt zc)~Q}$;?*pd~@7PCsIktwW~Q8JYXg=@%~JF{Q7uoByNH^)NksBXmFX}Wk+9fVk~aP zhDPJJp|r;YT6`o2I1o#pKwWS8Omdj{UGdEE)W{a{6gN>pSnsJAdSYp3BAp?nOnj_E zK)&RRy{Vb&%$ETG;}b)piS%*TC^`VO#F5{i6M&&aax`^p`)KT#oH;;}@l*MN=oCAW znJ!mzw>Y+@#>PkEnfM4K0+g}X?J3jMKR}sOYLv4odyw-q98W9ZE75g|?Gwr2+d9R~ zvC)b6zy#=_z+rdV!v+~^*j@R<1|T(bbRs<*%P3U^z#4HrZYKa~Orhiid8mw|q%LHP zZ(E#$%Ie~dqkX3_8)*y@cw>oV&L9Dz!taZZr}m{%8L2&LXsEIHUY*Z30LS7<=nJ|@ z4NG}+0A{hCkKPFYSxi4j1VHtR6^Yj-%oDL`Hf7aL%q2=eNW8*}Ma4v3gBD zs{jm7q%)~8*Q|E{c+zoTohV`krFZEykI8B1auISfrhKo>jcO=O!)67b;Z*Wy;@AWf z)*59;cMex9=J3=Xmjdr}p`p($6Jz5R({_JA0Hf&7J$L|5#zqq(F{}m9SadD*s3*5i z6e+lzL3RST$%Thb>7`;>_f9iLeU^M)m!8krc4Z?cw4(SHWEH`cae4??43@yy`1 zSSE%(hV6>2snJo)8|0F1yN*Vk7#3X7(~Bd zI(9U^CrP=>)j^7FN7^a(j*rKaBap~gEQ8fU#70I2`%E)sQnvfz!|}vP3#u$72Yg*T zwPiH+)|4sdT@09svA*Pp7*?J@z-f)fhT~#KdiTWW=pOUHajxAk?YLxvbFdX3kd=j9 zSc_or0?OK#Jee?4N&2jtV`hR2xp0DBgszwGnG7BZht}zmTVaBNqlD8cF5IOGO?i^k)L-Z~2V~M1c-#*OC&P37zDdA;d zQrl!LW&(>pWF*xS%StA`D>i(bAc!KToOV}^5<@N2XU5}#6AHr;2aY4y5nE&9nF(B# zq~e&EGkarZ8Wqr%OdKZDF*qp63AMlq$&jQ1QJKS$LCq_o% zNe6CsO;WaB%W`j5?noY$nhp;U8=VzPxjDJ^}hIM?6l0e>TSN@`9>y&GY(B#v|xpw7IrEykFl{{(~O;QU^W%01W8wg zrIiw%Nem@M6B$=6En|N=-hVtkI@)(SKFn!`%m<}bNkdd)vdXcOadFhv_pIL$GQQq& zW?MWx3`YV_WTRM}w^?Fl%|J@IV#g`NH|%1-Bdm~F4Cm+r5oxbn{=_&FGPpCIJccal zq#&#!YZ$l-<6heX31g5PEP7T>O?##Zb&7P!WuB!^iK?B%$Qt}vSNuJwbm$c zotc^#ch)S3JZ26b-!skyOv?ZCa9kBeAYE<-WrbP<2cQ;hH>8OvmpA1B5(KDhd>|!g z4Agms_V$2Nw;a<#)1SHY`iT=@ed|Wy>o7>&-OxyK{+Z3-h6hUPhyw@FeS?2A@ z?M;qsh0ILRJL)*q{y5x|3?YuQrr^d4ZYeW3IHY!Aa5zU}6Qke`(>R`jkmDn2pw}bF zgv$`_m8kC|Y|pMZNTb2_8aS?voKzRJr-L5usLz@uiVXYIF* zBErGc9TTz9G&Dy_&OxJ+?Ta6q7>yxh8aJUc46bY*9o+>;YGMC4e2miIw4iokPlerh zG7F=XO1)1@gWC#qP`UnzVXCA}+9jMeOIzi1VI-0sSe83MvWzXK*fYeS6;?yzqUr5G z#FH3K07RDDaUYDqOlS6(mWEM+m{aH)ZO+PB8nPpKk`YKUBWMI_^CAvfzFv;c&U0Mc zblPQC5MvLCR&&snM~-l$DA-z<*4`E3glWnV=PQ^BB}7VYT*R)_$@p%5e4epI@8~Gq zf?Cb(0^A{|mGG0Yqur@f@`^~8SsH38@iVgR zmRQ=^l}i!_uu4NIvtg9rvYi9Kq)0WxB9sjY`^LsmLVSWrz%-A?O%(Are@IN=uGgp- z5v@2g9u_7_;{p;9T2UKLIz>r8N^!uDUl;*K3g3bnM~k?Gj{u&)x7ktaX~S9$R5Td?oPBL zA11IzK`VyRanzuv9m^#K+YVzia4pD@{&r9@0aK+ulL`R;Z%F}(q^l6C2%+6 zb)%U)w&5R7ur;g=J#hxG^g;8KK8%9{6aAloyjeGaT2V{Q;8<^#wP}orb0w-(n>=U( zu_rKo&JaQfP>aacF$odHHZ|c_?L}WM1i4M%BdByiekoTK`|*g z1)-dkB(<(WV;Tpxt=+T`=9OgR+)aOHD-e=d5sX79Ll6rUf~pzA&+arLP0S%cQ{M~R zIIxuYa3Zix1&cHvDmSmW-P)!G8@^IPY~esPBb9NTScU&ck?tcdB|uRRW7MsHr6E)HoxH5nhr)8?ij|ML@6RiOc;%O z<~%qGyc_&nC)-Eh%=W^SL6Qe@)$vNDTvd%?{I<@tN>x>DEj2w~pKnQOEpRhI^@~7M z6o*nL6J;tCm6ZcaLAdmS`NR5;R!XW`Mozk;@Km(f#jaKmjy6{JB%5( zU3Pv@Pzc}c;D<5U3>+YUS~nFgSt;;{T7Mb?94=_xh4|!Hs5*tLyAZzR;(O;NDTUpJ zg@y{4usj}n6czi>tK*-<#(aN4dA}!tE{I!-_K%$i!qnnuO(gb_L^{GAK&mO0A%|VEnkA1i!qd z(Yt1l=8%*x9R=h9NM75bRyY$4=}DQQHH?oi&fmDu@UO|RE`Nqw(T_7yt)5u)&ZZ?z zdVZ5URj9C%y(Yo4Xq~Bd5m%TKLFnfM(xR5ZDy2Av_R6cLVasCrk0P*gdy1L=_5X8B zFjBzSxwKP_7y{52Gd@-EqAJ@a7C}@(x51c{@f5v~^4=;+rEpdVZTbb9aq1w0TS_iB z+Q`?)*@iX%#wH+DTSFbk>v)g+Wxh^7Z^aRO%m11o&`H*w7KC{MQ!5dIvi_OlzW+dFseS6{ru9*;n?gQ z6ua=`zrC}y2j?CLojVPeHbZ+*E}!!@H|6>$nW2TyuiL|5FwYI2@{{@O&Q{)v`LM&N zTs_aFNA~B&+!qydbiOugZg)EyBZc5IWxNZn(CwQPWx7M|UX_05D$m@Q{<>oNWR~UJ z6(%A!V4BqG!VUK(bT-?6{g@YSsuR##GR2(aQ-Ce9A>Xz^}35wRaK+j#{g zSdJhhca!P%{8tMa)eJnV29q1}kagvjuB6-UfiTZ?aSSq7n#;pDE=>ukk@Of!XYHP7 z4YreX&y(8pFeISQS3Bm}XJ`%8XiAOYcy>DM*esvJtCxA!kcQ22zhiT#f)s})Ei8@y ztQd52KgOZ9RZ8TAgCw^Br@^ur*@9dGP~MCeS(6Hi_8H^_N3nhS*s zc9@WdyK$z2-3H$>+nT&x&JQIax$T+R+Ftr*ry^T6ID9aabgx^oKAby72`h^NPx-zT zct@BaW?|cw*j$Tv;Sh8?@xrYWgw;?RC*j5>3%HDCzbQGa=8n0xST+rgE# z{%P!Rms^PGEn}TBWHuIMes`f?1w+ z&>*=)l6iHq!6lGh)OJ0@;HkB{o0-!=(56LN?55jr_xq)+Xd2f^DY8T z;Y+9id zPGMhqN>ZZkh@#ucUp+O6$~!0}J%Z7YU(~Fh8>dP^^Z1l~9>wS#>4-4LlSXe`(5R*8 zWAmHq6_RK{9;`DRg+}45EHnVM1`{FR4?^df~{f^JhDJvY~KvZ-2-c}+2-GorgKzfJO4MO_6yyVsE`b2=<}s& z!kek!Omtk?oVY})`?8GeWt?r~wtzA1I3Nwu8G9$@n%lFPrOzMy`DqB|z?J34VnW2iUcf`H&$%ELac6rViuD0*s zJ%j9;u!8aQNmtl5lPfFoUX{CZ9DwA~h_h$K?{`kz=^|+lj-B@7Xd;3;f0Ia$Nr|qP zIFv1Ohs6}qjrdWfbhV2C7kyW!IU7Zr9)idw-b?4)tjfFV5|@zGc+>`c4Q`jZ!ElZ< zsMczG<)+N-z1)7}C{Z<6bC&0tt8qaacJI|CSMgtut2a4!UCMv#0S9=b4qRmLpb<55 z3?<$XbZ#H0n*s183soECIcIpJo1C%yTeP7OR<=^j&z`GOyqYfL=+>&47HUUVg%(p$ zX5Uw$T(p~V{UTQ;)!Lz&>wVl0Wfffh56oQNufz|jJNGyWudmXBPXA^ut8*v%@4SHb zI-;>%qRq>=R5r&A+6zhUO$5<2m*q;5_J~vv42ju&sL;RtK1L=-iOVrK{ss(Sg9CM;yUB{Owk5CFtCW2r&+*-FFm} z`K+5(?;hWFJZiH8Ck%afeoR!HL<{H9DuKWH?~n9;`u6c_-w`?UZ0mRTy<2!Anijxg zAX*VJhQVSvv!RX57BRa}0u~ne2%f&n>(`70zG`Fo0WE+xuw^DJ{O$NQ20jPo4Wc#> z5!InS4N$*UZS2qjMJxsgMky?cB+whdrwP15)60>RmwWK9DeFEDdMsb)!CTtp<>l<^ z5a60mfVt_Hiy}Ix_}JAV!EX|QaW>Y{O=x{*I(93d~UfZrP^55+?X zGzLk0ZVYKT2dDdmhKlLWpr8lPqgJkySimp5#3?WG>kG>weNgw9j!q3K@*z*&H72k;fAdW>lLZv4&%bf6-05BU2KXi>1p-j9-TNc|T| zKzc-%>gaw@Vs{Z; zFRw%fOa}-$zp%JEH2stg5IWPf1$FZ(b-g-tzDZkzPI!S{0AZ0>r1^pp&o2SxdVMAS zp>P|;jj3av%N1RW^Q#uc6_S)2Pf{dCX(hG8q6KZzIQ96@ji~ecARl{*Fz?3n=Z)z{ zQ7z{zNR^Y#%7YFXz6pV*VNEIjGk%C|42`4&KJVukK5tZ(`-=iDdKS2<0v#5B*PZgO z4+QYf>0ssp<$(Yc(w-|`DQ%~J;Gv6hH3f%^Bg_PhLrTqzL!ktlVAxLpvAldCD9x+_ z5^N)sfcAK(=RicZ+=I^`U;+aWu#SQExq6lTIZT9<4mbc~0py}99o38@Wl&$87AK9U z+#3Iatm+V(TDPDGPt6=Dx8MP|5djOMQA*xDzOcYg3quziWsv%!XEopnC=SOPl!}9l zaRmLzYf%t-{sb%>+N@)Qa4gWuBSo;j=?`H7rC$1h^Hr$s!g7ysz6ZVnA^^k}@xZhK zfk!qEzRmda;JUycPln%kzV+fwUb;<9=)Qp8vS8f@Kc#zpq3H`gfM9Tys>YFz#|QGh z&{F*3ULPiq$sbq*0v?}nq(ZiIT9Dk`iX7@gk$}%KjG&dl$VyaJj+OY&SalqigZ5QW zp${q+(y#+?-*6pF;XEm7=ns6PCp1QV!AA)5rXIkc0@AfuSqM}I0YIcXdZHYLU>pG_ zoY@7T>2Cr|7bI)HS{~5wZ4Le{;>QvP^qK=^YMs=w41C?38WeuRSgh8>sw=mj z`MUA!T+Z_Du?Sl8gdx_cY`}h**Jr(+LUBu5!3v5)bBSevARd4)*Z3%}_4mV9+TSCz zU3)qE_{yvZJc{4Fb}bDK->=1QIeyQf?m1T-u_~Fk{`U26>pw7mp!ebDE?@WQl@HwV z&qWQ3Nn`7}!+7J-OdrNOe0wL%k%_UxP%pkNbr>HOh>ac|h>wjQ9+BTOIBZVfZTHdm z;ao*(UA<;?cgNAr?veP>YdThUt?B4m)3X|i(REFC_nPjZqn&HJ<7+yG+GA^v4z;)U ztc?#H?dUjq%}`H#WcVnm52uE1KWr*R%%j~lJ~AZwukY<#vsPH_ABbD*LqsL3zWZCn zul?O>^Y1tP@+aXhIOA<)KH`+!xds;=Hn*@Syz9xY&xo-!U)hh#S0ZJLH=0D`T6f$3 z%>O?v0bSZf1b15aJ>tE%<_<@Fxwg9ioOpT2fGGUqGpcA=LcD~?{QXa(A6)Ify`I&` z-i$N!L8RP|^2M;C;%6FNzBhSC5ysuqWR<3BNJZ^N!T71(PSG&dnaYq9fkD*K) zQm8HP4(!NyWXHdyvef`;xrfrMX-LI0nIx*mVS02>A8M(h5hkcrLNMpCpmzpE9X0ZleN*jh& ztp%6unENi2IsxkdWJJQR!5D^6R;9S0hVT}_8tmIUk@85I*DhekFj9fmoU>lcI1d*2 z=+mfta$t5oIEVO`pPv=thb}{S?Mq+Tu=(`ZXyl~&-ps~E#4(MLcyc(!SMfJC?jP9R z+T9qzw;u3v@@Og<-`IF2o^IT{sVrC)+z_)q*AM}TWO`%cgqd8I9zGr)i=|t~62oRH zojRIn9Zrp{i>1ffPIfd#@P(hm(Reyz2V}B85Q{{z#CG7b3>m!RnZpwUt;R?aLE6T~ zU1zZ7;@w>N-h5kZe7td$qL4B1DILC!K1Y5!8)ZB6oyOM-@L{ksRv8d8e#Zp(jF0R! z6DP5XAB(5wNVUtR8o{4KM|~jyZ$IyhpNx-2MwxDGjHU64FkbyP8zU2m-eJDMys_~p zUZsv(gOWs672w8ZeN_(c8&+k70E7*z>>1i5)#mESBM5DQb#3R>QU4R;|33-*AE0n8 ALjV8( literal 0 HcmV?d00001 diff --git a/build-tools/GeoBlazorBuild.exe b/build-tools/GeoBlazorBuild.exe new file mode 100644 index 0000000000000000000000000000000000000000..a41d208b296e39627e988fe0153d016cab417d14 GIT binary patch literal 162304 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

-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 literal 0 HcmV?d00001 diff --git a/build-tools/GeoBlazorBuild.runtimeconfig.json b/build-tools/GeoBlazorBuild.runtimeconfig.json new file mode 100644 index 000000000..59562bf43 --- /dev/null +++ b/build-tools/GeoBlazorBuild.runtimeconfig.json @@ -0,0 +1,36 @@ +{ + "runtimeOptions": { + "tfm": "net10.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "10.0.0" + }, + "configProperties": { + "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\GeoBlazorBuild.cs", + "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, + "System.ComponentModel.DefaultValueAttribute.IsSupported": false, + "System.ComponentModel.Design.IDesignerHost.IsSupported": false, + "System.ComponentModel.TypeConverter.EnableUnsafeBinaryFormatterInDesigntimeLicenseContextSerialization": false, + "System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported": false, + "System.Data.DataSet.XmlSerializationIsSupported": false, + "System.Diagnostics.Tracing.EventSource.IsSupported": false, + "System.Linq.Enumerable.IsSizeOptimized": true, + "System.Net.SocketsHttpHandler.Http3Support": false, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Resources.ResourceManager.AllowCustomResourceTypes": false, + "System.Resources.UseSystemResourceKeys": false, + "System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported": false, + "System.Runtime.InteropServices.BuiltInComInterop.IsSupported": false, + "System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting": false, + "System.Runtime.InteropServices.EnableCppCLIHostActivation": false, + "System.Runtime.InteropServices.Marshalling.EnableGeneratedComInterfaceComImportInterop": false, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false, + "System.StartupHookProvider.IsSupported": false, + "System.Text.Encoding.EnableUnsafeUTF7Encoding": false, + "System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault": false, + "System.Threading.Thread.EnableAutoreleasePool": false, + "System.Linq.Expressions.CanEmitObjectArrayDelegate": false + } + } +} \ No newline at end of file diff --git a/buildAppSettings.ps1 b/buildAppSettings.ps1 deleted file mode 100644 index e49d22acc..000000000 --- a/buildAppSettings.ps1 +++ /dev/null @@ -1,84 +0,0 @@ -<# -.SYNOPSIS - Generates appsettings.json files for test applications. - -.DESCRIPTION - Creates appsettings.json files at the specified paths with the provided configuration values. - -.PARAMETER ArcGISApiKey - The ArcGIS API key for map services. - -.PARAMETER LicenseKey - The GeoBlazor license key. - -.PARAMETER OutputPaths - Array of file paths where appsettings.json should be written. - -.PARAMETER DocsUrl - The documentation URL. Defaults to "https://docs.geoblazor.com". - -.PARAMETER ByPassApiKey - The API bypass key for samples. - -.PARAMETER WfsServers - Additional WFS server configuration (JSON fragment without outer braces). - -.EXAMPLE - ./buildAppSettings.ps1 -ArcGISApiKey "your-key" -LicenseKey "your-license" -OutputPaths @("./appsettings.json") - -.EXAMPLE - ./buildAppSettings.ps1 -ArcGISApiKey "key" -LicenseKey "license" -OutputPaths @("./app1/appsettings.json", "./app2/appsettings.json") -#> - -param( - [Parameter(Mandatory = $true)] - [string]$ArcGISApiKey, - - [Parameter(Mandatory = $true)] - [string]$LicenseKey, - - [Parameter(Mandatory = $true)] - [string[]]$OutputPaths, - - [Parameter(Mandatory = $false)] - [string]$DocsUrl = "https://docs.geoblazor.com", - - [Parameter(Mandatory = $false)] - [string]$ByPassApiKey = "", - - [Parameter(Mandatory = $false)] - [string]$WfsServers = "" -) - -# Build the appsettings JSON content -$appSettingsContent = @" -{ - "ArcGISApiKey": "$ArcGISApiKey", - "GeoBlazor": { - "LicenseKey": "$LicenseKey" - }, - "DocsUrl": "$DocsUrl", - "ByPassApiKey": "$ByPassApiKey" -"@ - -# Add WFS servers if provided -if ($WfsServers -ne "") { - $appSettingsContent += ",`n $WfsServers" -} - -$appSettingsContent += "`n}" - -# Write to each target path -foreach ($path in $OutputPaths) { - $directory = Split-Path -Parent $path - if ($directory -and !(Test-Path $directory)) { - New-Item -ItemType Directory -Path $directory -Force | Out-Null - } - if (!(Test-Path $path)) { - New-Item -ItemType File -Path $path -Force | Out-Null - } - $appSettingsContent | Out-File -FilePath $path -Encoding utf8 - Write-Host "Created: $path" -} - -Write-Host "AppSettings files generated successfully." diff --git a/bumpVersion.ps1 b/bumpVersion.ps1 deleted file mode 100644 index 73ac00b90..000000000 --- a/bumpVersion.ps1 +++ /dev/null @@ -1,88 +0,0 @@ -# Increments and returns the next version number based on the current version in Directory.Build.props -# If -publish is specified, checks against nuget.org and increments the patch version if needed -# If -test is specified, uses that version instead of reading from Directory.Build.props (for testing purposes) -# If neither is specified, increments the build number (or beta number if it's a beta version) -# example: .\bumpVersion.ps1 -test 1.2.3 ---- would test the version bump from 1.2.3 to 1.2.4 -# example: .\bumpVersion.ps1 -publish ---- compares against nuget, increments the 3rd number by one -param([switch]$Pro, [switch][Alias("pub")]$Publish, [string]$Test) - -## Read Directory.Build.Props to get the version number and increment it -$RepoRoot = $Pro ? (Join-Path $PSScriptRoot "..") : ($PSScriptRoot) - -$DirectoryBuildPropsPath = Join-Path -Path $RepoRoot "Directory.Build.props" -[xml]$PropsContent = [xml](Get-Content $DirectoryBuildPropsPath) -$CurrentVersion = $Pro ? $PropsContent.Project.PropertyGroup.ProVersion : $PropsContent.Project.PropertyGroup.CoreVersion - -if ($null -ne $Test -and $Test -ne ""){ - $CurrentVersion = $Test -} - -$null = $CurrentVersion -match '(\d+)\.(\d+)\.(\d+)\.?(\d*)?-?(beta)?-?(\d*)?' -$MajorVersion = [int]$matches[1] -$MinorVersion = [int]$matches[2] -$PatchVersion = [int]$matches[3] -$BuildVersion = if ($matches.Count -gt 4) { [int]$matches[4] } else { 0 } -$IsBeta = if ($matches.Count -gt 5) { $null -ne $matches[5] } else { $false } -$BetaVersion = if ($matches.Count -gt 6) { [int]$matches[6] } else { 0 } -$NewVersion = "" - -if ($Publish) -{ - if ($IsBeta) - { - throw "Cannot publish a beta version. Please update the version in Directory.Build.props to a release version." - } - - ## Check the latest version on Nuget.org using web API - $NuGetUrl = $Pro ` - ? "https://azuresearch-usnc.nuget.org/query?q=dymaptic.geoblazor.pro&prerelease=false" ` - : "https://azuresearch-usnc.nuget.org/query?q=dymaptic.geoblazor.core&prerelease=false" - $Response = Invoke-RestMethod -Uri $NuGetUrl -Method Get - $LatestVersion = $null - if ($Response.data.Count -gt 0) { - # Find the highest version (should be first, but sort just in case) - $LatestVersion = ($Response.data | Sort-Object { [version]$_.version } -Descending)[0].version - } - if ($null -eq $LatestVersion) { - throw "Could not determine latest version from NuGet API." - } - $null = $LatestVersion -match '(\d+)\.(\d+)\.(\d+)\.?(\d*)?(-beta-)?(\d*)?' - $NuGetMajorVersion = [int]$matches[1] - $NuGetMinorVersion = [int]$matches[2] - $NuGetPatchVersion = [int]$matches[3] - $NuGetBuildVersion = if ($matches.Count -gt 4) { [int]$matches[4] } else { 0 } - - if ($NuGetMajorVersion -gt $MajorVersion ` - -or ($NuGetMajorVersion -eq $MajorVersion -and $NuGetMinorVersion -gt $MinorVersion) ` - -or ($NuGetMajorVersion -eq $MajorVersion -and $NuGetMinorVersion -eq $MinorVersion -and $NuGetPatchVersion -gt $PatchVersion)) - { - throw "Version in Nuget is greater than local version. Please update the version in Directory.Build.props to match the latest version on Nuget.org." - } - - if ($NuGetMajorVersion -eq $MajorVersion -and $NuGetMinorVersion -eq $MinorVersion -and $NuGetPatchVersion -eq $PatchVersion) - { - # Increment the patch version for release - $NewVersion = "$MajorVersion.$MinorVersion.$($PatchVersion + 1)" - } - else - { - # Chop off the build version, we don't need to publish that, but the version is already higher than nuget. - $NewVersion = "$MajorVersion.$MinorVersion.$PatchVersion" - } -} -else -{ - # For non-release builds, increment the build number - if ($IsBeta) - { - # Increment the beta version - $NewVersion = "$MajorVersion.$MinorVersion.$PatchVersion.$BuildVersion-beta-$($BetaVersion + 1)" - } - else - { - # Increment the build version for local tracking - $NewVersion = "$MajorVersion.$MinorVersion.$PatchVersion.$([int]$BuildVersion + 1)" - } -} - -return $NewVersion \ No newline at end of file diff --git a/esBuildClearLocks.ps1 b/esBuildClearLocks.ps1 deleted file mode 100644 index 335c11438..000000000 --- a/esBuildClearLocks.ps1 +++ /dev/null @@ -1,22 +0,0 @@ -$CoreDebugLock = Join-Path $PSScriptRoot "src/dymaptic.GeoBlazor.Core/esBuild.Debug.lock" -$CoreReleaseLock = Join-Path $PSScriptRoot "src/dymaptic.GeoBlazor.Core/esBuild.Release.lock" -$ProDebugLock = Join-Path $PSScriptRoot "../src/dymaptic.GeoBlazor.Pro/esProBuild.Debug.lock" -$ProReleaseLock = Join-Path $PSScriptRoot "../src/dymaptic.GeoBlazor.Pro/esProBuild.Release.lock" -if (Test-Path $CoreDebugLock) -{ - Remove-Item -Path $CoreDebugLock -Force -} -if (Test-Path $CoreReleaseLock) -{ - Remove-Item -Path $CoreReleaseLock -Force -} -if (Test-Path $ProDebugLock) -{ - Remove-Item -Path $ProDebugLock -Force -} -if (Test-Path $ProReleaseLock) -{ - Remove-Item -Path $ProReleaseLock -Force -} - -Write-Host "Cleared esBuild lock files" \ No newline at end of file diff --git a/esBuildWaitForCompletion.ps1 b/esBuildWaitForCompletion.ps1 deleted file mode 100644 index c7254199f..000000000 --- a/esBuildWaitForCompletion.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# PowerShell -param([string][Alias("c")]$Configuration = "Debug") - -$CoreRootDir = Join-Path -Path $PSScriptRoot "src\dymaptic.GeoBlazor.Core" -$ProRootDir = Join-Path -Path $PSScriptRoot "..\src\dymaptic.GeoBlazor.Pro" -$CoreLockFilePath = Join-Path -Path $CoreRootDir "esBuild.$Configuration.lock" -$ProLockFilePath = Join-Path -Path $ProRootDir "esBuild.$Configuration.lock" - -Write-Host "Waiting for lock files: $CoreLockFilePath, $ProLockFilePath" - -if ((Test-Path -Path $CoreLockFilePath) -or (Test-Path -Path $ProLockFilePath)) { - Write-Host "Lock file found. Waiting for release." -} else { - Write-Host "No lock file found. Exiting." - return 0 -} - -$timeout = 30 -$elapsed = 0 - -while ((Test-Path -Path $CoreLockFilePath) -or (Test-Path -Path $ProLockFilePath)) { - Start-Sleep -Seconds 1 - Write-Host -NoNewline "." - $elapsed++ - - if ($elapsed -ge $timeout) { - Write-Host "" - Write-Host "Timeout reached ($timeout seconds). Deleting lock files." - if (Test-Path -Path $CoreLockFilePath) { - Remove-Item -Path $CoreLockFilePath -Force - Write-Host "Deleted: $CoreLockFilePath" - } - if (Test-Path -Path $ProLockFilePath) { - Remove-Item -Path $ProLockFilePath -Force - Write-Host "Deleted: $ProLockFilePath" - } - break - } -} - -Write-Host "Lock file removed. Exiting." -exit 0 diff --git a/showDialog.ps1 b/showDialog.ps1 deleted file mode 100644 index 46bb0ce57..000000000 --- a/showDialog.ps1 +++ /dev/null @@ -1,879 +0,0 @@ -<# -.SYNOPSIS - Cross-platform dialog utility for displaying message boxes. - -.DESCRIPTION - Shows a message dialog using platform-appropriate methods: - - Windows: WinForms-based custom dialog - - macOS: AppleScript display alert - - Linux: zenity, kdialog, or console fallback - -.PARAMETER Message - The message text to display in the dialog. - -.PARAMETER Title - The title of the dialog window. - -.PARAMETER Buttons - The button configuration. Valid values: None, OK, OKCancel, YesNo, YesNoCancel, RetryCancel, AbortRetryIgnore - Use 'None' for a dialog that stays open until programmatically killed. - -.PARAMETER Type - The dialog type which determines the color scheme. Valid values: information, warning, error, success - -.PARAMETER DefaultButtonIndex - Zero-based index of the default button. - -.PARAMETER ListenForInput - When specified, the dialog will listen for standard input and append each line received to the message. - This allows external processes to update the dialog message dynamically while it's open. - (Windows only) - -.PARAMETER DuplicateAction - Controls behavior when a dialog with the same title already exists. Valid values: - - Allow: (Default) Always open a new dialog, even if one with the same title exists - - Skip: Do not open a new dialog if one with the same title is already open; returns $null - - BringToFront: Bring the existing dialog to the front instead of opening a new one; returns $null - (Windows only) - -.EXAMPLE - .\showDialog.ps1 -Message "Operation completed successfully" -Title "Success" -Type success - -.EXAMPLE - .\showDialog.ps1 -Message "Are you sure?" -Title "Confirm" -Buttons YesNo -Type warning - -.EXAMPLE - $result = .\showDialog.ps1 -Message "Continue?" -Title "Question" -Buttons YesNoCancel - if ($result -eq "Yes") { Write-Host "User selected Yes" } - -.EXAMPLE - # Start a persistent dialog in async mode, then kill it later - $job = Start-Job { .\showDialog.ps1 -Message "Processing..." -Title "Please Wait" -Buttons None -Type information } - # ... do work ... - Stop-Job $job; Remove-Job $job - -.EXAMPLE - # Use -ListenForInput to dynamically update the dialog message from stdin - # Pipe output to the dialog to update its message in real-time - & { Write-Output "Step 1 complete"; Start-Sleep 1; Write-Output "Step 2 complete" } | .\showDialog.ps1 -Message "Starting..." -Title "Progress" -Buttons None -ListenForInput - -.EXAMPLE - # Use -DuplicateAction to prevent opening multiple dialogs with the same title - .\showDialog.ps1 -Message "Building..." -Title "Build Status" -Buttons None -DuplicateAction Skip - -.EXAMPLE - # Use -DuplicateAction BringToFront to focus an existing dialog instead of creating a new one - .\showDialog.ps1 -Message "Building..." -Title "Build Status" -Buttons None -DuplicateAction BringToFront -#> - -param( - [Parameter(Mandatory, Position = 0)] - [string]$Message, - - [Parameter(Position = 1)] - [string]$Title = "Message", - - [Parameter(Position = 2)] - [ValidateSet('None', 'OK', 'OKCancel', 'YesNo', 'YesNoCancel', 'RetryCancel', 'AbortRetryIgnore')] - [string]$Buttons = 'OK', - - [ValidateSet('information', 'warning', 'error', 'success')] - [string]$Type = 'information', - - [ValidateSet(0, 1, 2)] - [int]$DefaultButtonIndex = -1, - - [int]$Duration = 0, - - [switch]$Async, - - [switch]$ListenForInput, - - [Parameter()] - [ValidateSet('Allow', 'Skip', 'BringToFront')] - [string]$DuplicateAction = 'Skip' -) - -$buttonMap = @{ - 'None' = @{ buttonList = @(); defaultButtonIndex = -1; cancelButtonIndex = $null } - 'OK' = @{ buttonList = @('OK'); defaultButtonIndex = 0; cancelButtonIndex = $null } - 'OKCancel' = @{ buttonList = @('OK', 'Cancel'); defaultButtonIndex = 0; cancelButtonIndex = 1 } - 'YesNo' = @{ buttonList = @('Yes', 'No'); defaultButtonIndex = 0; cancelButtonIndex = 1 } - 'YesNoCancel' = @{ buttonList = @('Yes', 'No', 'Cancel'); defaultButtonIndex = 0; cancelButtonIndex = 2 } - 'RetryCancel' = @{ buttonList = @('Retry', 'Cancel'); defaultButtonIndex = 0; cancelButtonIndex = 1 } - 'AbortRetryIgnore' = @{ buttonList = @('Abort', 'Retry', 'Ignore'); defaultButtonIndex = 2; cancelButtonIndex = 0 } -} - -function Find-ExistingDialogByTitle { - param( - [string]$Title - ) - - if ($IsLinux -or $IsMacOS) { - # Not implemented for non-Windows platforms - return $null - } - - # Windows implementation using Win32 API - Add-Type @" - using System; - using System.Collections.Generic; - using System.Runtime.InteropServices; - using System.Text; - - public class DialogFinder { - [DllImport("user32.dll")] - private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); - - [DllImport("user32.dll")] - private static extern bool IsWindowVisible(IntPtr hWnd); - - [DllImport("user32.dll", CharSet = CharSet.Auto)] - private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); - - [DllImport("user32.dll")] - private static extern int GetWindowTextLength(IntPtr hWnd); - - [DllImport("user32.dll")] - public static extern bool SetForegroundWindow(IntPtr hWnd); - - [DllImport("user32.dll")] - public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); - - [DllImport("user32.dll")] - public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); - - public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); - public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); - public const uint SWP_NOMOVE = 0x0002; - public const uint SWP_NOSIZE = 0x0001; - public const int SW_SHOW = 5; - public const int SW_RESTORE = 9; - - private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); - - public static IntPtr FindWindowByTitle(string title) { - IntPtr foundHandle = IntPtr.Zero; - EnumWindows((hWnd, lParam) => { - if (IsWindowVisible(hWnd)) { - int length = GetWindowTextLength(hWnd); - if (length > 0) { - StringBuilder sb = new StringBuilder(length + 1); - GetWindowText(hWnd, sb, sb.Capacity); - if (sb.ToString() == title) { - foundHandle = hWnd; - return false; // Stop enumeration - } - } - } - return true; - }, IntPtr.Zero); - return foundHandle; - } - - public static void BringWindowToFront(IntPtr hWnd) { - ShowWindow(hWnd, SW_RESTORE); - SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - SetForegroundWindow(hWnd); - } - } -"@ - - $existingHandle = [DialogFinder]::FindWindowByTitle($Title) - if ($existingHandle -ne [IntPtr]::Zero) { - return $existingHandle - } - return $null -} - -function Show-WindowsDialog { - param( - [string]$Message, - [string]$Title, - [string]$Type, - [string[]]$ButtonList, - [int]$DefaultIndex, - [int]$CancelIndex, - [int]$Duration, - [bool]$Async, - [bool]$ListenForInput - ) - - # Create synchronized hashtable for cross-runspace communication - $syncHash = [hashtable]::Synchronized(@{ - Message = $Message - DialogClosed = $false - Result = $null - }) - - $runspace = [runspacefactory]::CreateRunspace() - $runspace.Open() - $runspace.SessionStateProxy.SetVariable('syncHash', $syncHash) - - $PowerShell = [PowerShell]::Create().AddScript({ - param ($message, $title, $type, $buttonList, $defaultButtonIndex, $cancelButtonIndex, $duration, $syncHash) - - Add-Type -AssemblyName System.Windows.Forms - Add-Type -AssemblyName System.Drawing - - # Win32 API for forcing window to foreground - Add-Type @" - using System; - using System.Runtime.InteropServices; - public class Win32 { - [DllImport("user32.dll")] - public static extern bool SetForegroundWindow(IntPtr hWnd); - - [DllImport("user32.dll")] - public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); - - [DllImport("user32.dll")] - public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); - - [DllImport("user32.dll")] - public static extern IntPtr GetForegroundWindow(); - - [DllImport("user32.dll")] - public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId); - - [DllImport("kernel32.dll")] - public static extern uint GetCurrentThreadId(); - - [DllImport("user32.dll")] - public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); - - public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); - public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); - public const uint SWP_NOMOVE = 0x0002; - public const uint SWP_NOSIZE = 0x0001; - public const int SW_SHOW = 5; - public const int SW_RESTORE = 9; - } -"@ - - $Timer = New-Object System.Windows.Forms.Timer - $Timer.Interval = 1000 - $script:result = $null - $script:countdown = $duration - - # Color schemes based on type - $colorSchemes = @{ - "success" = @{ back = "#60A917"; fore = "#FFFFFF" } - "warning" = @{ back = "#FA6800"; fore = "#FFFFFF" } - "information" = @{ back = "#693CB2"; fore = "#FFFFFF" } - "error" = @{ back = "#CE352C"; fore = "#FFFFFF" } - } - - $colors = if ($colorSchemes.ContainsKey($type)) { $colorSchemes[$type] } else { @{ back = "#FFFFFF"; fore = "#000000" } } - $back = $colors.back - $fore = $colors.fore - - # Build Form - $form = New-Object System.Windows.Forms.Form - $form.ShowInTaskbar = $false - $form.TopMost = $true - $form.Text = $title - $form.ForeColor = [System.Drawing.ColorTranslator]::FromHtml($fore) - $form.BackColor = [System.Drawing.ColorTranslator]::FromHtml($back) - $form.ControlBox = $true - $form.MinimizeBox = $false - $form.MaximizeBox = $false - $form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle - - # Calculate dimensions - $buttonHeight = 35 - $buttonMargin = 10 - $hasButtons = $buttonList.Count -gt 0 - $totalButtonHeight = if ($hasButtons) { $buttonHeight + ($buttonMargin * 2) } else { 0 } - $formWidth = 400 - $formHeight = 480 + $totalButtonHeight - - $form.Size = New-Object System.Drawing.Size($formWidth, $formHeight) - - # Center on primary screen, with offset for other dialog instances - $monitor = [System.Windows.Forms.Screen]::PrimaryScreen - $monitorWidth = $monitor.WorkingArea.Width - $monitorHeight = $monitor.WorkingArea.Height - - # Calculate base center position - $baseCenterX = [int](($monitorWidth / 2) - ($form.Width / 2)) - $baseCenterY = [int](($monitorHeight / 2) - ($form.Height / 2)) - - # Find other PowerShell-hosted forms by checking for windows at similar positions - # Use a simple offset based on existing windows at the center position - $offset = 0 - $offsetStep = 30 - - # Get all visible top-level windows and check for overlaps - Add-Type @" - using System; - using System.Collections.Generic; - using System.Runtime.InteropServices; - using System.Text; - - public class WindowFinder { - [DllImport("user32.dll")] - private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); - - [DllImport("user32.dll")] - private static extern bool IsWindowVisible(IntPtr hWnd); - - [DllImport("user32.dll")] - private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); - - [DllImport("user32.dll", CharSet = CharSet.Auto)] - private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); - - [StructLayout(LayoutKind.Sequential)] - public struct RECT { - public int Left, Top, Right, Bottom; - } - - private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); - - public static List GetVisibleWindowRects() { - List rects = new List(); - EnumWindows((hWnd, lParam) => { - if (IsWindowVisible(hWnd)) { - RECT rect; - if (GetWindowRect(hWnd, out rect)) { - // Only include reasonably sized windows (not tiny or huge) - int width = rect.Right - rect.Left; - int height = rect.Bottom - rect.Top; - if (width > 100 && width < 800 && height > 100 && height < 800) { - rects.Add(rect); - } - } - } - return true; - }, IntPtr.Zero); - return rects; - } - } -"@ - - # Check for windows near the center position and calculate offset - $existingRects = [WindowFinder]::GetVisibleWindowRects() - $tolerance = 50 - - foreach ($rect in $existingRects) { - $windowX = $rect.Left - $windowY = $rect.Top - - # Check if this window is near our intended position (with current offset) - $targetX = $baseCenterX + $offset - $targetY = $baseCenterY + $offset - - if ([Math]::Abs($windowX - $targetX) -lt $tolerance -and [Math]::Abs($windowY - $targetY) -lt $tolerance) { - $offset += $offsetStep - } - } - - # Apply offset (cascade down and right) - $finalX = $baseCenterX + $offset - $finalY = $baseCenterY + $offset - - # Make sure we stay on screen - $finalX = [Math]::Min($finalX, $monitorWidth - $form.Width - 10) - $finalY = [Math]::Min($finalY, $monitorHeight - $form.Height - 10) - $finalX = [Math]::Max($finalX, 10) - $finalY = [Math]::Max($finalY, 10) - - $form.StartPosition = "Manual" - $form.Location = New-Object System.Drawing.Point($finalX, $finalY) - - # Add message control - use TextBox for scrolling when listening for input - $marginX = 30 - $marginY = 30 - $labelWidth = $formWidth - ($marginX * 2) - 16 # Account for form border - $labelHeight = $formHeight - ($marginY * 2) - $totalButtonHeight - 40 - - # Use a TextBox with scrolling capability - $textBox = New-Object System.Windows.Forms.TextBox - $textBox.Location = New-Object System.Drawing.Size($marginX, $marginY) - $textBox.Size = New-Object System.Drawing.Size($labelWidth, $labelHeight) - $textBox.Font = New-Object System.Drawing.Font("Segoe UI", 11, [System.Drawing.FontStyle]::Regular) - $textBox.Text = $message - $textBox.ForeColor = [System.Drawing.ColorTranslator]::FromHtml($fore) - $textBox.BackColor = [System.Drawing.ColorTranslator]::FromHtml($back) - $textBox.Multiline = $true - $textBox.ReadOnly = $true - $textBox.ScrollBars = [System.Windows.Forms.ScrollBars]::Vertical - $textBox.BorderStyle = [System.Windows.Forms.BorderStyle]::None - $textBox.TabStop = $false - $form.Controls.Add($textBox) - - # Timer to check for message updates from syncHash - $MessageTimer = New-Object System.Windows.Forms.Timer - $MessageTimer.Interval = 100 - $MessageTimer.Add_Tick({ - if ($null -ne $syncHash -and $syncHash.Message -ne $textBox.Text) { - $textBox.Text = $syncHash.Message - # Auto-scroll to the bottom - $textBox.SelectionStart = $textBox.Text.Length - $textBox.ScrollToCaret() - } - }.GetNewClosure()) - $MessageTimer.Start() - - # Handle form closing via X button - $form.Add_FormClosing({ - $MessageTimer.Stop() - $MessageTimer.Dispose() - $Timer.Stop() - $Timer.Dispose() - if ($null -ne $syncHash) { - # Set result to Cancel or first button if closed via X - $script:result = if ($null -ne $cancelButtonIndex -and $cancelButtonIndex -lt $buttonList.Count) { - $buttonList[$cancelButtonIndex] - } elseif ($buttonList.Count -gt 0) { - $buttonList[0] - } else { - $null - } - $syncHash.Result = $script:result - $syncHash.DialogClosed = $true - } - }.GetNewClosure()) - - # Create buttons (only if there are any) - if ($hasButtons) { - $buttonWidth = 90 - $buttonSpacing = 10 - $totalButtonsWidth = ($buttonList.Count * $buttonWidth) + (($buttonList.Count - 1) * $buttonSpacing) - $startX = ($formWidth - $totalButtonsWidth) / 2 - $buttonY = $formHeight - $buttonHeight - $buttonMargin - 40 - - for ($i = 0; $i -lt $buttonList.Count; $i++) { - $button = New-Object System.Windows.Forms.Button - $button.Text = $buttonList[$i] - $button.Size = New-Object System.Drawing.Size($buttonWidth, $buttonHeight) - $button.Location = New-Object System.Drawing.Point(($startX + ($i * ($buttonWidth + $buttonSpacing))), $buttonY) - $button.BackColor = [System.Drawing.ColorTranslator]::FromHtml($back) - $button.ForeColor = [System.Drawing.ColorTranslator]::FromHtml($fore) - $button.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat - $button.FlatAppearance.BorderSize = 1 - $button.FlatAppearance.BorderColor = [System.Drawing.ColorTranslator]::FromHtml($fore) - $button.Font = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Regular) - - # Set as default button if specified - if ($i -eq $defaultButtonIndex) { - $form.AcceptButton = $button - $button.FlatAppearance.BorderSize = 2 - } - - # Set as cancel button if specified - if ($null -ne $cancelButtonIndex -and $i -eq $cancelButtonIndex) { - $form.CancelButton = $button - } - - # Add click event - $button.Add_Click({ - $script:result = $this.Text - $Timer.Stop() - $Timer.Dispose() - $MessageTimer.Stop() - $MessageTimer.Dispose() - if ($null -ne $syncHash) { - $syncHash.Result = $script:result - $syncHash.DialogClosed = $true - } - $form.Close() - }.GetNewClosure()) - - $form.Controls.Add($button) - } - } - - # Timer for auto-close - $Timer.Add_Tick({ - $script:countdown-- - if ($script:countdown -lt 0) { - $script:result = if ($null -ne $cancelButtonIndex -and $cancelButtonIndex -lt $buttonList.Count) { - $buttonList[$cancelButtonIndex] - } else { - $buttonList[0] - } - $Timer.Stop() - $Timer.Dispose() - $MessageTimer.Stop() - $MessageTimer.Dispose() - if ($null -ne $syncHash) { - $syncHash.Result = $script:result - $syncHash.DialogClosed = $true - } - $form.Close() - } - }) - - if ($duration -gt 0) { - $Timer.Start() - } - - # Bring form to front when shown - use Win32 API for reliable foreground activation - $form.Add_Shown({ - $hwnd = $this.Handle - - # Get the foreground window's thread - $foregroundHwnd = [Win32]::GetForegroundWindow() - $foregroundThread = [Win32]::GetWindowThreadProcessId($foregroundHwnd, [IntPtr]::Zero) - $currentThread = [Win32]::GetCurrentThreadId() - - # Attach to the foreground thread to allow SetForegroundWindow to work - if ($foregroundThread -ne $currentThread) { - [Win32]::AttachThreadInput($currentThread, $foregroundThread, $true) | Out-Null - } - - # Set as topmost, then remove topmost (this forces it to front) - [Win32]::SetWindowPos($hwnd, [Win32]::HWND_TOPMOST, 0, 0, 0, 0, [Win32]::SWP_NOMOVE -bor [Win32]::SWP_NOSIZE) | Out-Null - [Win32]::SetWindowPos($hwnd, [Win32]::HWND_NOTOPMOST, 0, 0, 0, 0, [Win32]::SWP_NOMOVE -bor [Win32]::SWP_NOSIZE) | Out-Null - - # Show and set foreground - [Win32]::ShowWindow($hwnd, [Win32]::SW_SHOW) | Out-Null - [Win32]::SetForegroundWindow($hwnd) | Out-Null - - # Detach from the foreground thread - if ($foregroundThread -ne $currentThread) { - [Win32]::AttachThreadInput($currentThread, $foregroundThread, $false) | Out-Null - } - - # Also use .NET methods as backup - $this.Focus() - $this.Activate() - $this.BringToFront() - }) - - $form.ShowDialog() | Out-Null - - return $script:result - - }).AddArgument($Message). - AddArgument($Title). - AddArgument($Type). - AddArgument($ButtonList). - AddArgument($DefaultIndex). - AddArgument($CancelIndex). - AddArgument($Duration). - AddArgument($syncHash) - - $PowerShell.Runspace = $runspace - - if ($ListenForInput) { - # Start dialog asynchronously and return syncHash for stdin listening - $handle = $PowerShell.BeginInvoke() - return @{ - SyncHash = $syncHash - PowerShell = $PowerShell - Handle = $handle - } - } - elseif ($Async) { - $handle = $PowerShell.BeginInvoke() - - $null = Register-ObjectEvent -InputObject $PowerShell -MessageData $handle -EventName InvocationStateChanged -Action { - param([System.Management.Automation.PowerShell] $ps) - if ($ps.InvocationStateInfo.State -in 'Completed', 'Failed', 'Stopped') { - $ps.Runspace.Close() - $ps.Runspace.Dispose() - try { $ps.EndInvoke($Event.MessageData) } catch { } - $ps.Dispose() - [GC]::Collect() - } - } - - return $null - } - else { - $result = $PowerShell.Invoke() - $PowerShell.Runspace.Close() - $PowerShell.Runspace.Dispose() - $PowerShell.Dispose() - return $result - } -} - -function Show-MacOSDialog { - param( - [string]$Message, - [string]$Title, - [string]$Type, - [string[]]$ButtonList, - [int]$DefaultIndex, - [int]$CancelIndex - ) - - # No buttons - use notification that stays until dismissed (or just display with minimal interaction) - if ($ButtonList.Count -eq 0) { - # Use osascript to display a notification - these persist until cleared - $escapedMessage = $Message -replace '"', '\"' - $escapedTitle = $Title -replace '"', '\"' - $appleScript = "display notification `"$escapedMessage`" with title `"$escapedTitle`"" - $appleScript | osascript 2>$null - # Block indefinitely - caller must kill the process - while ($true) { Start-Sleep -Seconds 60 } - return $null - } - - # Map type to AppleScript icon type - $iconClause = switch ($Type) { - 'error' { 'as critical' } - 'warning' { 'as warning' } - default { '' } # AppleScript doesn't have success/info differentiation - } - - # Build button list for AppleScript - $buttonClause = "buttons { $($ButtonList -replace '^', '"' -replace '$', '"' -join ', ') }" - $defaultButtonClause = "default button $(1 + $DefaultIndex)" - - $cancelButtonClause = "" - if ($null -ne $CancelIndex -and $CancelIndex -ne $DefaultIndex) { - $cancelButtonClause = "cancel button $(1 + $CancelIndex)" - } - - # Escape quotes in message and title - $escapedMessage = $Message -replace '"', '\"' - $escapedTitle = $Title -replace '"', '\"' - - $appleScript = "display alert `"$escapedTitle`" message `"$escapedMessage`" $iconClause $buttonClause $defaultButtonClause $cancelButtonClause" - - # Execute AppleScript - $result = $appleScript | osascript 2>$null - - # Parse result - AppleScript returns "button:" or empty on cancel - if (-not $result) { - if ($null -ne $CancelIndex) { - return $ButtonList[$CancelIndex] - } - return $ButtonList[0] - } - - return ($result -replace '.+:') -} - -function Show-LinuxDialog { - param( - [string]$Message, - [string]$Title, - [string]$Type, - [string[]]$ButtonList, - [int]$DefaultIndex, - [int]$CancelIndex - ) - - # No buttons - display message and block indefinitely - if ($ButtonList.Count -eq 0) { - $color = switch ($Type) { - 'error' { 'Red' } - 'warning' { 'Yellow' } - 'success' { 'Green' } - default { 'Cyan' } - } - Write-Host "" - Write-Host "=== $Title ===" -ForegroundColor $color - Write-Host $Message - Write-Host "(Press Ctrl+C to dismiss)" - Write-Host "" - # Block indefinitely - caller must kill the process - while ($true) { Start-Sleep -Seconds 60 } - return $null - } - - # Map type to zenity/kdialog icon - $zenityType = switch ($Type) { - 'error' { '--error' } - 'warning' { '--warning' } - 'information' { '--info' } - 'success' { '--info' } - default { '--info' } - } - - # Try zenity first (GTK) - $zenityPath = Get-Command zenity -ErrorAction SilentlyContinue - if ($zenityPath) { - if ($ButtonList.Count -eq 1) { - # Simple message with OK - zenity $zenityType --title="$Title" --text="$Message" 2>$null - return $ButtonList[0] - } - else { - # Question dialog for multi-button - $zenityResult = zenity --question --title="$Title" --text="$Message" 2>$null - if ($LASTEXITCODE -eq 0) { - return $ButtonList[0] # "Yes" or first button - } - else { - return $ButtonList[1] # "No" or second button - } - } - } - - # Try kdialog (KDE) - $kdialogPath = Get-Command kdialog -ErrorAction SilentlyContinue - if ($kdialogPath) { - $kdType = switch ($Type) { - 'error' { '--error' } - 'warning' { '--sorry' } - default { '--msgbox' } - } - - if ($ButtonList.Count -eq 1) { - kdialog $kdType "$Message" --title "$Title" 2>$null - return $ButtonList[0] - } - else { - $kdResult = kdialog --yesno "$Message" --title "$Title" 2>$null - if ($LASTEXITCODE -eq 0) { - return $ButtonList[0] - } - else { - return $ButtonList[1] - } - } - } - - # Fallback to console - Write-Host "" - Write-Host "=== $Title ===" -ForegroundColor $(switch ($Type) { - 'error' { 'Red' } - 'warning' { 'Yellow' } - 'success' { 'Green' } - default { 'Cyan' } - }) - Write-Host $Message - Write-Host "" - - if ($ButtonList.Count -eq 1) { - Read-Host "Press Enter to continue" - return $ButtonList[0] - } - - # Show options for multi-button - for ($i = 0; $i -lt $ButtonList.Count; $i++) { - $prefix = if ($i -eq $DefaultIndex) { "*" } else { " " } - Write-Host "$prefix[$($i + 1)] $($ButtonList[$i])" - } - - $defaultDisplay = $DefaultIndex + 1 - $choice = Read-Host "Enter choice (1-$($ButtonList.Count)) [default: $defaultDisplay]" - - if ([string]::IsNullOrWhiteSpace($choice)) { - return $ButtonList[$DefaultIndex] - } - - $choiceNum = 0 - if ([int]::TryParse($choice, [ref]$choiceNum) -and $choiceNum -ge 1 -and $choiceNum -le $ButtonList.Count) { - return $ButtonList[$choiceNum - 1] - } - - return $ButtonList[$DefaultIndex] -} - -# Main execution -# Allow $IsLinux and $IsMacOS to be accessed safely in Windows PowerShell -Set-StrictMode -Off - -$config = $buttonMap[$Buttons] -$buttonList = $config.buttonList -$defaultIndex = if ($DefaultButtonIndex -ge 0) { $DefaultButtonIndex } else { $config.defaultButtonIndex } -$cancelIndex = $config.cancelButtonIndex - -# Ensure default index is within bounds -$defaultIndex = [math]::Min($buttonList.Count - 1, $defaultIndex) - -# Check for duplicate dialogs (Windows only for now) -if ($DuplicateAction -ne 'Allow' -and -not $IsLinux -and -not $IsMacOS) { - $existingHandle = Find-ExistingDialogByTitle -Title $Title - if ($null -ne $existingHandle) { - if ($DuplicateAction -eq 'Skip') { - # Return without showing - dialog already exists - Write-Output "Skipping duplicate dialog titled $Title" - return $null - } - elseif ($DuplicateAction -eq 'BringToFront') { - # Bring existing dialog to front and return - [DialogFinder]::BringWindowToFront($existingHandle) - return $null - } - } -} - -if ($IsLinux) { - $result = Show-LinuxDialog -Message $Message -Title $Title -Type $Type -ButtonList $buttonList -DefaultIndex $defaultIndex -CancelIndex $cancelIndex -} -elseif ($IsMacOS) { - $result = Show-MacOSDialog -Message $Message -Title $Title -Type $Type -ButtonList $buttonList -DefaultIndex $defaultIndex -CancelIndex $cancelIndex -} -else { - # Windows - if ($ListenForInput) { - # Start dialog and listen for stdin input to append to message - $dialogInfo = Show-WindowsDialog -Message $Message -Title $Title -Type $Type -ButtonList $buttonList -DefaultIndex $defaultIndex -CancelIndex $cancelIndex -Duration $Duration -Async $false -ListenForInput $true - - $syncHash = $dialogInfo.SyncHash - $ps = $dialogInfo.PowerShell - $handle = $dialogInfo.Handle - - try { - # Read from stdin and append to message until dialog closes or EOF - # Use a background runspace to read stdin without blocking the main thread - $stdinRunspace = [runspacefactory]::CreateRunspace() - $stdinRunspace.Open() - $stdinRunspace.SessionStateProxy.SetVariable('syncHash', $syncHash) - - $stdinPS = [PowerShell]::Create().AddScript({ - param($syncHash) - $stdinStream = [System.Console]::OpenStandardInput() - $reader = New-Object System.IO.StreamReader($stdinStream) - - try { - while (-not $syncHash.DialogClosed) { - $line = $reader.ReadLine() - if ($null -eq $line) { - # EOF reached - break - } - # Append line to message (use CRLF for Windows TextBox) - $syncHash.Message = $syncHash.Message + "`r`n" + $line - } - } - finally { - $reader.Dispose() - $stdinStream.Dispose() - } - }).AddArgument($syncHash) - - $stdinPS.Runspace = $stdinRunspace - $stdinHandle = $stdinPS.BeginInvoke() - - # Wait for dialog to close - while (-not $syncHash.DialogClosed) { - Start-Sleep -Milliseconds 100 - } - - # Clean up stdin reader - if (-not $stdinHandle.IsCompleted) { - $stdinPS.Stop() - } - $stdinRunspace.Close() - $stdinRunspace.Dispose() - $stdinPS.Dispose() - } - finally { - # Wait for dialog to complete if still running - if (-not $handle.IsCompleted) { - $null = $ps.EndInvoke($handle) - } - $ps.Runspace.Close() - $ps.Runspace.Dispose() - $ps.Dispose() - } - - $result = $syncHash.Result - } - else { - $result = Show-WindowsDialog -Message $Message -Title $Title -Type $Type -ButtonList $buttonList -DefaultIndex $defaultIndex -CancelIndex $cancelIndex -Duration $Duration -Async $Async -ListenForInput $false - } -} - -return $result diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProcessHelper.cs b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProcessHelper.cs index e4baee42e..5b03afc2f 100644 --- a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProcessHelper.cs +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProcessHelper.cs @@ -1,6 +1,7 @@ using CliWrap; using CliWrap.EventStream; using Microsoft.CodeAnalysis; +using System.Collections.Concurrent; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -22,10 +23,10 @@ public static class ProcessHelper /// The name of the PowerShell script file to execute. /// Command-line arguments to pass to the script. /// A StringBuilder to accumulate log output. - /// A cancellation token to cancel the operation. + /// The SourceProductionContext for diagnostic reporting. /// Optional environment variables to set for the process. public static async Task RunPowerShellScript(string processName, string workingDirectory, - string powershellScriptName, string[] arguments, StringBuilder logBuilder, CancellationToken token, + string powershellScriptName, string[] arguments, StringBuilder logBuilder, SourceProductionContext context, Dictionary? environmentVariables = null) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -49,7 +50,7 @@ public static async Task RunPowerShellScript(string processName, string workingD ]; } - await Execute(processName, workingDirectory, "pwsh", arguments, logBuilder, token, + await Execute(processName, workingDirectory, "pwsh", arguments, logBuilder, context, environmentVariables); } @@ -60,10 +61,10 @@ await Execute(processName, workingDirectory, "pwsh", arguments, logBuilder, toke /// The working directory for the command execution. /// The PowerShell command to execute. /// A StringBuilder to accumulate log output. - /// A cancellation token to cancel the operation. + /// The SourceProductionContext for diagnostic reporting. /// Optional environment variables to set for the process. public static async Task RunPowerShellCommand(string processName, string workingDirectory, - string[] arguments, StringBuilder logBuilder, CancellationToken token, + string[] arguments, StringBuilder logBuilder, SourceProductionContext context, Dictionary? environmentVariables = null) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -80,7 +81,7 @@ public static async Task RunPowerShellCommand(string processName, string working ]; } - await Execute(processName, workingDirectory, "pwsh", arguments, logBuilder, token, + await Execute(processName, workingDirectory, "pwsh", arguments, logBuilder, context, environmentVariables); } @@ -92,11 +93,11 @@ await Execute(processName, workingDirectory, "pwsh", arguments, logBuilder, toke /// The executable file name. If null, uses the platform-specific shell command. /// Command-line arguments to pass to the process. /// A StringBuilder to accumulate log output. - /// A cancellation token to cancel the operation. + /// The SourceProductionContext for diagnostic reporting. /// Optional environment variables to set for the process. /// Thrown when the process exits with a non-zero exit code. public static async Task Execute(string processName, string workingDirectory, string? fileName, - string[] shellArguments, StringBuilder logBuilder, CancellationToken token, + string[] shellArguments, StringBuilder logBuilder, SourceProductionContext context, Dictionary? environmentVariables = null) { fileName ??= shellCommand; @@ -105,7 +106,7 @@ public static async Task Execute(string processName, string workingDirectory, st int? processId = null; int? exitCode = null; - token.Register(() => + context.CancellationToken.Register(() => { logBuilder.AppendLine($"{processName}: Command execution cancelled."); logBuilder.AppendLine(outputBuilder.ToString()); @@ -118,7 +119,7 @@ public static async Task Execute(string processName, string workingDirectory, st .WithValidation(CommandResultValidation.None) .WithEnvironmentVariables(environmentVariables ?? new Dictionary()); - await foreach (CommandEvent cmdEvent in cmd.ListenAsync(cancellationToken: token)) + await foreach (var cmdEvent in cmd.ListenAsync(context.CancellationToken)) { switch (cmdEvent) { @@ -157,9 +158,43 @@ public static async Task Execute(string processName, string workingDirectory, st if (exitCode != 0) { - throw new ProcessException($"{processName}: Error executing command '{string.Join(" ", shellArguments) - }' for process { - processId}. Exit code: {exitCode}"); + var response = logBuilder.ToString(); + Log(processName, response, DiagnosticSeverity.Info, context); + + if (response.Contains("The process cannot access the file") && (fileName == "dotnet")) + { + var programName = shellArguments[1]; // dotnet[fileName] run[arg[0]] ESBuild.cs[arg[1]] + + var runningProc = Process.GetProcessesByName("dotnet") + .FirstOrDefault(p => p.MainModule?.FileName.Contains(programName) ?? false); + + if (runningProc is not null) + { + try + { + runningProc.Kill(); + runningProc.WaitForExit(); + } + catch + { + // ignore + } + } + + await Task.Delay(500); + + await Execute(processName, workingDirectory, fileName, shellArguments, logBuilder, context, + environmentVariables); + + return; + } + + Log(processName, + $"Command '{fileName} {string.Join(" ", shellArguments)}' failed with exit code {exitCode}.", + DiagnosticSeverity.Error, + context); + + return; } // Return the standard output if the process completed normally @@ -176,12 +211,13 @@ public static async Task Execute(string processName, string workingDirectory, st /// The severity level of the diagnostic. /// The source production context to report the diagnostic to. /// Whether to show a popup console window with the message + /// Optional session ID to identify the console dialog instance. Each unique session ID gets its own dialog window. public static void Log(string title, string message, DiagnosticSeverity severity, - SourceProductionContext context, bool showConsole = false) + SourceProductionContext context, bool showConsole = false, string? sessionId = null) { if (showConsole) { - ShowOrUpdateConsole(title, message); + ShowOrUpdateConsole(title, message, sessionId); } context.ReportDiagnostic(Diagnostic.Create(new DiagnosticDescriptor("GBSourceGen", @@ -193,65 +229,154 @@ public static void Log(string title, string message, DiagnosticSeverity severity } ///

- /// Closes any open console window created by . + /// Closes the console window for the specified session. /// - public static void CloseDialog() + /// The session ID of the console dialog to close. + public static void CloseDialog(string sessionId) { _ = Task.Run(() => { - if (_consoleProcess is null) + if (!_consoleProcesses.TryRemove(sessionId, out var process)) { return; } - _consoleProcess.StandardInput.Flush(); - Thread.Sleep(500); - _consoleProcess.StandardInput.WriteLine("exit"); - _consoleProcess.WaitForExit(); - _consoleProcess.Dispose(); + if (HasProcessExited(process)) + { + return; + } + + try + { + process.StandardInput.Flush(); + Thread.Sleep(500); + process.StandardInput.WriteLine("exit"); + process.WaitForExit(); + process.Dispose(); + } + catch (InvalidOperationException) + { + // Process was not started or has already exited - ignore + } }); } - private static void ShowOrUpdateConsole(string title, string message, + /// + /// Closes all open console windows created by . + /// + public static void CloseAllDialogs() + { + foreach (var sessionId in _consoleProcesses.Keys.ToArray()) + { + CloseDialog(sessionId); + } + } + + private static void ShowOrUpdateConsole(string title, string message, string? sessionId = null, [CallerFilePath] string callerFilePath = "") { - if (_consoleProcess is null) + // Use session ID if provided, otherwise use title as the key + var key = sessionId ?? title; + + try { - string buildScriptPath = Path.GetFullPath(Path.Combine( - Path.GetDirectoryName(callerFilePath)!, // GeoBlazor/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared - "..", // GeoBlazor/src - "..", // GeoBlazor Core repo root - "build")); + // Try to get existing process for this session + if (_consoleProcesses.TryGetValue(key, out var existingProcess) && !HasProcessExited(existingProcess)) + { + existingProcess.StandardInput.WriteLine(message); - string[] args = - [ - "ConsoleDialog.cs", - title - ]; + return; + } - ProcessStartInfo startInfo = new("dotnet") + // Need to create a new process - use lock to prevent race conditions + lock (_consoleLock) { - Arguments = string.Join(" ", args), - WorkingDirectory = buildScriptPath, - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - RedirectStandardInput = true, - CreateNoWindow = true, - }; - - _consoleProcess = Process.Start(startInfo); - _consoleProcess!.StandardInput.AutoFlush = true; + // Double-check after acquiring lock + if (_consoleProcesses.TryGetValue(key, out existingProcess) && !HasProcessExited(existingProcess)) + { + existingProcess.StandardInput.WriteLine(message); + + return; + } + + // Remove stale process if it exists + if (existingProcess is not null) + { + _consoleProcesses.TryRemove(key, out _); + + try + { + existingProcess.Dispose(); + } + catch + { + // ignore disposal errors + } + } + + var buildScriptPath = Path.GetFullPath(Path.Combine( + Path.GetDirectoryName( + callerFilePath)!, // GeoBlazor/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared + "..", // GeoBlazor/src + "..", // GeoBlazor Core repo root + "build-tools")); + + string[] args = + [ + "ConsoleDialog.dll", + $"\"{title}\"", + "-w", + "2" + ]; + + ProcessStartInfo startInfo = new("dotnet") + { + Arguments = string.Join(" ", args), + WorkingDirectory = buildScriptPath, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + RedirectStandardInput = true, + CreateNoWindow = true + }; + + var newProcess = Process.Start(startInfo); + + if (newProcess is null) + { + return; // Failed to start process + } + + newProcess.StandardInput.AutoFlush = true; + _consoleProcesses[key] = newProcess; + newProcess.StandardInput.WriteLine(message); + } } + catch (InvalidOperationException) + { + // Process failed to start or is in invalid state - remove from dictionary + _consoleProcesses.TryRemove(key, out _); + } + } - _consoleProcess.StandardInput.WriteLine(message); + private static bool HasProcessExited(Process process) + { + try + { + return process.HasExited; + } + catch (InvalidOperationException) + { + return true; // Process was never started or is in invalid state + } } private static readonly string shellCommand = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? WindowsShell : LinuxShell; - private static Process? _consoleProcess; + private static readonly ConcurrentDictionary _consoleProcesses = new(); + private static readonly object _consoleLock = new(); private const string LinuxShell = "/bin/bash"; private const string WindowsShell = "cmd"; diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProtobufDefinitionsGenerator.cs b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProtobufDefinitionsGenerator.cs index dafe87316..76b3318dd 100644 --- a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProtobufDefinitionsGenerator.cs +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/ProtobufDefinitionsGenerator.cs @@ -13,15 +13,15 @@ namespace dymaptic.GeoBlazor.Core.SourceGenerator.Shared; public static class ProtobufDefinitionsGenerator { public static Dictionary UpdateProtobufDefinitions(SourceProductionContext context, - ImmutableArray types, string corePath) + ImmutableArray types, string corePath, bool showDialog, string? sessionId = null) { ProcessHelper.Log(nameof(ProtobufDefinitionsGenerator), "Updating Protobuf definitions...", DiagnosticSeverity.Info, - context, true); + context, showDialog, sessionId); // fetch protobuf definitions - var protoTypeContent = Generate(context, types); + var protoTypeContent = Generate(context, types, showDialog, sessionId); var typescriptContent = $""" export let protoTypeDefinitions: string = ` @@ -45,25 +45,26 @@ public static Dictionary UpdateProtobufDefinitio ProcessHelper.RunPowerShellScript("Copy Protobuf Definitions", corePath, scriptPath, ["-Content", encoded], - logBuilder, context.CancellationToken) + logBuilder, context) .GetAwaiter() .GetResult(); ProcessHelper.Log(nameof(ProtobufDefinitionsGenerator), logBuilder.ToString(), DiagnosticSeverity.Info, - context); + context, sessionId: sessionId); ProcessHelper.Log(nameof(ProtobufDefinitionsGenerator), "Protobuf definitions updated successfully.", DiagnosticSeverity.Info, - context, true); + context, showDialog, sessionId); return _protoDefinitions ?? []; } public static Dictionary ExtractProtobufDefinitions( - ImmutableArray types, SourceProductionContext context) + ImmutableArray types, SourceProductionContext context, bool showDialog, + string? sessionId = null) { var definitions = new Dictionary(); const string protoContractAttribute = "ProtoContract"; @@ -84,7 +85,7 @@ public static Dictionary ExtractProtobufDefiniti type.AttributeLists.SelectMany(al => al.Attributes.SelectMany(a => a.ToString()))) }", DiagnosticSeverity.Warning, - context, true); + context, showDialog, sessionId); } continue; @@ -104,7 +105,7 @@ public static Dictionary ExtractProtobufDefiniti ProcessHelper.Log(nameof(ProtobufDefinitionsGenerator), $"Error processing syntax node {type.Identifier.Text}: {ex.Message}", DiagnosticSeverity.Warning, - context, true); + context, showDialog, sessionId); } } @@ -112,22 +113,22 @@ public static Dictionary ExtractProtobufDefiniti } private static string Generate(SourceProductionContext context, - ImmutableArray types) + ImmutableArray types, bool showDialog, string? sessionId = null) { try { ProcessHelper.Log(nameof(ProtobufDefinitionsGenerator), "Generating Protobuf schema", DiagnosticSeverity.Info, - context, true); + context, showDialog, sessionId); // Extract protobuf definitions from syntax nodes - _protoDefinitions ??= ExtractProtobufDefinitions(types, context); + _protoDefinitions ??= ExtractProtobufDefinitions(types, context, showDialog, sessionId); ProcessHelper.Log(nameof(ProtobufDefinitionsGenerator), $"Extracted {_protoDefinitions.Count} Protobuf message definitions.", DiagnosticSeverity.Info, - context, true); + context, showDialog, sessionId); // Generate new proto file content var newProtoContent = GenerateProtoFileContent(_protoDefinitions); @@ -135,7 +136,7 @@ private static string Generate(SourceProductionContext context, ProcessHelper.Log(nameof(ProtobufDefinitionsGenerator), "Protobuf schema generation complete", DiagnosticSeverity.Info, - context, true); + context, showDialog, sessionId); return newProtoContent; } @@ -144,7 +145,7 @@ private static string Generate(SourceProductionContext context, ProcessHelper.Log(nameof(ProtobufDefinitionsGenerator), $"Error generating Protobuf definitions: {ex.Message}", DiagnosticSeverity.Error, - context, true); + context, showDialog, sessionId); return string.Empty; } diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/SerializationGenerator.cs b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/SerializationGenerator.cs index 1d2711f92..27d92c4d0 100644 --- a/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/SerializationGenerator.cs +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator.Shared/SerializationGenerator.cs @@ -18,10 +18,12 @@ public static class SerializationGenerator /// The collection of type declarations to analyze for serialization attributes. /// A dictionary of Protobuf message definitions keyed by type name. /// Whether generating for Pro (true) or Core (false) library. + /// Whether to show progress dialog during generation. + /// Optional session ID to identify the console dialog instance. public static void GenerateSerializationDataClass(SourceProductionContext context, ImmutableArray types, Dictionary protoMessageDefinitions, - bool isPro) + bool isPro, bool showDialog, string? sessionId = null) { try { @@ -100,7 +102,7 @@ internal static partial class {{className}} ProcessHelper.Log(nameof(SerializationGenerator), $"Generated serialized data class: {className}.g.cs", DiagnosticSeverity.Info, - context, true); + context, showDialog, sessionId); context.AddSource($"{className}.g.cs", classBuilder.ToString()); } @@ -109,7 +111,7 @@ internal static partial class {{className}} ProcessHelper.Log(nameof(SerializationGenerator), $"Error generating serialized data class: {ex}", DiagnosticSeverity.Error, - context, true); + context, showDialog, sessionId); } } diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator/ESBuildGenerator.cs b/src/dymaptic.GeoBlazor.Core.SourceGenerator/ESBuildGenerator.cs index 39147f21f..ea8489806 100644 --- a/src/dymaptic.GeoBlazor.Core.SourceGenerator/ESBuildGenerator.cs +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator/ESBuildGenerator.cs @@ -14,9 +14,9 @@ namespace dymaptic.GeoBlazor.Core.SourceGenerator; [SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1035:Do not use APIs banned for analyzers")] public class ESBuildGenerator : IIncrementalGenerator { - private static string? BuildScriptsPath => _corePath is null + private static string? BuildToolsPath => _corePath is null ? null - : Path.GetFullPath(Path.Combine(_corePath, "..", "..", "build")); + : Path.GetFullPath(Path.Combine(_corePath, "..", "..", "build-tools")); /// public void Initialize(IncrementalGeneratorInitializationContext context) @@ -29,7 +29,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) .Collect(); // Reads the MSBuild properties to get the project directory and configuration. - IncrementalValueProvider<(string?, string?, string?)> optionsProvider = + IncrementalValueProvider<(string?, string?, string?, string?)> optionsProvider = context.AnalyzerConfigOptionsProvider.Select((configProvider, _) => { configProvider.GlobalOptions.TryGetValue("build_property.CoreProjectPath", @@ -41,18 +41,23 @@ public void Initialize(IncrementalGeneratorInitializationContext context) configProvider.GlobalOptions.TryGetValue("build_property.PipelineBuild", out string? pipelineBuild); - return (projectDirectory, configuration, pipelineBuild); + configProvider.GlobalOptions.TryGetValue("build_property.DesignTimeBuild", + out var designTimeBuild); + + return (projectDirectory, configuration, pipelineBuild, designTimeBuild); }); - IncrementalValueProvider<(ImmutableArray Left, (string?, string?, string?) Right)> combined = - tsFilesProvider.Combine(optionsProvider); + var + combined = + tsFilesProvider.Combine(optionsProvider); context.RegisterSourceOutput(combined, FilesChanged); } private void FilesChanged(SourceProductionContext context, (ImmutableArray Files, - (string? ProjectDirectory, string? Configuration, string? PipelineBuild) Options) pipeline) + (string? ProjectDirectory, string? Configuration, string? PipelineBuild, string? DesignTimeBuild) Options) + pipeline) { if (!SetProjectDirectoryAndConfiguration(pipeline.Options, context)) { @@ -71,9 +76,7 @@ private void FilesChanged(SourceProductionContext context, ProcessHelper.Log(nameof(ESBuildGenerator), "Skipping ESBuild process as PipelineBuild is set to true.", DiagnosticSeverity.Info, - context, true); - - ProcessHelper.CloseDialog(); + context); return; } @@ -85,7 +88,7 @@ private void FilesChanged(SourceProductionContext context, } private bool SetProjectDirectoryAndConfiguration( - (string? ProjectDirectory, string? Configuration, string? _) options, + (string? ProjectDirectory, string? Configuration, string? _, string? DesignTimeBuild) options, SourceProductionContext context) { string? projectDirectory = options.ProjectDirectory; @@ -127,6 +130,7 @@ private bool SetProjectDirectoryAndConfiguration( if (options.Configuration is { } configuration) { _configuration = configuration; + _isDesignTimeBuild = options.DesignTimeBuild == "true"; return true; } @@ -159,18 +163,24 @@ private void LaunchESBuild(SourceProductionContext context) bool proBuildSuccess = false; // gets the ESBuild.cs script + // Only show dialog on full compilation builds, not design-time builds + string[] coreArgs = + [ + "ESBuild.dll", + "-c", _configuration!, // set config for ESBuild + "-d" // show dialog + ]; + + if (!_isDesignTimeBuild) + { + coreArgs = [..coreArgs, "-v"]; // show verbose output + } + tasks.Add(Task.Run(async () => { await ProcessHelper.Execute("Core", - BuildScriptsPath!, "dotnet", - [ - "run", - "ESBuild.cs", - "-c", _configuration!, // pass config to MSBuild - "--", - "-c", _configuration!, // set config for ESBuild - "-d" // show dialog - ], logBuilder, context.CancellationToken); + BuildToolsPath!, "dotnet", + coreArgs, logBuilder, context); buildSuccess = true; })); @@ -178,19 +188,24 @@ await ProcessHelper.Execute("Core", { logBuilder.AppendLine("Starting Pro ESBuild process..."); + string[] proArgs = + [ + "ESBuild.dll", + "-c", _configuration!, // set config for ESBuild + "-d", // show dialog + "--pro" // build for Pro project + ]; + + if (!_isDesignTimeBuild) + { + proArgs = [..proArgs, "-v"]; // show verbose output + } + tasks.Add(Task.Run(async () => { await ProcessHelper.Execute("Pro", - BuildScriptsPath!, "dotnet", - [ - "run", - "ESBuild.cs", - "-c", _configuration!, // pass config to MSBuild - "--", - "-c", _configuration!, // set config for ESBuild - "-d", // show dialog - "--pro" // build for Pro project - ], logBuilder, context.CancellationToken); + BuildToolsPath!, "dotnet", + proArgs, logBuilder, context); proBuildSuccess = true; })); } @@ -245,11 +260,11 @@ await ProcessHelper.Execute("Pro", private void ClearESBuildLocks(SourceProductionContext context) { StringBuilder logBuilder = new(); - string rootCorePath = Path.Combine(_corePath!, "..", ".."); - _ = Task.Run(async () => await ProcessHelper.RunPowerShellScript("Clear Locks", - rootCorePath, "esBuildClearLocks.ps1", [], - logBuilder, context.CancellationToken)); + _ = Task.Run(async () => await ProcessHelper.Execute("Clear Locks", + BuildToolsPath!, "dotnet", + ["ESBuildClearLocks.dll"], + logBuilder, context)); ProcessHelper.Log(nameof(ESBuildGenerator), "Cleared ESBuild Process Locks", @@ -260,4 +275,5 @@ private void ClearESBuildLocks(SourceProductionContext context) private static string? _corePath; private static string? _proPath; private static string? _configuration; + private static bool _isDesignTimeBuild; } \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core.SourceGenerator/ProtobufSourceGenerator.cs b/src/dymaptic.GeoBlazor.Core.SourceGenerator/ProtobufSourceGenerator.cs index 8f3b9888e..c1c6e068c 100644 --- a/src/dymaptic.GeoBlazor.Core.SourceGenerator/ProtobufSourceGenerator.cs +++ b/src/dymaptic.GeoBlazor.Core.SourceGenerator/ProtobufSourceGenerator.cs @@ -32,43 +32,70 @@ syntaxNode is ClassDeclarationSyntax or StructDeclarationSyntax or RecordDeclara .Collect(); // Reads the MSBuild properties to get the project directory. - IncrementalValueProvider optionsProvider = + IncrementalValueProvider<(string?, string?)> optionsProvider = context.AnalyzerConfigOptionsProvider.Select((configProvider, _) => { configProvider.GlobalOptions.TryGetValue("build_property.CoreProjectPath", out var projectDirectory); - return projectDirectory; + configProvider.GlobalOptions.TryGetValue("build_property.PipelineBuild", + out var pipelineBuild); + + return (projectDirectory, pipelineBuild); }); - IncrementalValueProvider<(ImmutableArray Left, string? Right)> combined = + IncrementalValueProvider<(ImmutableArray Left, (string?, string?) Right)> combined = typeProvider.Combine(optionsProvider); context.RegisterSourceOutput(combined, FilesChanged); } private void FilesChanged(SourceProductionContext context, - (ImmutableArray Types, string? ProjectDirectory) pipeline) + (ImmutableArray Types, (string? ProjectDirectory, string? PipelineBuild) Options) + pipeline) { - _corePath = pipeline.ProjectDirectory; + _corePath = pipeline.Options.ProjectDirectory; + var showDialog = pipeline.Options.PipelineBuild != "true"; + + // Generate a unique session ID for this build session + var sessionId = $"{nameof(ProtobufSourceGenerator)}_{Guid.NewGuid():N}"; if (pipeline.Types.Length > 0) { - ProcessHelper.Log(nameof(ProtobufSourceGenerator), - $"Source Generation triggered with {pipeline.Types.Length} protobuf types found.", - DiagnosticSeverity.Info, - context, true); + try + { + ProcessHelper.Log(nameof(ProtobufSourceGenerator), + $"Source Generation triggered with {pipeline.Types.Length} protobuf types found.", + DiagnosticSeverity.Info, + context, showDialog, sessionId); - var protoDefinitions = ProtobufDefinitionsGenerator - .UpdateProtobufDefinitions(context, pipeline.Types, _corePath!); + var protoDefinitions = ProtobufDefinitionsGenerator + .UpdateProtobufDefinitions(context, pipeline.Types, _corePath!, showDialog, sessionId); - context.CancellationToken.ThrowIfCancellationRequested(); + context.CancellationToken.ThrowIfCancellationRequested(); - SerializationGenerator.GenerateSerializationDataClass(context, - pipeline.Types, protoDefinitions, false); + SerializationGenerator.GenerateSerializationDataClass(context, + pipeline.Types, protoDefinitions, false, showDialog, sessionId); + + context.CancellationToken.ThrowIfCancellationRequested(); + + if (showDialog) + { + ProcessHelper.CloseDialog(sessionId); + } + } + catch (Exception ex) + { + ProcessHelper.Log(nameof(ProtobufSourceGenerator), + $"Error generating serialization data class: {ex.Message}\n{ex.StackTrace}", + DiagnosticSeverity.Error, + context, showDialog, sessionId); - context.CancellationToken.ThrowIfCancellationRequested(); - ProcessHelper.CloseDialog(); + if (showDialog) + { + ProcessHelper.CloseDialog(sessionId); + } + } } } diff --git a/src/dymaptic.GeoBlazor.Core/badge_fullmethodcoverage.svg b/src/dymaptic.GeoBlazor.Core/badge_fullmethodcoverage.svg index f55c3455b..e0166c286 100644 --- a/src/dymaptic.GeoBlazor.Core/badge_fullmethodcoverage.svg +++ b/src/dymaptic.GeoBlazor.Core/badge_fullmethodcoverage.svg @@ -137,8 +137,8 @@ Coverage - 0.2% - 0.2% + 3% + 3% diff --git a/src/dymaptic.GeoBlazor.Core/badge_linecoverage.svg b/src/dymaptic.GeoBlazor.Core/badge_linecoverage.svg index 5de7e46cc..071b90fed 100644 --- a/src/dymaptic.GeoBlazor.Core/badge_linecoverage.svg +++ b/src/dymaptic.GeoBlazor.Core/badge_linecoverage.svg @@ -128,8 +128,8 @@ Coverage Coverage - 0.2% - 0.2% + 1.3% + 1.3% diff --git a/src/dymaptic.GeoBlazor.Core/badge_methodcoverage.svg b/src/dymaptic.GeoBlazor.Core/badge_methodcoverage.svg index 537db244b..5f0a2bfad 100644 --- a/src/dymaptic.GeoBlazor.Core/badge_methodcoverage.svg +++ b/src/dymaptic.GeoBlazor.Core/badge_methodcoverage.svg @@ -132,8 +132,8 @@ Coverage - 0.2% - 0.2% + 3.2% + 3.2% diff --git a/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj b/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj index d073d3cd8..8e0b40e6e 100644 --- a/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj +++ b/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj @@ -125,6 +125,6 @@ - + diff --git a/src/dymaptic.GeoBlazor.Core/esBuild.ps1 b/src/dymaptic.GeoBlazor.Core/esBuild.ps1 deleted file mode 100644 index 557a13ea9..000000000 --- a/src/dymaptic.GeoBlazor.Core/esBuild.ps1 +++ /dev/null @@ -1,311 +0,0 @@ -param([string][Alias("c")]$Configuration = "Debug", - [switch][Alias("f")]$Force, - [switch][Alias("h")]$Help) - -# Allow $IsLinux and $IsMacOS to be accessed safely in Windows PowerShell -Set-StrictMode -Off - -if ($Help) { - Write-Host "ESBuild TypeScript -> JavaScript Compilation Script" - Write-Host "" - Write-Host "Parameters:" - Write-Host " -Force (-f) Removes any lock files and forces the script to run" - Write-Host " -Configuration (-c) Build configuration (default is 'Release')" - Write-Host " Valid values are 'Debug' and 'Release'" - Write-Host " -Help (-h) Display this help message" - exit 0 -} - -cd $PSScriptRoot - -$DebugLockFilePath = Join-Path -Path $PSScriptRoot "esBuild.Debug.lock" -$ReleaseLockFilePath = Join-Path -Path $PSScriptRoot "esBuild.Release.lock" -$LockFilePath = if ($Configuration.ToLowerInvariant() -eq "release") { $ReleaseLockFilePath } else { $DebugLockFilePath } - -# Check for changes before starting the dialog -$RecordFilePath = Join-Path -Path $PSScriptRoot ".." ".." ".esbuild-record.json" -$ScriptsDir = Join-Path -Path $PSScriptRoot "Scripts" -$OutputDir = Join-Path -Path $PSScriptRoot "wwwroot" "js" - -# Handle --force flag: delete record file -if ($Force) -{ - if (Test-Path $RecordFilePath) - { - Write-Host "Force rebuild: Deleting existing record file." - Remove-Item -Path $RecordFilePath -Force - } -} - -function Get-CurrentGitBranch -{ - try - { - $branch = git rev-parse --abbrev-ref HEAD 2> $null - if ($LASTEXITCODE -eq 0) - { - return $branch.Trim() - } - return "unknown" - } - catch - { - return "unknown" - } -} - -function Get-LastBuildRecord -{ - if (-not (Test-Path $RecordFilePath)) - { - return @{ timestamp = 0; branch = "unknown" } - } - try - { - $data = Get-Content -Path $RecordFilePath -Raw | ConvertFrom-Json - return @{ - timestamp = if ($data.timestamp) - { - $data.timestamp - } - else - { - 0 - } - branch = if ($data.branch) - { - $data.branch - } - else - { - "unknown" - } - } - } - catch - { - return @{ timestamp = 0; branch = "unknown" } - } -} - -function Get-ScriptsModifiedSince -{ - param([long]$LastTimestamp) - - # Convert JavaScript timestamp (milliseconds) to DateTime - $lastBuildTime = [DateTimeOffset]::FromUnixTimeMilliseconds($LastTimestamp).DateTime - - $files = Get-ChildItem -Path $ScriptsDir -Recurse -File - foreach ($file in $files) - { - if ($file.LastWriteTime -gt $lastBuildTime) - { - return $true - } - } - return $false -} - -# Check if build is needed -$lastBuild = Get-LastBuildRecord -$currentBranch = Get-CurrentGitBranch -$branchChanged = $currentBranch -ne $lastBuild.branch - -$needsBuild = $false -if ($branchChanged) -{ - Write-Host "Git branch changed from `"$( $lastBuild.branch )`" to `"$currentBranch`". Rebuilding..." - $needsBuild = $true -} -elseif (-not (Get-ScriptsModifiedSince -LastTimestamp $lastBuild.timestamp)) -{ - Write-Host "No changes in Scripts folder since last build." - - # Check output directory for existing files - if ((Test-Path $OutputDir) -and ((Get-ChildItem -Path $OutputDir -File).Count -gt 0)) - { - Write-Host "Output directory is not empty. Skipping build." - exit 0 - } - else - { - Write-Host "Output directory is empty. Proceeding with build." - $needsBuild = $true - } -} -else -{ - Write-Host "Changes detected in Scripts folder. Proceeding with build." - $needsBuild = $true -} - -if (-not $needsBuild) -{ - exit 0 -} - -function WriteToDialog -{ - param([System.Diagnostics.Process]$DialogProcess, - [string]$Content) - if ($DialogProcess.StandardInput -eq $null) - { - return; - } - - $DialogProcess.StandardInput.WriteLine($Content); -} - -# Start dialog process only if we're actually going to build -$ConsoleDialogPath = Join-Path -Path $PSScriptRoot ".." ".." "build" -$DialogStartInfo = New-Object System.Diagnostics.ProcessStartInfo -$DialogStartInfo.FileName = "dotnet" -$DialogStartInfo.WorkingDirectory = $ConsoleDialogPath -$DialogStartInfo.Arguments = "ConsoleDialog.cs `"GeoBlazor Core ESBuild`"" -$DialogStartInfo.RedirectStandardInput = $true -$DialogStartInfo.RedirectStandardOutput = $true -$DialogStartInfo.UseShellExecute = $false - -$DialogProcess = [System.Diagnostics.Process]::Start($DialogStartInfo) - -# Check if the process is locked for the current configuration -$Locked = (($Configuration.ToLowerInvariant() -eq "debug") -and ($null -ne (Get-Item -Path $DebugLockFilePath -EA 0))) ` - -or (($Configuration.ToLowerInvariant() -eq "release") -and ($null -ne (Get-Item -Path $ReleaseLockFilePath -EA 0))) - -# Prevent multiple instances of the script from running at the same time -if ($Locked) -{ - if ($Force -eq $true) { - if (Test-Path $DebugLockFilePath) - { - Remove-Item -Path $DebugLockFilePath -Force - } - if (Test-Path $ReleaseLockFilePath) - { - Remove-Item -Path $ReleaseLockFilePath -Force - } - - Write-Host "Cleared esBuild lock files" - } else { - Write-Output "Another instance of the script is already running. Exiting." - $DialogProcess.Kill() - Exit 1 - } -} - -try -{ - # Lock - New-Item -Path $LockFilePath - - ## Delete old assets - from prior to 4.2.x - ## Eventually we can remove this, but it will make switching branches simpler - $AssetsPath = Join-Path -Path $PSScriptRoot "wwwroot/assets" - if (Test-Path $AssetsPath) - { - Write-Output "Deleting old assets at $AssetsPath" - Remove-Item -Path $AssetsPath -Recurse -Force -ErrorAction Stop - } - - $OutJsPath = Join-Path -Path $PSScriptRoot "wwwroot/js" - if (-not (Test-Path $OutJsPath)) - { - New-Item -Path $OutJsPath -ItemType Directory | Out-Null - } - - $Install = npm install 2>&1 - Write-Output $Install - foreach ($line in $Install) - { - WriteToDialog -DialogProcess $DialogProcess -Content $line - } - $HasError = ($Install -like "*Error*") - $HasWarning = ($Install -like "*Warning*") - Write-Output "-----" - WriteToDialog -DialogProcess $DialogProcess -Content "-----" - if ($HasError -ne $null -or $HasWarning -ne $null) - { - Write-Output "NPM Install failed" - WriteToDialog -DialogProcess $DialogProcess -Content "NPM Install failed" - WriteToDialog -DialogProcess $DialogProcess -Content "hold" - exit 1 - } - - # Run ESLint before build - Write-Output "Running ESLint..." - WriteToDialog -DialogProcess $DialogProcess -Content "Running ESLint..." - $Lint = npm run lint 2>&1 - Write-Output $Lint - foreach ($line in $Lint) - { - WriteToDialog -DialogProcess $DialogProcess -Content $line - } - $LintHasError = ($Lint -like "*error*") - if ($LintHasError -ne $null) - { - Write-Output "ESLint found errors" - WriteToDialog -DialogProcess $DialogProcess -Content "ESLint found errors" - WriteToDialog -DialogProcess $DialogProcess -Content "hold" - exit 1 - } - Write-Output "-----" - WriteToDialog -DialogProcess $DialogProcess -Content "-----" - - if ($Configuration.ToLowerInvariant() -eq "release") - { - $Build = npm run releaseBuild 2>&1 - Write-Output $Build - foreach ($line in $Build) - { - WriteToDialog -DialogProcess $DialogProcess -Content $line - } - $HasError = ($Build -like "*Error*") - $HasWarning = ($Build -like "*Warning*") - Write-Output "-----" - WriteToDialog -DialogProcess $DialogProcess -Content "-----" - if ($HasError -ne $null -or $HasWarning -ne $null) - { - WriteToDialog -DialogProcess $DialogProcess -Content "hold" - exit 1 - } - } - else - { - $Build = npm run debugBuild 2>&1 - Write-Output $Build - foreach ($line in $Build) - { - WriteToDialog -DialogProcess $DialogProcess -Content $line - } - $HasError = ($Build -like "*Error*") - $HasWarning = ($Build -like "*Warning*") - Write-Output "-----" - WriteToDialog -DialogProcess $DialogProcess -Content "-----" - if ($HasError -ne $null -or $HasWarning -ne $null) - { - WriteToDialog -DialogProcess $DialogProcess -Content "hold" - exit 1 - } - } - Write-Output "NPM Build Complete" - WriteToDialog -DialogProcess $DialogProcess -Content "NPM Build Complete" - WriteToDialog -DialogProcess $DialogProcess -Content "exit" - exit 0 -} -catch -{ - Write-Output "An error occurred in esBuild.ps1" - WriteToDialog -DialogProcess $DialogProcess -Content "An error occurred in esBuild.ps1" - Write-Output $_ - WriteToDialog -DialogProcess $DialogProcess -Content $_ - WriteToDialog -DialogProcess $DialogProcess -Content "hold" - exit 1 -} -finally -{ - # Unlock - if (Test-Path -Path $LockFilePath) - { - Remove-Item -Path $LockFilePath -Force - } -} \ No newline at end of file diff --git a/src/dymaptic.GeoBlazor.Core/esBuildLogger.ps1 b/src/dymaptic.GeoBlazor.Core/esBuildLogger.ps1 deleted file mode 100644 index 41fb7148b..000000000 --- a/src/dymaptic.GeoBlazor.Core/esBuildLogger.ps1 +++ /dev/null @@ -1,48 +0,0 @@ -param([string][Alias("c")]$Content, [bool]$isError=$false) - -# ESBuild logger - writes build output to a rolling 2-day log file -# Usage: ./esBuildLogger.ps1 -Content "Build message" [-isError $true] - -$logFile = Join-Path $PSScriptRoot "esbuild.log" - -# Load existing log content and trim entries older than 2 days -$logContent = Get-Content -Path $logFile -ErrorAction SilentlyContinue -$newLogContent = @() -$twoDaysAgo = (Get-Date).AddDays(-2) - -if ($logContent) -{ - $startIndex = 0 - for ($i = 0; $i -lt $logContent.Count; $i++) - { - $line = $logContent[$i] - if ($line -match '^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]') - { - $timestamp = [datetime]$matches[1] - if ($timestamp -lt $twoDaysAgo) - { - $startIndex = $i + 1 - } - else - { - break - } - } - } - $newLogContent = $logContent[$startIndex..($logContent.Count - 1)] -} - -# Add new entry with timestamp -$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" -$prefix = if ($isError) -{ - "[ERROR]" -} -else -{ - "" -} -$logEntry = "[$timestamp]$prefix $Content" -$newLogContent += $logEntry - -Set-Content -Path $logFile -Value $newLogContent -Force diff --git a/test/dymaptic.GeoBlazor.Core.Test.Automation/GeoBlazorTestClass.cs b/test/dymaptic.GeoBlazor.Core.Test.Automation/GeoBlazorTestClass.cs index f742d214b..c1ab31c0b 100644 --- a/test/dymaptic.GeoBlazor.Core.Test.Automation/GeoBlazorTestClass.cs +++ b/test/dymaptic.GeoBlazor.Core.Test.Automation/GeoBlazorTestClass.cs @@ -1,5 +1,6 @@ using Microsoft.Playwright; using System.Diagnostics; +using System.Text; using System.Web; @@ -64,7 +65,6 @@ protected async Task RunTestImplementation(string testName, int retries = 0) .ConfigureAwait(false); page.Console += HandleConsoleMessage; page.PageError += HandlePageError; - string testMethodName = testName.Split('.').Last(); try { @@ -86,54 +86,49 @@ protected async Task RunTestImplementation(string testName, int retries = 0) ILocator testBtn = page.GetByText("Run Test"); await testBtn.ClickAsync(); + ILocator passedSpan = page.GetByTestId("passed"); ILocator inconclusiveSpan = page.GetByTestId("inconclusive"); if (await inconclusiveSpan.IsVisibleAsync()) { + var (messages, errors) = CheckMessages(testName); + Trace.WriteLine(messages, "TEST"); + + if (!string.IsNullOrWhiteSpace(errors)) + { + // report errors but don't fail the test + Trace.WriteLine(errors, "TEST_ERROR"); + } + // Inconclusive we treat as passing for our automation purposes - Trace.WriteLine($"{testName} Inconclusive", "TEST"); + Trace.WriteLine($"{testName} Inconclusive", "TEST_INCONCLUSIVE"); + TestConfig.InconclusiveTests.Add(testName); } else { await Expect(passedSpan).ToBeVisibleAsync(VisibleOptions); await Expect(passedSpan).ToHaveTextAsync("Passed: 1"); - Trace.WriteLine($"{testName} Passed", "TEST"); - } + var (messages, errors) = CheckMessages(testName); + Trace.WriteLine(messages, "TEST"); - if (_consoleMessages.TryGetValue(testName, out List? consoleMessages)) - { - foreach (string message in consoleMessages) + if (!string.IsNullOrWhiteSpace(errors)) { - Trace.WriteLine(message, "TEST"); + Trace.WriteLine(errors, "TEST_ERROR"); + await RetryOrMarkAsFailure(testName, new Exception(errors), retries); + + return; } + + Trace.WriteLine($"{testName} Passed", "TEST"); } } catch (Exception ex) { - if (_errorMessages.TryGetValue(testMethodName, out List? testErrors)) - { - foreach (string error in testErrors.Distinct()) - { - Trace.WriteLine(error, "ERROR"); - } - } - else - { - Trace.WriteLine($"{ex.Message}{Environment.NewLine}{ex.StackTrace}", "ERROR"); - } - - if (retries > 2) - { - Assert.Fail($"{testName} Exceeded the maximum number of retries."); - } - - // Exponential backoff: 1s, 2s between retries - var backoffMs = 1000 * (retries + 1); - Trace.WriteLine($"Retrying {testName} in {backoffMs}ms (attempt {retries + 2}/3)", "TEST"); - await Task.Delay(backoffMs); - - await RunTestImplementation(testName, retries + 1); + var (messages, errors) = CheckMessages(testName); + Trace.WriteLine(messages, "TEST"); + Trace.WriteLine(errors, "TEST_ERROR"); + await RetryOrMarkAsFailure(testName, ex, retries); } finally { @@ -202,6 +197,30 @@ private BrowserNewContextOptions ContextOptions() }; } + private (string Messages, string Errors) CheckMessages(string testName) + { + StringBuilder messageBuilder = new(); + StringBuilder errorBuilder = new(); + + if (_consoleMessages.TryGetValue(testName, out var consoleMessages)) + { + foreach (var message in consoleMessages) + { + messageBuilder.AppendLine(message); + } + } + + if (_errorMessages.TryGetValue(testName, out var errorMessages)) + { + foreach (var message in errorMessages) + { + errorBuilder.AppendLine(message); + } + } + + return (messageBuilder.ToString(), errorBuilder.ToString()); + } + // Set up console message logging private void HandleConsoleMessage(object? pageObject, IConsoleMessage message) { @@ -243,6 +262,22 @@ private void HandlePageError(object? pageObject, string message) _errorMessages[testName].Add(message); } + private async Task RetryOrMarkAsFailure(string testName, Exception ex, int retries) + { + if (retries > 2) + { + TestConfig.FailedTests[testName] = $"{ex.Message}{Environment.NewLine}{ex.StackTrace}"; + Assert.Fail($"{testName} Exceeded the maximum number of retries."); + } + + // Exponential backoff: 1s, 2s between retries + var backoffMs = 1000 * (retries + 1); + Trace.WriteLine($"Retrying {testName} in {backoffMs}ms (attempt {retries + 2}/3)", "TEST"); + await Task.Delay(backoffMs); + + await RunTestImplementation(testName, retries + 1); + } + private readonly List _contexts = new(); private readonly BrowserTypeLaunchOptions? _launchOptions = new() { diff --git a/test/dymaptic.GeoBlazor.Core.Test.Automation/TestConfig.cs b/test/dymaptic.GeoBlazor.Core.Test.Automation/TestConfig.cs index 2d7f0d77b..c8d91f724 100644 --- a/test/dymaptic.GeoBlazor.Core.Test.Automation/TestConfig.cs +++ b/test/dymaptic.GeoBlazor.Core.Test.Automation/TestConfig.cs @@ -34,6 +34,10 @@ public class TestConfig ///
public static bool IsCI { get; private set; } + public static Dictionary FailedTests { get; } = []; + + public static List InconclusiveTests { get; } = []; + private static string ComposeFilePath => _proAvailable && !CoreOnly ? ProComposeFilePath : CoreComposeFilePath; private static string CoreComposeFilePath => Path.Combine(_projectFolder, "docker-compose-core.yml"); private static string ProComposeFilePath => Path.Combine(_projectFolder, "docker-compose-pro.yml"); @@ -71,6 +75,32 @@ public static async Task AssemblyInitialize(TestContext testContext) Trace.Listeners.Add(new StringBuilderTraceListener(logBuilder)); Trace.AutoFlush = true; + // Handle Ctrl-C gracefully + Console.CancelKeyPress += (sender, e) => + { + Trace.WriteLine("Ctrl-C detected, initiating shutdown...", "TEST_SHUTDOWN"); + e.Cancel = true; // Prevent immediate termination to allow cleanup + + // Trigger cancellation + if (!cts.IsCancellationRequested) + { + cts.Cancel(); + } + + if (!gracefulCts.IsCancellationRequested) + { + gracefulCts.Cancel(); + } + + // Force exit after timeout if cleanup hangs + Task.Run(async () => + { + await Task.Delay(15000); // 15 second timeout for cleanup + Trace.WriteLine("Cleanup timeout - forcing exit", "TEST_SHUTDOWN"); + Environment.Exit(1); + }); + }; + SetupConfiguration(); // kill old running test apps and containers @@ -104,19 +134,37 @@ public static async Task AssemblyInitialize(TestContext testContext) [AssemblyCleanup] public static async Task AssemblyCleanup() { + var isCancelled = cts.IsCancellationRequested; + // Dispose browser pool first if (BrowserPool.TryGetInstance(out var pool) && pool is not null) { Trace.WriteLine("Disposing browser pool...", "TEST_CLEANUP"); - await pool.DisposeAsync().ConfigureAwait(false); - Trace.WriteLine("Browser pool disposed", "TEST_CLEANUP"); + + try + { + using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(isCancelled ? 3 : 10)); + await pool.DisposeAsync().ConfigureAwait(false); + Trace.WriteLine("Browser pool disposed", "TEST_CLEANUP"); + } + catch (Exception ex) + { + Trace.WriteLine($"Browser pool disposal error: {ex.Message}", "TEST_CLEANUP"); + } } - cts.CancelAfter(5000); + if (!isCancelled) + { + cts.CancelAfter(5000); + } - await gracefulCts.CancelAsync(); + if (!gracefulCts.IsCancellationRequested) + { + await gracefulCts.CancelAsync(); + } - await Task.Delay(5000); + // Shorter delay if already cancelled + await Task.Delay(isCancelled ? 1000 : 5000); if (_useContainer) { From 4355a44cedc5f35a53809707bfee031dea0f9396 Mon Sep 17 00:00:00 2001 From: "submodule-validation-for-geoblazor[bot]" <235551211+submodule-validation-for-geoblazor[bot]@users.noreply.github.com> Date: Wed, 21 Jan 2026 22:27:34 +0000 Subject: [PATCH 7/7] Pipeline Build Commit of Version and Docs --- Directory.Build.props | 10 +++++----- build-tools/BuildAppSettings | Bin 0 -> 78256 bytes build-tools/BuildAppSettings.dll | Bin 10240 -> 10240 bytes .../BuildAppSettings.runtimeconfig.json | 4 ++-- build-tools/BuildTemplates | Bin 0 -> 78256 bytes build-tools/BuildTemplates.dll | Bin 23040 -> 24576 bytes build-tools/BuildTemplates.runtimeconfig.json | 4 ++-- build-tools/ConsoleDialog | Bin 0 -> 78256 bytes build-tools/ConsoleDialog.dll | Bin 11264 -> 11264 bytes build-tools/ConsoleDialog.runtimeconfig.json | 4 ++-- build-tools/ESBuild | Bin 0 -> 78256 bytes build-tools/ESBuild.dll | Bin 18944 -> 18944 bytes build-tools/ESBuild.runtimeconfig.json | 4 ++-- build-tools/ESBuildClearLocks | Bin 0 -> 78256 bytes build-tools/ESBuildClearLocks.dll | Bin 8192 -> 8192 bytes .../ESBuildClearLocks.runtimeconfig.json | 4 ++-- build-tools/ESBuildWaitForCompletion | Bin 0 -> 78256 bytes build-tools/ESBuildWaitForCompletion.dll | Bin 9728 -> 9728 bytes ...SBuildWaitForCompletion.runtimeconfig.json | 4 ++-- build-tools/FetchNuGetVersion | Bin 0 -> 78256 bytes build-tools/FetchNuGetVersion.dll | Bin 9216 -> 9216 bytes .../FetchNuGetVersion.runtimeconfig.json | 4 ++-- build-tools/GeoBlazorBuild | Bin 0 -> 78256 bytes build-tools/GeoBlazorBuild.dll | Bin 40448 -> 40448 bytes build-tools/GeoBlazorBuild.runtimeconfig.json | 4 ++-- 25 files changed, 21 insertions(+), 21 deletions(-) create mode 100755 build-tools/BuildAppSettings create mode 100755 build-tools/BuildTemplates create mode 100755 build-tools/ConsoleDialog create mode 100755 build-tools/ESBuild create mode 100755 build-tools/ESBuildClearLocks create mode 100755 build-tools/ESBuildWaitForCompletion create mode 100755 build-tools/FetchNuGetVersion create mode 100755 build-tools/GeoBlazorBuild diff --git a/Directory.Build.props b/Directory.Build.props index 8dfa8a8e3..a17678e13 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,16 +1,16 @@  - - + + enable enable - 5.0.0.37 + 5.0.0.38 true Debug;Release;SourceGen Highlighting AnyCPU $(MSBuildThisFileDirectory)src\dymaptic.GeoBlazor.Core - + $(StaticWebAssetEndpointExclusionPattern);js/** @@ -23,6 +23,6 @@ - + \ No newline at end of file diff --git a/build-tools/BuildAppSettings b/build-tools/BuildAppSettings new file mode 100755 index 0000000000000000000000000000000000000000..45ce8ddd230d3d024b08a790b3c67ba031b0f85e GIT binary patch literal 78256 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 delta 630 zcmZWlOK1~O6n!r-NQ+Y%i{LM9nvZ6qnctg_B$}uZKa~dBQjkG?GxJ6x`7xh`6l@EE z3N8``1aYg-f+!eJ)Qv8yg>FQ_g)3Kr=%OHkpx2V(!n?Tlp7YMVm-7~?3)RleEx$gl zJ?h@xi&Nd@*`c)pLX!xhgwT4dJ3bPQ;|n+!F5>-oJzU1Kk!Z0OiM-e~TzY-2aeiQ= zvZ%bf{Qf1E>8NanwB2^WQND{9LOk%_~TILnQWpzfq|JNUE+a{Vi zSr&3}|7v9R0A-~C}ac(dPQSg`*xHbRkVJ;lbR^V+Wdjj&kY$DZH%UB!1GTv aofeFI$c_#02yFvbnPM-#?;Gy&TmJwa9=2!z diff --git a/build-tools/BuildAppSettings.runtimeconfig.json b/build-tools/BuildAppSettings.runtimeconfig.json index 30e44d148..6766cb69d 100644 --- a/build-tools/BuildAppSettings.runtimeconfig.json +++ b/build-tools/BuildAppSettings.runtimeconfig.json @@ -6,8 +6,8 @@ "version": "10.0.0" }, "configProperties": { - "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\BuildAppSettings.cs", - "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "EntryPointFilePath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts/BuildAppSettings.cs", + "EntryPointFileDirectoryPath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts", "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, "System.ComponentModel.DefaultValueAttribute.IsSupported": false, "System.ComponentModel.Design.IDesignerHost.IsSupported": false, diff --git a/build-tools/BuildTemplates b/build-tools/BuildTemplates new file mode 100755 index 0000000000000000000000000000000000000000..38b514fdb7d7c8ddeb9221cf2695c53b828f227a GIT binary patch literal 78256 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 diff --git a/build-tools/BuildTemplates.runtimeconfig.json b/build-tools/BuildTemplates.runtimeconfig.json index af9a48010..97080ffdb 100644 --- a/build-tools/BuildTemplates.runtimeconfig.json +++ b/build-tools/BuildTemplates.runtimeconfig.json @@ -6,8 +6,8 @@ "version": "10.0.0" }, "configProperties": { - "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\BuildTemplates.cs", - "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "EntryPointFilePath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts/BuildTemplates.cs", + "EntryPointFileDirectoryPath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts", "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false } diff --git a/build-tools/ConsoleDialog b/build-tools/ConsoleDialog new file mode 100755 index 0000000000000000000000000000000000000000..636dd088d96def97cb0559e3caba687bd5e76ac2 GIT binary patch literal 78256 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 diff --git a/build-tools/ConsoleDialog.runtimeconfig.json b/build-tools/ConsoleDialog.runtimeconfig.json index 27bfc6111..033cf94ea 100644 --- a/build-tools/ConsoleDialog.runtimeconfig.json +++ b/build-tools/ConsoleDialog.runtimeconfig.json @@ -6,8 +6,8 @@ "version": "10.0.0" }, "configProperties": { - "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\ConsoleDialog.cs", - "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "EntryPointFilePath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts/ConsoleDialog.cs", + "EntryPointFileDirectoryPath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts", "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, "System.ComponentModel.DefaultValueAttribute.IsSupported": false, "System.ComponentModel.Design.IDesignerHost.IsSupported": false, diff --git a/build-tools/ESBuild b/build-tools/ESBuild new file mode 100755 index 0000000000000000000000000000000000000000..41912328b196b680c4edf415c16e09714d9f29f7 GIT binary patch literal 78256 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�r+E9OiPbG}QB-CHvPK0r0 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 B3I6~9 diff --git a/build-tools/ESBuild.runtimeconfig.json b/build-tools/ESBuild.runtimeconfig.json index 9fb9a7739..3b38c9acb 100644 --- a/build-tools/ESBuild.runtimeconfig.json +++ b/build-tools/ESBuild.runtimeconfig.json @@ -6,8 +6,8 @@ "version": "10.0.0" }, "configProperties": { - "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\ESBuild.cs", - "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "EntryPointFilePath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts/ESBuild.cs", + "EntryPointFileDirectoryPath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts", "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, "System.ComponentModel.DefaultValueAttribute.IsSupported": false, "System.ComponentModel.Design.IDesignerHost.IsSupported": false, diff --git a/build-tools/ESBuildClearLocks b/build-tools/ESBuildClearLocks new file mode 100755 index 0000000000000000000000000000000000000000..bb0a0a176259ff34bb597d605456f162b2b657c0 GIT binary patch literal 78256 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 s=by$-r=fp3JZ#%J;|($N*w?H1vVh(QUCw| literal 0 HcmV?d00001 diff --git a/build-tools/ESBuildClearLocks.dll b/build-tools/ESBuildClearLocks.dll index 564799e4c642004a067147e2f46bdb64313b7470..26bb90e7b044930a88355cc77fc2ddee11f83602 100644 GIT binary patch delta 1119 zcmZuxO=#3m5T0z3YFDlOvF*0qmX-=eYfZArb`z+jRcl*OT&dy@9{Q5JxYg~hCc9d_ zSPz0o1=r`P2;M{wf^exu(L6y)_SXfSrIc2=GoUbTurW09cOrq6V;=b%oZm{oEQZ%Ff{Uj@{t) zb}k^LB%`Py5aD_^Qda_Sh*7K9u4aWLLsxq~aBy^2eJCP@0D8Pn0cr`*j{vm>XdP?i z^>RL6k`JIU*2P+y2hLaBZkwFD@5o6s7dQ=w8PLR)~=vA2KOVg*~QV2c%O zvCK}galzoOvsocheGlu_E%jc8*iAw2eTzuy00`HImq=CEQ+?R`_RlAEVn|wrLr>US z&1%Hynu9ztB=q#I;60077WcIrf-Fn{ z1sOcZLk1s;mJBD*@4*qYM$nUmO^^lxrxv~c^|AAHZJf+5)UGW)sXNQnzWDZP?)=(` z&G+wW0-5<$U33~2ILR^X1SK&|B~D!Fvx%eF2|^6rjoTX0bkoA9LoI`yY1Gtd_W2=j zJCb_LX?HX?Moh(25=NhjqMW4#- zR#SWIPlwTRhq%s>FVA%M;ZJFJT1`EDU;ZYrap2=PbQZdrLJK-;ZvM(9n%5U=A_w@L z4wzs=0#AoP3^Y)2b|4N4^r63GD~oZ0wgEc07_%{tpz6rA%3KF4SYWU_ZA07(_PuSG z3$vlpDJi1!c)^ViXhs delta 1110 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 B1D*f? delta 1028 zcmZuwO=weD6h1dUFIxMmZJOHj2lHCBkESywFM01JwOXUmTCKK2TSR$a-_H$nNSk<* zEF4^j)5RviIx;ZeqKXSa6cuJOD`n10A~OpQoO922zVBYn z;kf+SZ-+aYeH#e%6`^eYo-BWG%QvlO|b^stNRHb0+0zfO`1s!0HOP&#anhbe- zVSb71CRu)$oFcC|@dR75K>&h6bb-I=iPdI2=g5{>KNQ(%H<sQAnp(YGIG%lkv-*Ke7pL+0ry>bH*)m{ zUrE6>w!L0td-=G3sG$)4r$`64HWUIXe)T6whClY-310{R49?F&Upv4yY+`U?elm;a zNbS7vml#;h!YCNPzjh99ae%@E`Z5@NJk%R9>Zkw*ArB_}0tH~mT<`292LCar*FJR) zd$x@|QdQrv(2>=(x%{pt-G^%O_UA-aQ+7_HF)Lv!skr9kG~Kk~c+jL}+G<)+ZK|k= zoXNYxBk}obQ-1?FG2_9u{y=|-n|~O_q-pMwan~?}zJj023a^9*C!znJqxaXlrdKj+ zPhRvtIP0nojT-YM%1XxE;?hioIh7?NQ!Hl9vS~~eY%_1n(WRo{6w1rAY_Q65ZZS^{ z{zdFQ`Gcw`2^x1a-ASZ%>@=rPJswNp44O?fC1K+jiDXv*==t2^;0;mpMPv*O7!$2X#X;#A-4qnk&n zQWtq$yVEmDYHfY@ywfVAz=j-XxStqUkU*qhEshnZUe|F)7UBk?kVIsnN`*8kRm^Dp zOrYB2fk=kD=aZ4cUa>{wS0cxV$X{Yj(^b diff --git a/build-tools/ESBuildWaitForCompletion.runtimeconfig.json b/build-tools/ESBuildWaitForCompletion.runtimeconfig.json index 0010c1e92..3e7d1efdf 100644 --- a/build-tools/ESBuildWaitForCompletion.runtimeconfig.json +++ b/build-tools/ESBuildWaitForCompletion.runtimeconfig.json @@ -6,8 +6,8 @@ "version": "10.0.0" }, "configProperties": { - "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\ESBuildWaitForCompletion.cs", - "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "EntryPointFilePath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts/ESBuildWaitForCompletion.cs", + "EntryPointFileDirectoryPath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts", "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, "System.ComponentModel.DefaultValueAttribute.IsSupported": false, "System.ComponentModel.Design.IDesignerHost.IsSupported": false, diff --git a/build-tools/FetchNuGetVersion b/build-tools/FetchNuGetVersion new file mode 100755 index 0000000000000000000000000000000000000000..077ee4a1f0e334485400a685c677c4214630dfd6 GIT binary patch literal 78256 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 aSW}FA$YplO0PGZ&%4WBJ=sWDl+y4RqOuEtl diff --git a/build-tools/FetchNuGetVersion.runtimeconfig.json b/build-tools/FetchNuGetVersion.runtimeconfig.json index 568a9e54a..a1cdfde9a 100644 --- a/build-tools/FetchNuGetVersion.runtimeconfig.json +++ b/build-tools/FetchNuGetVersion.runtimeconfig.json @@ -6,8 +6,8 @@ "version": "10.0.0" }, "configProperties": { - "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\FetchNuGetVersion.cs", - "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "EntryPointFilePath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts/FetchNuGetVersion.cs", + "EntryPointFileDirectoryPath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts", "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, "System.ComponentModel.DefaultValueAttribute.IsSupported": false, "System.ComponentModel.Design.IDesignerHost.IsSupported": false, diff --git a/build-tools/GeoBlazorBuild b/build-tools/GeoBlazorBuild new file mode 100755 index 0000000000000000000000000000000000000000..d263ef349902e2aa4153fafa47bec4100b38e120 GIT binary patch literal 78256 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 Ntm?!+xnXb7{{SS!Y>fZ_ delta 3801 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

i{>`sKEcF?EmQkPg-^C6K>R1 F@LvIOVg&#I diff --git a/build-tools/GeoBlazorBuild.runtimeconfig.json b/build-tools/GeoBlazorBuild.runtimeconfig.json index 59562bf43..789dbb8d2 100644 --- a/build-tools/GeoBlazorBuild.runtimeconfig.json +++ b/build-tools/GeoBlazorBuild.runtimeconfig.json @@ -6,8 +6,8 @@ "version": "10.0.0" }, "configProperties": { - "EntryPointFilePath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts\\GeoBlazorBuild.cs", - "EntryPointFileDirectoryPath": "D:\\dymaptic.GeoBlazor.CodeGen\\GeoBlazor.Pro\\GeoBlazor\\build-scripts", + "EntryPointFilePath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts/GeoBlazorBuild.cs", + "EntryPointFileDirectoryPath": "/home/runner/work/GeoBlazor/GeoBlazor/build-scripts", "Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability": true, "System.ComponentModel.DefaultValueAttribute.IsSupported": false, "System.ComponentModel.Design.IDesignerHost.IsSupported": false,