public static void LayoutHeaderButton(Texture2D headerTexture, string headerURL)
        {
            if (headerTexture != null)
            {
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                float maxWidth = EditorGUIUtility.currentViewWidth - WitStyles.WindowPaddingLeft - WitStyles.WindowPaddingRight - WitStyles.IconButton.CalcSize(WitStyles.HelpIcon).x;
                float headerWidth = Mathf.Min(WitStyles.HeaderWidth, maxWidth);
                float headerHeight = headerWidth * (float)headerTexture.height / (float)headerTexture.width;
                if (GUILayout.Button(headerTexture, WitStyles.HeaderButton, GUILayout.Width(headerWidth), GUILayout.Height(headerHeight)) && !string.IsNullOrEmpty(headerURL))
                {
                    Application.OpenURL(headerURL);
                }
                GUILayout.FlexibleSpace();
                if (LayoutIconButton(WitStyles.HelpIcon))
                {
                    Application.OpenURL(headerURL);
                }
                GUILayout.EndHorizontal();
            }
        }


public static T FindUnityAsset<T>(string filter) where T : UnityEngine.Object
        {
            T[] results = FindUnityAssets<T>(filter, true);
            if (results != null && results.Length > 0)
            {
                return results[0];
            }
            return null;
        }


private static IEnumerable<MethodBase> TargetMethods() =>
        typeof(PopFXManager).GetMethods()
            .Where(it => it.Name.StartsWith("SpawnFX"));

// ReSharper disable once UnusedMember.Local


[TestMethod]
        public void ATest()
        {
            string? ip = DNSHelpers.AQuery("hypixel.net");
            Console.WriteLine(ip);
            Assert.IsNotNull(string.IsNullOrEmpty(ip));
        }


private AppVersion? GetLatestVersion(bool enablePre)
        {
            if (_version is null)
                return null;
            using(HttpRequestMessage request = new(HttpMethod.Get, "releases/latest"))
            {
                request.Headers.Add("User-Agent", $"{_version.AppName}-AppUpdater");
                using(HttpResponseMessage response = _client.Send(request))
                {
                    if (!response.IsSuccessStatusCode)
                        throw new HttpRequestException(response.StatusCode.ToString());
                    string resultString = string.Empty;
                    Task.Run(async () =>
                    {
                        resultString = await response.Content.ReadAsStringAsync();
                    }).Wait();
                    Release release = JsonSerializer.Deserialize<Release>(resultString) ?? throw new JsonException();
                    foreach(var asset in release.Assets)
                    {
                        string fileName = Path.GetFileNameWithoutExtension(asset.Name);
                        try
                        {
                            fileName = "NectarRcon-x86-1.0.0-beta2";
                            AppVersion version = AppVersion.ParseVersion(fileName);
                            if(version.AppName.ToLower() == _version.AppName.ToLower() && version.Platform.ToLower() == _version.Platform.ToLower())
                            {
                                if (version.IsPreRelease && !enablePre)
                                    continue;
                                if (version > _version)
                                {
                                    return version;
                                }
                            }
                        }
                        catch (InvalidOperationException) { } // Invalid version format
                    }
                    return null;
                }
            }
        }

/// <summary>
/// 获取最新版本, null为没找到
/// </summary>
/// <param name="enablePre">是否允许pre版本</param>


public static UniTask<T> AsUniTask<T>(this Task<T> task, bool useCurrentSynchronizationContext = true)
        {
            var promise = new UniTaskCompletionSource<T>();

            task.ContinueWith((x, state) =>
            {
                var p = (UniTaskCompletionSource<T>)state;

                switch (x.Status)
                {
                    case TaskStatus.Canceled:
                        p.TrySetCanceled();
                        break;
                    case TaskStatus.Faulted:
                        p.TrySetException(x.Exception);
                        break;
                    case TaskStatus.RanToCompletion:
                        p.TrySetResult(x.Result);
                        break;
                    default:
                        throw new NotSupportedException();
                }
            }, promise, useCurrentSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current);

            return promise.Task;
        }

/// <summary>
/// Convert Task[T] -> UniTask[T].
/// </summary>


public static void BindTo<TSource, TObject>(this IUniTaskAsyncEnumerable<TSource> source, TObject monoBehaviour, Action<TObject, TSource> bindAction, bool rebindOnError = true)
            where TObject : MonoBehaviour
        {
            BindToCore(source, monoBehaviour, bindAction, monoBehaviour.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
        }


UniTaskStatus IUniTaskSource.GetStatus(short token)
        {
            return UniTaskStatus.Pending;
        }

// dummy interface implementation for TaskTracker.


protected override object GetUninitializedObject()
        {
            return Activator.CreateInstance(this.SerializedType);
        }

/// <summary>
/// Gets a new object of type <see cref="T" />.
/// </summary>
/// <returns>
/// A new object of type <see cref="T" />.
/// </returns>


protected override void DeserializeImplementation(ref T value, IDataReader reader)
        {
            #if false //vrc security patch
            string name;
            EntryType entry;

            entry = reader.PeekEntry(out name);

            if (entry == EntryType.StartOfArray)
            {
                // We have legacy ISerializable data for the MethodInfo, since in no case will data written by this formatter ever start with an array.
                // In this case, get the proper legacy formatter for this type and read the data using that.

                IFormatter serializableFormatter;
                serializableFormatter = new WeakSerializableFormatter(typeof(T));
                value = (T)(object)serializableFormatter.Deserialize(reader);
                return;
            }

            Type declaringType = null;
            string methodName = null;
            Type[] signature = null;
            Type[] genericArguments = null;

            while ((entry = reader.PeekEntry(out name)) != EntryType.EndOfNode && entry != EntryType.EndOfArray && entry != EntryType.EndOfStream)
            {
                switch (name)
                {
                    case "declaringType":
                        {
                            var t = TypeSerializer.ReadValue(reader);

                            if (t != null)
                            {
                                declaringType = t;
                            }
                        }
                        break;

                    case "methodName":
                        {
                            methodName = StringSerializer.ReadValue(reader);
                        }
                        break;

                    case "signature":
                        {
                            signature = TypeArraySerializer.ReadValue(reader);
                        }
                        break;

                    case "genericArguments":
                        {
                            genericArguments = TypeArraySerializer.ReadValue(reader);
                        }
                        break;

                    default:
                        reader.SkipEntry();
                        break;
                }
            }

            if (declaringType == null)
            {
                reader.Context.Config.DebugContext.LogWarning("Missing declaring type of MethodInfo on deserialize.");
                return;
            }

            if (methodName == null)
            {
                reader.Context.Config.DebugContext.LogError("Missing method name of MethodInfo on deserialize.");
                return;
            }

            MethodInfo methodInfo;
            bool useSignature = false;
            bool wasAmbiguous = false;

            if (signature != null)
            {
                useSignature = true;

                for (int i = 0; i < signature.Length; i++)
                {
                    if (signature[i] == null)
                    {
                        useSignature = false;
                        break;
                    }
                }
            }

            if (useSignature)
            {
                try
                {
                    methodInfo = declaringType.GetMethod(methodName, Flags.AllMembers, null, signature, null);
                }
                catch (AmbiguousMatchException)
                {
                    methodInfo = null;
                    wasAmbiguous = true;
                }
            }
            else
            {
                try
                {
                    methodInfo = declaringType.GetMethod(methodName, Flags.AllMembers);
                }
                catch (AmbiguousMatchException)
                {
                    methodInfo = null;
                    wasAmbiguous = true;
                }
            }

            if (methodInfo == null)
            {
                if (useSignature)
                {
                    reader.Context.Config.DebugContext.LogWarning("Could not find method with signature " + name + "(" + string.Join(", ", signature.Select(p => p.GetNiceFullName()).ToArray()) + ") on type '" + declaringType.FullName + (wasAmbiguous ? "; resolution was ambiguous between multiple methods" : string.Empty) + ".");
                }
                else
                {
                    reader.Context.Config.DebugContext.LogWarning("Could not find method with name " + name + " on type '" + declaringType.GetNiceFullName() + (wasAmbiguous ? "; resolution was ambiguous between multiple methods" : string.Empty) + ".");
                }

                return;
            }

            if (methodInfo.IsGenericMethodDefinition)
            {
                if (genericArguments == null)
                {
                    reader.Context.Config.DebugContext.LogWarning("Method '" + declaringType.GetNiceFullName() + "." + methodInfo.GetNiceName() + "' to deserialize is a generic method definition, but no generic arguments were in the serialization data.");
                    return;
                }

                int argCount = methodInfo.GetGenericArguments().Length;

                if (genericArguments.Length != argCount)
                {
                    reader.Context.Config.DebugContext.LogWarning("Method '" + declaringType.GetNiceFullName() + "." + methodInfo.GetNiceName() + "' to deserialize is a generic method definition, but there is the wrong number of generic arguments in the serialization data.");
                    return;
                }

                for (int i = 0; i < genericArguments.Length; i++)
                {
                    if (genericArguments[i] == null)
                    {
                        reader.Context.Config.DebugContext.LogWarning("Method '" + declaringType.GetNiceFullName() + "." + methodInfo.GetNiceName() + "' to deserialize is a generic method definition, but one of the serialized generic argument types failed to bind on deserialization.");
                        return;
                    }
                }

                try
                {
                    methodInfo = methodInfo.MakeGenericMethod(genericArguments);
                }
                catch (Exception ex)
                {
                    reader.Context.Config.DebugContext.LogWarning("Method '" + declaringType.GetNiceFullName() + "." + methodInfo.GetNiceName() + "' to deserialize is a generic method definition, but failed to create generic method from definition, using generic arguments '" + string.Join(", ", genericArguments.Select(p => p.GetNiceFullName()).ToArray()) + "'. Method creation failed with an exception of type " + ex.GetType().GetNiceFullName() + ", with the message: " + ex.Message);
                    return;
                }
            }

            try
            {
                value = (T)methodInfo;
            }
            catch (InvalidCastException)
            {
                reader.Context.Config.DebugContext.LogWarning("The serialized method '" + declaringType.GetNiceFullName() + "." + methodInfo.GetNiceName() + "' was successfully resolved into a MethodInfo reference of the runtime type '" + methodInfo.GetType().GetNiceFullName() + "', but failed to be cast to expected type '" + typeof(T).GetNiceFullName() + "'.");
                return;
            }

            this.RegisterReferenceID(value, reader);
            #endif
            reader.Context.Config.DebugContext.LogWarning("MethodInfo deserialization has been removed for security."); //VRC
        }

/// <summary>
/// Provides the actual implementation for deserializing a value of type <see cref="!:T" />.
/// </summary>
/// <param name="value">The uninitialized value to serialize into. This value will have been created earlier using <see cref="M:OdinSerializer.BaseFormatter`1.GetUninitializedObject" />.</param>
/// <param name="reader">The reader to deserialize with.</param>


public static HashSet<object> GetSceneObjectsToKeepSet(UnityEngine.Object unityObject, bool createIfDoesntExist)
            {
                HashSet<object> keep;

                if (!SceneObjectsToKeepOnApply.TryGetValue(unityObject, out keep))
                {
                    keep = new HashSet<object>(ReferenceEqualityComparer<object>.Default);
                    SceneObjectsToKeepOnApply.Add(unityObject, keep);
                }

                return keep;
            }

/// <summary>
/// Note: it is assumed that code calling this is holding the DeserializePrefabCaches_LOCK lock, and will continue to hold it while the returned hashset is being modified
/// </summary>


public bool isDefaultConfig()
        {
            return fileName == content && content == "Default";
        }


public bool load()
        {
            try
            {
                if (!File.Exists(resultsFileName))
                {
                    return false;
                }

                string jsonString = File.ReadAllText(resultsFileName);
                loadedInstance = JsonSerializer.Deserialize<ScanResults>(jsonString)!;

            }
            catch (Exception ex)
            {
                Tools.logStep($"ScanResults.load() had exception: {ex.Message}");
                return false;
            }

            return true;
        }


public async Task InitializeAsync() {
			await FtpContainer.StartAsync().ConfigureAwait(false);
		}


public static void CheckBlobPrefix(string prefix) {
			if (prefix == null) return;

			string[] parts = prefix.Split('/');

			foreach (string part in parts) {
				if (part.Length > MaxBlobPrefixLength)
					throw new ArgumentException(
					   string.Format("blob prefix cannot exceed {0} characters", MaxBlobPrefixLength),
					   nameof(prefix));
			}
		}

/// <summary>
/// Validates blob prefix search
/// </summary>
/// <param name="prefix"></param>


public static IApplicationBuilder UseThrottlingTroll(this IApplicationBuilder builder, Action<ThrottlingTrollOptions> options = null)
        {
            // Need to create this instance here, so that Assemblies are correctly initialized.
            var opt = new ThrottlingTrollOptions
            {
                Assemblies = new List<Assembly> { Assembly.GetCallingAssembly() }
            };

            if (options != null)
            {
                options(opt);
            }

            opt.GetConfigFunc = ThrottlingTrollCoreExtensions.MergeAllConfigSources(opt.Config, CollectDeclarativeConfig(opt.Assemblies), opt.GetConfigFunc, builder.ApplicationServices);

            if (opt.Log == null)
            {
                var logger = builder.ApplicationServices.GetService<ILogger<ThrottlingTroll>>();
                opt.Log = logger == null ? null : (l, s) => logger.Log(l, s);
            }

            // TODO: move default counter store creation into ThrottlingTroll
            opt.CounterStore ??= builder.ApplicationServices.GetService<ICounterStore>() ?? new MemoryCacheCounterStore();

            return builder.UseMiddleware<ThrottlingTrollMiddleware>(opt);
        }

/// <summary>
/// Configures ThrottlingTroll ingress throttling
/// </summary>


public static IHttpClientBuilder AddThrottlingTrollMessageHandler(this IHttpClientBuilder builder, Action<ThrottlingTrollOptions> options = null)
        {
            return builder.AddThrottlingTrollMessageHandler(options == null ? null : (provider, opt) => options(opt));
        }

/// <summary>
/// Appends <see cref="ThrottlingTrollHandler"/> to the given HttpClient.
/// Optionally allows to configure options.
/// </summary>


void Awake()
		{
			if ( linearMapping == null )
			{
				linearMapping = GetComponent<LinearMapping>();
			}
		}


void Awake()
		{
			if ( animator == null )
			{
				animator = GetComponent<Animator>();
			}

			animator.speed = 0.0f;

			if ( linearMapping == null )
			{
				linearMapping = GetComponent<LinearMapping>();
			}
		}


void Awake()
		{
			thisAudioSource = GetComponent<AudioSource>();

			if ( playOnAwake )
			{
				Play();
			}
		}


void Awake()
		{
			allowTeleport = GetComponent<AllowTeleportWhileAttachedToHand>();
			//allowTeleport.teleportAllowed = true;
			allowTeleport.overrideHoverLock = false;

			arrowList = new List<GameObject>();
		}


[HarmonyPrefix] [HarmonyPatch(nameof(PlatformerMovement.Update))] static bool Update(PlatformerMovement __instance)
        {
            if (MonoSingleton<OptionsManager>.Instance.paused) return false;

            Vector2 vector = Vector2.zero;
            if (__instance.activated)
            {
                vector = Input.InputVars.MoveVector * Vars.Config.MovementMultiplier;
                __instance.movementDirection = Vector3.ClampMagnitude(vector.x * Vector3.right + vector.y * Vector3.forward, 1f);
                __instance.movementDirection = Quaternion.Euler(0f, __instance.platformerCamera.rotation.eulerAngles.y, 0f) * __instance.movementDirection;
            }
            else
            {
                __instance.rb.velocity = new Vector3(0f, __instance.rb.velocity.y, 0f);
                __instance.movementDirection = Vector3.zero;
            }

            if (__instance.movementDirection.magnitude > 0f) __instance.anim.SetBool("Running", true);
            else __instance.anim.SetBool("Running", false);

            if (__instance.rb.velocity.y < -100f)
                __instance.rb.velocity = new Vector3(__instance.rb.velocity.x, -100f, __instance.rb.velocity.z);

            if (__instance.activated && MonoSingleton<InputManager>.Instance.InputSource.Jump.WasPerformedThisFrame
                && !__instance.falling && !__instance.jumpCooldown) __instance.Jump(false, 1f);

            if (!__instance.groundCheck.onGround)
            {
                if (__instance.fallTime < 1f)
                {
                    __instance.fallTime += Time.deltaTime * 5f;
                    if (__instance.fallTime > 1f) __instance.falling = true;
                }
                else if (__instance.rb.velocity.y < -2f) __instance.fallSpeed = __instance.rb.velocity.y;
            }
            else __instance.fallTime = 0f;

            if (__instance.groundCheck.onGround && __instance.falling && !__instance.jumpCooldown)
            {
                __instance.falling = false;
                __instance.fallSpeed = 0f;
                __instance.groundCheck.heavyFall = false;
            }

            if (MonoSingleton<InputManager>.Instance.InputSource.Slide.WasPerformedThisFrame && __instance.groundCheck.onGround
                && __instance.activated && !__instance.sliding) __instance.StartSlide();

            RaycastHit raycastHit;
            if (MonoSingleton<InputManager>.Instance.InputSource.Slide.WasPerformedThisFrame
                && !__instance.groundCheck.onGround && !__instance.sliding && !__instance.jumping && __instance.activated
                && Physics.Raycast(__instance.groundCheck.transform.position + __instance.transform.up, __instance.transform.up * -1f, out raycastHit, 2f,
                LayerMaskDefaults.Get(LMD.Environment))) __instance.StartSlide();

            if (MonoSingleton<InputManager>.Instance.InputSource.Slide.WasCanceledThisFrame && __instance.sliding)
                __instance.StopSlide();

            if (__instance.sliding && __instance.activated)
            {
                __instance.slideLength += Time.deltaTime;
                if (__instance.currentSlideEffect != null) __instance.currentSlideEffect.transform.position = __instance.transform.position + __instance.dodgeDirection * 10f;
                if (__instance.slideSafety > 0f) __instance.slideSafety -= Time.deltaTime * 5f;
                if (__instance.groundCheck.onGround) __instance.currentSlideScrape.transform.position = __instance.transform.position + __instance.dodgeDirection;
                else __instance.currentSlideScrape.transform.position = Vector3.one * 5000f;
            }

            // Dash fix
            if (MonoSingleton<InputManager>.Instance.InputSource.Dodge.WasPerformedThisFrame && __instance.activated)
            {
                if (__instance.groundProperties && !__instance.groundProperties.canDash)
                    if (!__instance.groundProperties.silentDashFail) Object.Instantiate<GameObject>(__instance.staminaFailSound);
                /* else */ if (__instance.boostCharge >= 100f)
                {
                    if (__instance.sliding) __instance.StopSlide();
                    __instance.boostLeft = 100f;
                    __instance.boost = true;
                    __instance.anim.Play("Dash", -1, 0f);

                    __instance.dodgeDirection = __instance.movementDirection.normalized * Vars.Config.MovementMultiplier;
                    if (__instance.dodgeDirection == Vector3.zero)
                        __instance.dodgeDirection = __instance.playerModel.forward * Vars.Config.MovementMultiplier;

                    Quaternion identity = Quaternion.identity;
                    identity.SetLookRotation(__instance.dodgeDirection * -1f);
                    Object.Instantiate<GameObject>
                            (__instance.dodgeParticle, __instance.transform.position + Vector3.up * 2f + __instance.dodgeDirection * 10f, identity).transform.localScale *= 2f;
                    if (!MonoSingleton<AssistController>.Instance.majorEnabled || !MonoSingleton<AssistController>.Instance.infiniteStamina)
                        __instance.boostCharge -= 100f;

                    __instance.aud.clip = __instance.dodgeSound;
                    __instance.aud.volume = 1f;
                    __instance.aud.pitch = 1f;
                    __instance.aud.Play();
                }
                else Object.Instantiate<GameObject>(__instance.staminaFailSound);
            }

            if (__instance.boostCharge != 300f && !__instance.sliding && !__instance.spinning)
            {
                float num = 1f;
                if (__instance.difficulty == 1) num = 1.5f;
                else if (__instance.difficulty == 0) num = 2f;

                __instance.boostCharge = Mathf.MoveTowards(__instance.boostCharge, 300f, 70f * Time.deltaTime * num);
            }

            if (__instance.spinCooldown > 0f) __instance.spinCooldown = Mathf.MoveTowards(__instance.spinCooldown, 0f, Time.deltaTime);

            if (__instance.activated && !__instance.spinning && __instance.spinCooldown <= 0f && !MonoSingleton<InputManager>.Instance.PerformingCheatMenuCombo()
                && (MonoSingleton<InputManager>.Instance.InputSource.Fire1.WasPerformedThisFrame
                || MonoSingleton<InputManager>.Instance.InputSource.Fire2.WasPerformedThisFrame
                || MonoSingleton<InputManager>.Instance.InputSource.Punch.WasPerformedThisFrame)
                && !MonoSingleton<OptionsManager>.Instance.paused) __instance.Spin();

            if (__instance.spinning) __instance.playerModel.Rotate(Vector3.up, Time.deltaTime * 3600f, Space.Self);
            else if (__instance.movementDirection.magnitude != 0f || __instance.boost)
            {
                Quaternion quaternion = Quaternion.LookRotation(__instance.movementDirection);
                if (__instance.boost)
                    quaternion = Quaternion.LookRotation(__instance.dodgeDirection);
                __instance.playerModel.rotation =
                    Quaternion.RotateTowards(__instance.playerModel.rotation, quaternion,
                    (Quaternion.Angle(__instance.playerModel.rotation, quaternion) + 20f) * 35f * __instance.movementDirection.magnitude * Time.deltaTime);
            }

            if (__instance.cameraTrack)
            {
                if (!__instance.freeCamera)
                {
                    __instance.CheckCameraTarget(false);
                    __instance.platformerCamera.transform.position =
                        Vector3.MoveTowards(__instance.platformerCamera.position, __instance.transform.position + __instance.cameraTarget,
                        Time.deltaTime * 15f * (0.1f + Vector3.Distance(__instance.platformerCamera.position, __instance.cameraTarget)));

                    __instance.platformerCamera.transform.rotation =
                        Quaternion.RotateTowards(__instance.platformerCamera.transform.rotation,
                        Quaternion.Euler(__instance.cameraRotation), Time.deltaTime * 15f * (0.1f + Vector3.Distance(__instance.platformerCamera.rotation.eulerAngles,
                        __instance.cameraRotation)));
                }
                else if (!MonoSingleton<OptionsManager>.Instance.paused)
                {
                    __instance.platformerCamera.transform.position = __instance.transform.position + __instance.defaultCameraTarget;
                    __instance.platformerCamera.transform.rotation = Quaternion.Euler(__instance.defaultCameraRotation);

                    Vector2 vector2 = MonoSingleton<InputManager>.Instance.InputSource.Look.ReadValue<Vector2>();
                    if (!MonoSingleton<CameraController>.Instance.reverseY) __instance.rotationX += vector2.y * (MonoSingleton<OptionsManager>.Instance.mouseSensitivity / 10f);
                    else __instance.rotationX -= vector2.y * (MonoSingleton<OptionsManager>.Instance.mouseSensitivity / 10f);

                    if (!MonoSingleton<CameraController>.Instance.reverseX) __instance.rotationY += vector2.x * (MonoSingleton<OptionsManager>.Instance.mouseSensitivity / 10f);
                    else __instance.rotationY -= vector2.x * (MonoSingleton<OptionsManager>.Instance.mouseSensitivity / 10f);

                    if (__instance.rotationY > 180f) __instance.rotationY -= 360f;
                    else if (__instance.rotationY < -180f) __instance.rotationY += 360f;

                    __instance.rotationX = Mathf.Clamp(__instance.rotationX, -69f, 109f);

                    float num2 = 2.5f;
                    if (__instance.sliding || Physics.Raycast(__instance.transform.position + Vector3.up * 0.625f, Vector3.up, 2.5f, LayerMaskDefaults.Get(LMD.Environment)))
                        num2 = 0.625f;

                    Vector3 vector3 = __instance.transform.position + Vector3.up * num2;
                    __instance.platformerCamera.RotateAround(vector3, Vector3.left, __instance.rotationX);
                    __instance.platformerCamera.RotateAround(vector3, Vector3.up, __instance.rotationY);

                    RaycastHit raycastHit2;
                    if (Physics.SphereCast(vector3, 0.25f, __instance.platformerCamera.position - vector3, out raycastHit2,
                        Vector3.Distance(vector3, __instance.platformerCamera.position), LayerMaskDefaults.Get(LMD.Environment)))
                        __instance.platformerCamera.position = raycastHit2.point + 0.5f * raycastHit2.normal;
                }
            }

            RaycastHit raycastHit3;
            if (Physics.SphereCast(__instance.transform.position + Vector3.up, 0.5f, Vector3.down, out raycastHit3, float.PositiveInfinity,
                LayerMaskDefaults.Get(LMD.Environment), QueryTriggerInteraction.Ignore))
            {
                __instance.jumpShadow.position = raycastHit3.point + Vector3.up * 0.05f;
                __instance.jumpShadow.forward = raycastHit3.normal;
            }
            else
            {
                __instance.jumpShadow.position = __instance.transform.position - Vector3.up * 1000f;
                __instance.jumpShadow.forward = Vector3.up;
            }

            if (__instance.coinTimer > 0f) __instance.coinTimer = Mathf.MoveTowards(__instance.coinTimer, 0f, Time.deltaTime);
            if (__instance.coinEffectTimer > 0f) __instance.coinEffectTimer = Mathf.MoveTowards(__instance.coinEffectTimer, 0f, Time.deltaTime);
            else if (__instance.queuedCoins > 0) __instance.CoinGetEffect();

            if (__instance.invincible && __instance.extraHits < 3)
            {
                if (__instance.blinkTimer > 0f)
                    __instance.blinkTimer = Mathf.MoveTowards(__instance.blinkTimer, 0f, Time.deltaTime);
                else
                {
                    __instance.blinkTimer = 0.05f;
                    if (__instance.playerModel.gameObject.activeSelf) __instance.playerModel.gameObject.SetActive(false);
                    else __instance.playerModel.gameObject.SetActive(true);
                }
            }

            if (__instance.superTimer > 0f)
            {
                if (!NoWeaponCooldown.NoCooldown) __instance.superTimer = Mathf.MoveTowards(__instance.superTimer, 0f, Time.deltaTime);
                if (__instance.superTimer == 0f) __instance.GetHit();
            }

            return false;
        }


[HarmonyPostfix] [HarmonyPatch(typeof(FlashImage), nameof(FlashImage.Flash))] static void FlashImageTweak(FlashImage __instance)
        {
            if (__instance.gameObject.name.Contains("White") || __instance.gameObject.name.Contains("Black"))
                __instance.transform.localScale *= 20;
        }

/// <summary>
///     Fuck you
/// </summary>


[System.Runtime.InteropServices.DllImport("gdi32.dll")]
        private static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse);


private void OnHeaderButtonClick(object? sender, RoutedEventArgs e)
    {
        // Header button should be hidden in Month mode.
        if (Mode == CalendarViewMode.Month) return;
        if (Mode == CalendarViewMode.Year)
        {
            Mode = CalendarViewMode.Decade;
            var range = DateTimeHelper.GetDecadeViewRangeByYear(ContextDate.Year!.Value);
            _dateContextSyncing = true;
            ContextDate =  ContextDate.With(startYear: range.start, endYear: range.end);
            _dateContextSyncing = false;
            UpdateYearButtons();
            return;
        }

        if (Mode == CalendarViewMode.Decade)
        {
            Mode = CalendarViewMode.Century;
            var range = DateTimeHelper.GetCenturyViewRangeByYear(ContextDate.StartYear!.Value);
            _dateContextSyncing = true;
            ContextDate = ContextDate.With(startYear: range.start, endYear: range.end);
            _dateContextSyncing = false;
            UpdateYearButtons();
        }
    }

/// <summary>
///     Rule:
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>


public static void ApplyAllFigmaEffectsToUnityNode(GameObject nodeGameObject,Node node,
            FigmaImportProcessData figmaImportProcessData)
        {
            foreach (var effect in node.effects) ApplyEffectToUnityNode(nodeGameObject,node,effect,figmaImportProcessData);

        }

/// <summary>
/// Apply all effects to a given node
/// </summary>
/// <param name="nodeGameObject"></param>
/// <param name="node"></param>
/// <param name="figmaImportProcessData"></param>


public void UnparentTarget(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource)
        {
            parent = target.parent;
            Mod.logger.LogInfo($"Unparenting {target.name}, remembering {parent.name}");
            target.SetParent(null, true);
        }

// Unparent Target, so we can finetune the position


public static unsafe BitmapImage ConvertMsResourceToIcon(Uri iconPathUri, string packageFullName)
    {
        try
        {
            var indirectPathToResource = "@{" + packageFullName + "? " + iconPathUri.AbsoluteUri + "}";
            Span<char> outputBuffer = new char[MaxBufferLength];

            fixed (char* outBufferPointer = outputBuffer)
            {
                fixed (char* resourcePathPointer = indirectPathToResource)
                {
                    var res = PInvoke.SHLoadIndirectString(resourcePathPointer, new PWSTR(outBufferPointer), (uint)outputBuffer.Length, null);
                    if (res.Succeeded)
                    {
                        var iconImageLocation = new string(outputBuffer.TrimEnd('\0'));

                        if (File.Exists(iconImageLocation))
                        {
                            var bitmap = new BitmapImage();
                            bitmap.UriSource = new Uri(iconImageLocation);
                            return bitmap;
                        }
                    }

                    Log.Error($"Failed to find icon image in path: {iconPathUri} for package: {packageFullName} due to error: 0x{res.Value:X}");
                }
            }
        }
        catch (Exception ex)
        {
            Log.Error(ex, $"Failed to load icon from ms-resource: {iconPathUri} for package: {packageFullName} due to error:");
        }

        return new BitmapImage();
    }

/// <summary>
/// Converts a passed in ms-resource URI and package full name to a BitmapImage.
/// </summary>
/// <param name="iconPathUri">the ms-resource:// path to an image resource in an app packages pri file.</param>
/// <returns>The bitmap image that represents the icon.</returns>


private bool IsFeaturePresent(ExperimentalFeature experimentalFeature)
    {
        if (string.Equals(experimentalFeature.Id, "FileExplorerSourceControlIntegration", StringComparison.OrdinalIgnoreCase))
        {
            try
            {
                return ExtraFolderPropertiesWrapper.IsSupported();
            }
            catch (Exception)
            {
                return false;
            }
        }

        throw new NotImplementedException();
    }

/// <summary>
/// Checks if the specified experimental feature is present on the machine.
/// This method should be extended to handle new features by adding the corresponding
/// feature check logic. If a feature is supported on the current machine, it should
/// return false here.
/// </summary>


public static T Get<T>()
        where T : ITelemetry
    {
        return (T)(object)GetTelemetryInstance();
    }

/// <summary>
/// Gets a singleton instance of Telemetry
/// This would be useful for the future when interfaces have been updated for logger like ITelemetry2, ITelemetry3 and so on


public IAsyncOperation<ComputeSystemOperationResult> ShutDownAsync(string options) => throw new NotImplementedException();


public static DefaultWait<WindowsDriver<WindowsElement>> Wait(
        this WindowsDriver<WindowsElement> driver,
        TimeSpan timeout,
        TimeSpan pollingInterval)
    {
        return new(driver)
        {
            Timeout = timeout,
            PollingInterval = pollingInterval,
        };
    }

/// <summary>
/// Create an instance of <see cref="DefaultWait{T}"/>
/// </summary>
/// <param name="driver">Driver instance</param>
/// <param name="timeout">Wait timeout</param>
/// <param name="pollingInterval">Action interval</param>
/// <returns>Instance of <see cref="DefaultWait{T}"/></returns>


public static async Task Main(string[] args)
    {
        // We declare for variables which we will use later, ggmlType, modelFileName, wavFileName and coreMlModelcName
        var ggmlType = GgmlType.Base;
        var modelFileName = "ggml-base.bin";
        var wavFileName = "kennedy.wav";
        var coreMlModelcName = "ggml-base-encoder.mlmodelc";

        // This section detects whether the "ggml-base.bin" file exists in our project disk. If it doesn't, it downloads it from the internet
        if (!File.Exists(modelFileName))
        {
            await DownloadModel(modelFileName, ggmlType);
        }

        // This sections detects whether the modelc directory (used by CoreML) is in out project disk. If it doesn't, it downloads it and extract it to the current folder.
        if (!Directory.Exists(coreMlModelcName))
        {
            // Note: The modelc directory needs to be extracted at the same level as the "ggml-base.bin" file (and the current executable).
            await WhisperGgmlDownloader.GetEncoderCoreMLModelAsync(ggmlType)
                                       .ExtractToPath(".");
        }

        // Optional logging from the native library

        using var whisperLogger = LogProvider.AddLogger((level, message) =>
        {
            Console.Write($"{level}: {message}");
        });

        // This section creates the whisperFactory object which is used to create the processor object.
        using var whisperFactory = WhisperFactory.FromPath(modelFileName);

        // This section creates the processor object which is used to process the audio file, it uses language `auto` to detect the language of the audio file.
        using var processor = whisperFactory.CreateBuilder()
            .WithLanguage("auto")
            .Build();

        using var fileStream = File.OpenRead(wavFileName);

        // This section processes the audio file and prints the results (start time, end time and text) to the console.
        await foreach (var result in processor.ProcessAsync(fileStream))
        {
            Console.WriteLine($"{result.Start}->{result.End}: {result.Text}");
        }
    }

// This examples shows how to use Whisper.net to create a transcription from an audio file with 16Khz sample rate, using CoreML


public static async Task Main(string[] args)
    {
        // We declare three variables which we will use later, ggmlType, modelFileName and wavFileName
        var ggmlType = GgmlType.LargeV3Turbo;
        var modelFileName = "ggml-largev3.bin";
        var wavFileName = "kennedy.wav";

        using var whisperLogger = LogProvider.AddConsoleLogging(WhisperLogLevel.Debug);

        // This section detects whether the "ggml-largev3.bin" file exists in our project disk. If it doesn't, it downloads it from the internet
        if (!File.Exists(modelFileName))
        {
            await DownloadModel(modelFileName, ggmlType);
        }

        // This section creates the whisperFactory object which is used to create the processor object.
        using var whisperFactory = WhisperFactory.FromPath(modelFileName);

        // This section creates the processor object which is used to process the audio file, it uses language `auto` to detect the language of the audio file.
        using var processor = whisperFactory.CreateBuilder()
            .WithLanguage("auto")
            .Build();

        using var fileStream = File.OpenRead(wavFileName);

        // This section processes the audio file and prints the results (start time, end time and text) to the console.
        await foreach (var result in processor.ProcessAsync(fileStream))
        {
            Console.WriteLine($"{result.Start}->{result.End}: {result.Text}");
        }
    }

// This examples shows how to use Whisper.net to create a transcription from an audio file with 16Khz sample rate.
// It uses both Cuda (NVidia GPU) or CPU, and loads the first one that is available.


public static string MapPath(this string path)
        {
            return MapPath(path, false);
        }

/// <summary>
/// 返回的路径后面不带/，拼接时需要自己加上/
/// </summary>
/// <param name="path"></param>
/// <returns></returns>


public static void Send(string title, string content, params string[] list)
        {
            Console.WriteLine(AppSetting.GetSection("ModifyMember")["DateUTCField"]);
            MailMessage message = new MailMessage
            {
                From = new MailAddress(address, name)//发送人邮箱
            };
            foreach (var item in list)
            {
                message.To.Add(item);//收件人地址
            }

            message.Subject = title;//发送邮件的标题

            message.Body = content;//发送邮件的内容
            //配置smtp服务地址
            SmtpClient client = new SmtpClient
            {
                Host = host,
                Port = port,//端口587
                EnableSsl = enableSsl,
                //发送人邮箱与授权密码
                Credentials = new NetworkCredential(address, authPwd)
            };
            client.Send(message);
        }

/// <summary>
/// 发送邮件
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">内容</param>
/// <param name="list">收件人</param>


public static void AddProcese<T>(T entity, bool rewrite = false,bool changeTableStatus=true) where T:class
        {
            string workTable = typeof(T).GetEntityTableName();

            Sys_WorkFlow workFlow = DBServerProvider.DbContext.Set<Sys_WorkFlow>()
                .Where(x => x.WorkTable == workTable)
                 .Include(x => x.Sys_WorkFlowStep)
                .FirstOrDefault();

            if (workFlow == null || workFlow.Sys_WorkFlowStep.Count == 0) return;
            //重新生成流程
            if (rewrite)
            {
                Rewrite(entity, workFlow,changeTableStatus);
                return;
            }

            var userInfo = UserContext.Current.UserInfo;
            Guid workFlowTable_Id = Guid.NewGuid();
            Sys_WorkFlowTable workFlowTable = new Sys_WorkFlowTable()
            {
                WorkFlowTable_Id = workFlowTable_Id,
                AuditStatus = (int)AuditStatus.审核中,
                CurrentOrderId = 1,
                Enable = 1,
                WorkFlow_Id = workFlow.WorkFlow_Id,
                WorkName = workFlow.WorkName,
                WorkTable = workTable,
                WorkTableKey = typeof(T).GetKeyProperty().GetValue(entity).ToString(),
                WorkTableName = workFlow.WorkTableName,
                CreateID = userInfo.User_Id,
                CreateDate = DateTime.Now,
                Creator = userInfo.UserTrueName,
                Sys_WorkFlowTableStep = workFlow.Sys_WorkFlowStep.OrderBy(x => x.OrderId).Select(s => new Sys_WorkFlowTableStep()
                {
                    Sys_WorkFlowTableStep_Id = Guid.NewGuid(),
                    WorkFlowTable_Id = workFlowTable_Id,
                    WorkFlow_Id = s.WorkFlow_Id,
                    StepId = s.StepId,
                    StepName = s.StepName,
                    AuditId = s.StepType == (int)AuditType.用户审批 ? s.StepValue : null,
                    StepType = s.StepType,
                    StepValue = s.StepValue,
                    OrderId = s.OrderId,
                    Enable = 1,
                    CreateDate = DateTime.Now,
                }).ToList()
            };
            DBServerProvider.DbContext.Set<Sys_WorkFlowTable>().Add(workFlowTable);
            DBServerProvider.DbContext.SaveChanges();
        }

/// <summary>
/// 写入流程
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <param name="rewrite">是否重新生成流程</param>
/// <param name="changeTableStatus">是否修改原表的审批状态</param>


public void AppendCriteria([NotNull]FilterCriteria criteria)
        {
            if (criteria.FilteringMethod != this.FilteringMethod)
                throw new Exception("The filtering method used is incompatible and may cause problems due to differences in syntax.");

            FilterClauses.AddRange(criteria.FilterClauses);

            foreach (var param in criteria.FilterParameters)
            {
                FilterParameters.Add(param.Key, param.Value);
            }
        }

/// <summary>
/// Copies all the <paramref name="criteria"/>'s FilterClauses and FilterParameters to this
/// FilterCriteria.
/// </summary>
/// <param name="criteria"></param>


public static TAttribute GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<TAttribute>(MemberInfo memberInfo, TAttribute defaultValue = default, bool inherit = true)
            where TAttribute : class
        {
            return memberInfo.GetCustomAttributes(true).OfType<TAttribute>().FirstOrDefault()
                   ?? memberInfo.ReflectedType?.GetTypeInfo().GetCustomAttributes(true).OfType<TAttribute>().FirstOrDefault()
                   ?? defaultValue;
        }

/// <summary>
/// Copied from ABP
/// Tries to gets an of attribute defined for a class member and it's declaring type including inherited attributes.
/// Returns default value if it's not declared at all.
/// </summary>
/// <typeparam name="TAttribute">Type of the attribute</typeparam>
/// <param name="memberInfo">MemberInfo</param>
/// <param name="defaultValue">Default value (null as default)</param>
/// <param name="inherit">Inherit attribute from base classes</param>


public static void ValidateCodeIdentifier(string identifier)
        {
            if (!CSharpSyntaxHelper.IsValidIdentifier(identifier))
                throw new IdentifierIsNotValidException(identifier);
        }

/// <summary>
/// Validate specified <paramref name="identifier"/>, throws <see cref="IdentifierIsNotValidException"/> if identifier is not valid
/// </summary>
/// <param name="identifier"></param>
/// <exception cref="IdentifierIsNotValidException"></exception>


public string GetModuleName(Type migrationType)
        {
            return migrationType.GetConfigurableModuleName();
        }


public override void Up()
        {

            Create.Table("SheshaFunctionalTests_Books")
             .WithIdAsGuid()
             .WithFullAuditColumns()
             .WithColumn("Frwk_Discriminator").AsString(SheshaDatabaseConsts.DiscriminatorMaxSize).NotNullable()
             .WithColumn("Name").AsString().Nullable()
             .WithColumn("Description").AsString().Nullable()
             .WithColumn("Price").AsDecimal();

            Create.Table("SheshaFunctionalTests_Schools")
             .WithIdAsGuid()
             .WithFullAuditColumns()
             .WithColumn("Frwk_Discriminator").AsString(SheshaDatabaseConsts.DiscriminatorMaxSize).NotNullable()
             .WithColumn("Name").AsString().Nullable()
             .WithColumn("Latitude").AsDecimal().Nullable()
             .WithColumn("Longitude").AsDecimal()
             .WithColumn("ContactNumber").AsString().Nullable();

            Create.Table("SheshaFunctionalTests_Subjects")
             .WithIdAsGuid()
             .WithFullAuditColumns()
             .WithColumn("Frwk_Discriminator").AsString(SheshaDatabaseConsts.DiscriminatorMaxSize).NotNullable()
             .WithColumn("Name").AsString().Nullable()
             .WithColumn("Description").AsString().Nullable()
             .WithColumn("Total").AsDecimal().Nullable();

            Alter.Table("SheshaFunctionalTests_Schools").AddForeignKeyColumn("AddressId", "Core_Addresses").Nullable();

            Alter.Table("SheshaFunctionalTests_Schools").AddForeignKeyColumn("HeadLeaderId", "Core_Persons").Nullable();

            Alter.Table("SheshaFunctionalTests_Subjects").AddForeignKeyColumn("BookId", "SheshaFunctionalTests_Books").Nullable();

            Alter.Table("SheshaFunctionalTests_Subjects").AddForeignKeyColumn("SchoolId", "SheshaFunctionalTests_Schools").Nullable();

        }


public override void Up()
        {
            Alter.Table("SheshaFunctionalTests_MembershipPayments").AddColumn("PaymentTypeLkp").AsInt64().Nullable();
        }


public static bool SwappedBrightness()
    {
        return ContainsModel("FA506IEB") || ContainsModel("FA506IH") || ContainsModel("FA506IC") || ContainsModel("FX506LU") || ContainsModel("FX506IC") || ContainsModel("FX506LH") || ContainsModel("FA506IV") || ContainsModel("FA706IC") || ContainsModel("FA706IH");
    }

// Devices with bugged bios command to change brightness


public void LocalAddContinuation(PlayerLoopTiming timing, Action continuation)
        {
            var q = yielders[(int)timing];
            if (q == null)
            {
                ThrowInvalidLoopTiming(timing);
            }
            q.Enqueue(continuation);
        }

// NOTE: Continuation means a asynchronous task invoked by another task after the other task finishes.


public static bool MatchesWeekOfMonth(this DateTime date, int recurrence)
            => Matches(recurrence, 1 << (date.Day / 8));


public static async Task<(string Host, string BaseHost)> IpToHostAsync(string ip)
    {
        string result = string.Empty;
        string baseHost = string.Empty;
        if (!OperatingSystem.IsWindows()) return (result, baseHost);
        if (!await IsInternetAliveByNicAsync()) return (result, baseHost); // nslookup takes time when there is no internet access

        string content = await ProcessManager.ExecuteAsync("nslookup", null, ip, true, true);
        if (string.IsNullOrEmpty(content)) return (result, baseHost);
        content = content.ToLower();
        string[] split = content.Split(Environment.NewLine);
        for (int n = 0; n < split.Length; n++)
        {
            string line = split[n];
            if (line.Contains("name:"))
            {
                result = line.Replace("name:", string.Empty).Trim();
                if (result.Contains('.'))
                {
                    GetHostDetails(result, 0, out _, out _, out baseHost, out _, out _, out _);
                }
                break;
            }
        }

        return (result, baseHost);
    }

/// <summary>
/// IP to Host using Nslookup (Windows Only)
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>


public static async Task<List<string>> Github_Latest_Release_Async(string owner, string repo, int timeoutMs = 5000)
    {
        List<string> relaeseURLs = new();

        try
        {
            Uri apiMain = new($"https://api.github.com/repos/{owner}/{repo}/releases/latest");
            HttpRequest hr = new()
            {
                Method = HttpMethod.Get,
                AllowInsecure = true,
                TimeoutMS = timeoutMs,
                URI = apiMain,
                Headers =
                {
                    { "accept", "application/json" }
                }
            };
            HttpRequestResponse hrr = await HttpRequest.SendAsync(hr).ConfigureAwait(false);
            string json = Encoding.UTF8.GetString(hrr.Data);

            List<JsonTool.JsonPath> path = new()
            {
                new JsonTool.JsonPath() {Key = "assets", Count = 1, Conditions = new()},
                new JsonTool.JsonPath() {Key = "browser_download_url", Conditions = new()}
            };

            relaeseURLs = JsonTool.GetValues(json, path);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("WebAPI Github_Latest_Release_Async: " + ex.Message);
        }

        return relaeseURLs;
    }

/// <summary>
/// Github Latest Release
/// </summary>
/// <returns>Returns Download Links</returns>


public static bool IntersectRayMesh(Ray ray, Mesh mesh, Matrix4x4 matrix, out RaycastHit hit)
        {
            object[] parameters = { ray, mesh, matrix, null };
            bool result = (bool) MethodIntersectRayMesh.Invoke(null, parameters);
            hit = (RaycastHit) parameters[3];
            return result;
        }

// Adapted from https://gist.github.com/MattRix/9205bc62d558fef98045


static void Main(string[] args)
    {
        // if you want to use a different Application Delegate class from "AppDelegate"
        // you can specify it here.
        UIApplication.Main(args, null, typeof(AppDelegate));
    }

// This is the main entry point of the application.


public async Task<ContentDialogResult> ShowAsync() => await ShowAsyncCore(null);

/// <summary>
/// Begins an asynchronous operation to show the dialog.
/// </summary>


internal static byte[] Encode(byte[] dataBytes, int numECBytes, GeneratorPolynomial generatorPoly)
	{
		int dataLength = dataBytes.Length;
        if (generatorPoly == null)
            throw new ArgumentNullException(nameof(generatorPoly));

        if (dataLength == 0)
		{
			throw new ArgumentException("There is no data bytes to encode.");
		}

		if (numECBytes <= 0)
		{
			throw new ArgumentException("No Error Correction bytes.");
		}

		int[] toEncode = ConvertToIntArray(dataBytes, dataLength, numECBytes);

		Polynomial generator = generatorPoly.GetGenerator(numECBytes);

		Polynomial dataPoly = new(generator.GField, toEncode);

		PolyDivideStruct divideResult = dataPoly.Divide(generator);

		int[] remainderCoeffs = divideResult.Remainder.Coefficients;

		return ConvertTosByteArray(remainderCoeffs, numECBytes);
	}

/// <summary>
/// Encode an array of data codeword with GaloisField 256.
/// </summary>
/// <param name="dataBytes">Array of data codewords for a single block.</param>
/// <param name="numECBytes">Number of error correction codewords for data codewords</param>
/// <param name="generatorPoly">Cached or newly create GeneratorPolynomial</param>
/// <returns>Return error correction codewords array</returns>


public static void AppendQuerytoUrl(ref string url, string parameterName, string query) {
            if (query == null) {
                return;
            }
            url += parameterName + "=" + query + "&";
        }

/// <summary>
/// Appends <paramref name="appendix"/> to <paramref name="url"/>.
/// </summary>


private async Task InvokeAgentAsync(OpenAIAssistantAgent agent, string threadId, string input)
    {
        ChatMessageContent message = new(AuthorRole.User, input);
        await agent.AddChatMessageAsync(threadId, message);
        this.WriteAgentChatMessage(message);

        ChatHistory history = [];

        bool isFirst = false;
        bool isCode = false;
        await foreach (StreamingChatMessageContent response in agent.InvokeStreamingAsync(threadId, messages: history))
        {
            if (string.IsNullOrEmpty(response.Content))
            {
                StreamingFunctionCallUpdateContent? functionCall = response.Items.OfType<StreamingFunctionCallUpdateContent>().SingleOrDefault();
                if (functionCall != null)
                {
                    Console.WriteLine($"\n# {response.Role} - {response.AuthorName ?? "*"}: FUNCTION CALL - {functionCall.Name}");
                }

                continue;
            }

            // Differentiate between assistant and tool messages
            if (isCode != (response.Metadata?.ContainsKey(OpenAIAssistantAgent.CodeInterpreterMetadataKey) ?? false))
            {
                isFirst = false;
                isCode = !isCode;
            }

            if (!isFirst)
            {
                Console.WriteLine($"\n# {response.Role} - {response.AuthorName ?? "*"}:");
                isFirst = true;
            }

            Console.WriteLine($"\t > streamed: '{response.Content}'");
        }

        foreach (ChatMessageContent content in history)
        {
            this.WriteAgentChatMessage(content);
        }
    }

// Local function to invoke agent and display the conversation messages.


internal static ChatMessageContent? GetSystemMessage(this IReadOnlyList<ChatMessageContent> chatHistory)
    {
        return chatHistory.FirstOrDefault(m => m.Role == AuthorRole.System);
    }

/// <summary>
/// Returns the system prompt from the chat history.
/// </summary>
/// <remarks>
/// For simplicity only a single system message is supported in these examples.
/// </remarks>


[Fact]
    public async Task AutoFunctionInvocationFilterAsync()
    {
        var builder = Kernel.CreateBuilder();

        builder.AddOpenAIChatCompletion("gpt-4", TestConfiguration.OpenAI.ApiKey);

        // This filter outputs information about auto function invocation and returns overridden result.
        builder.Services.AddSingleton<IAutoFunctionInvocationFilter>(new AutoFunctionInvocationFilter(this.Output));

        var kernel = builder.Build();

        var function = KernelFunctionFactory.CreateFromMethod(() => "Result from function", "MyFunction");

        kernel.ImportPluginFromFunctions("MyPlugin", [function]);

        var executionSettings = new OpenAIPromptExecutionSettings
        {
            FunctionChoiceBehavior = FunctionChoiceBehavior.Required([function], autoInvoke: true)
        };

        var result = await kernel.InvokePromptAsync("Invoke provided function and return result", new(executionSettings));

        Console.WriteLine(result);

        // Output:
        // Request sequence number: 0
        // Function sequence number: 0
        // Total number of functions: 1
        // Result from auto function invocation filter.
    }

/// <summary>
/// Shows how to use <see cref="IAutoFunctionInvocationFilter"/>.
/// </summary>


[Fact]
    public async Task MethodFunctionsChainingAsync()
    {
        Console.WriteLine("Running Method Function Chaining example...");

        var kernel = new Kernel();

        var functions = kernel.ImportPluginFromType<FunctionsChainingPlugin>();

        var customType = await kernel.InvokeAsync<MyCustomType>(functions["Function1"]);

        Console.WriteLine($"CustomType.Number: {customType!.Number}"); // 2
        Console.WriteLine($"CustomType.Text: {customType.Text}"); // From Function1 + From Function2
    }

/// <summary>
/// This example executes Function1, which in turn executes Function2.
/// </summary>


private static IEnumerable<Product> CreateProductRecords()
    {
        yield return new Product
        {
            Key = 1,
            Description = "Premium coffee maker that allows you to make up to 20 types of drinks with one machine.",
            FeatureList = ["Milk Frother", "Easy to use", "One button operation", "Stylish design"]
        };

        yield return new Product
        {
            Key = 2,
            Description = "Value coffee maker that gives you what you need at a good price.",
            FeatureList = ["Simple design", "Easy to clean"]
        };

        yield return new Product
        {
            Key = 3,
            Description = "Efficient vacuum cleaner",
            FeatureList = ["1000W power", "Hard floor tool", "Bagless", "Corded"]
        };

        yield return new Product
        {
            Key = 4,
            Description = "High performance handheld vacuum cleaner",
            FeatureList = ["Pet hair tool", "2000W power", "Hard floor tool", "Bagless", "Cordless"]
        };
    }

/// <summary>
/// Create some sample product records.
/// </summary>
/// <returns>A list of sample product records.</returns>


[KernelFunction, Description("Provides a list of specials from the menu.")]
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Too smart")]
    public string[] GetSpecials(KernelArguments? arguments)
    {
        return
            [
                "Special Soup: Clam Chowder",
                "Special Salad: Cobb Salad",
                "Special Drink: Chai Tea",
            ];
    }

/// <summary>
/// Returns a mock item menu.
/// </summary>


[Fact]
    public async Task ObservabilityWithFiltersAsync()
    {
        // Create a kernel with OpenAI chat completion
        IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
        kernelBuilder.AddOpenAIChatCompletion(
                modelId: TestConfiguration.OpenAI.ChatModelId,
                apiKey: TestConfiguration.OpenAI.ApiKey);

        kernelBuilder.Plugins.AddFromType<TimeInformation>();

        // Add filter using DI
        kernelBuilder.Services.AddSingleton<ITestOutputHelper>(this.Output);
        kernelBuilder.Services.AddSingleton<IFunctionInvocationFilter, MyFunctionFilter>();

        Kernel kernel = kernelBuilder.Build();

        // Add filter without DI
        kernel.PromptRenderFilters.Add(new MyPromptFilter(this.Output));

        // Invoke the kernel with a prompt and allow the AI to automatically invoke functions
        OpenAIPromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
        Console.WriteLine(await kernel.InvokePromptAsync("How many days until Christmas? Explain your thinking.", new(settings)));
    }

/// <summary>
/// Shows how to observe the execution of a <see cref="KernelPlugin"/> instance with filters.
/// </summary>


public string? ReadLine()
    {
        if (SimulatedInputTextIndex < SimulatedInputText.Count)
        {
            return SimulatedInputText[SimulatedInputTextIndex++];
        }

        return null;
    }

/// <summary>
/// Simulates reading input strings from a user for the purpose of running tests.
/// </summary>
/// <returns>A simulate user input string, if available. Null otherwise.</returns>


protected override async Task ReceiveAsync(IEnumerable<ChatMessageContent> history, CancellationToken cancellationToken)
    {
        foreach (ChatMessageContent message in history)
        {
            await AssistantThreadActions.CreateMessageAsync(this._client, this._threadId, message, cancellationToken).ConfigureAwait(false);
        }
    }


[LoggerMessage(
        EventId = 0,
        Level = LogLevel.Debug,
        Message = "[{MethodName}] Creating assistant thread for {ChannelType}.")]
    public static partial void LogOpenAIAssistantAgentCreatingChannel(
        this ILogger logger,
        string methodName,
        string channelType);

/// <summary>
/// Logs <see cref="OpenAIAssistantAgent"/> creating channel (started).
/// </summary>


[Fact]
    public void VerifyAssistantMessageAdapterCreateOptionsDefault()
    {
        // Arrange (Setup message with null metadata)
        ChatMessageContent message = new(AuthorRole.User, "test");

        // Act: Create options
        MessageCreationOptions options = AssistantMessageFactory.CreateOptions(message);

        // Assert
        Assert.NotNull(options);
        Assert.Empty(options.Metadata);
    }

/// <summary>
/// Verify options creation.
/// </summary>


public static IServiceCollection AddHuggingFaceTextGeneration(
        this IServiceCollection services,
        string model,
        Uri? endpoint = null,
        string? apiKey = null,
        string? serviceId = null,
        HttpClient? httpClient = null)
    {
        Verify.NotNull(services);

        return services.AddKeyedSingleton<ITextGenerationService>(serviceId, (serviceProvider, _) =>
            new HuggingFaceTextGenerationService(
                model,
                endpoint,
                apiKey,
                HttpClientProvider.GetHttpClient(httpClient, serviceProvider),
                serviceProvider.GetService<ILoggerFactory>()));
    }

/// <summary>
/// Adds an Hugging Face text generation service with the specified configuration.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> instance to augment.</param>
/// <param name="model">The name of the Hugging Face model.</param>
/// <param name="endpoint">The endpoint URL for the text generation service.</param>
/// <param name="apiKey">The API key required for accessing the Hugging Face service.</param>
/// <param name="serviceId">A local identifier for the given AI service.</param>
/// <param name="httpClient">The HttpClient to use with this service.</param>
/// <returns>The same instance as <paramref name="services"/>.</returns>


public static IServiceCollection AddPineconeVectorStore(this IServiceCollection services, PineconeVectorStoreOptions? options = default, string? serviceId = default)
    {
        // If we are not constructing the PineconeClient, add the IVectorStore as transient, since we
        // cannot make assumptions about how PineconeClient is being managed.
        services.AddKeyedTransient<IVectorStore>(
            serviceId,
            (sp, obj) =>
            {
                var pineconeClient = sp.GetRequiredService<Sdk.PineconeClient>();
                var selectedOptions = options ?? sp.GetService<PineconeVectorStoreOptions>();

                return new PineconeVectorStore(
                    pineconeClient,
                    selectedOptions);
            });

        return services;
    }

/// <summary>
/// Register a Pinecone <see cref="IVectorStore"/> with the specified service ID and where <see cref="Sdk.PineconeClient"/> is retrieved from the dependency injection container.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to register the <see cref="IVectorStore"/> on.</param>
/// <param name="options">Optional options to further configure the <see cref="IVectorStore"/>.</param>
/// <param name="serviceId">An optional service id to use as the service key.</param>
/// <returns>The service collection.</returns>


public static async IAsyncEnumerable<T> WrapAsyncEnumerableAsync<T>(IAsyncEnumerable<T> asyncEnumerable, string operationName, string? collectionName = null)
    {
        var enumerator = asyncEnumerable.ConfigureAwait(false).GetAsyncEnumerator();

        var nextResult = await GetNextAsync<T>(enumerator, operationName, collectionName).ConfigureAwait(false);
        while (nextResult.more)
        {
            yield return nextResult.item;
            nextResult = await GetNextAsync(enumerator, operationName, collectionName).ConfigureAwait(false);
        }
    }

/// <summary>
/// Wraps an <see cref="IAsyncEnumerable{T}"/> in an <see cref="IAsyncEnumerable{T}"/> that will throw a <see cref="VectorStoreOperationException"/>
/// if an exception is thrown while iterating over the original enumerator.
/// </summary>
/// <typeparam name="T">The type of the items in the async enumerable.</typeparam>
/// <param name="asyncEnumerable">The async enumerable to wrap.</param>
/// <param name="operationName">The name of the operation being performed.</param>
/// <param name="collectionName">The name of the collection being operated on.</param>
/// <returns>An async enumerable that will throw a <see cref="VectorStoreOperationException"/> if an exception is thrown while iterating over the original enumerator.</returns>


public static WeaviateCollectionSchema MapToSchema(
        string collectionName,
        IEnumerable<VectorStoreRecordDataProperty> dataProperties,
        IEnumerable<VectorStoreRecordVectorProperty> vectorProperties,
        IReadOnlyDictionary<string, string> storagePropertyNames)
    {
        var schema = new WeaviateCollectionSchema(collectionName);

        // Handle data properties.
        foreach (var property in dataProperties)
        {
            schema.Properties.Add(new WeaviateCollectionSchemaProperty
            {
                Name = storagePropertyNames[property.DataModelPropertyName],
                DataType = [MapType(property.PropertyType)],
                IndexFilterable = property.IsFilterable,
                IndexSearchable = property.IsFullTextSearchable
            });
        }

        // Handle vector properties.
        foreach (var property in vectorProperties)
        {
            var vectorPropertyName = storagePropertyNames[property.DataModelPropertyName];
            schema.VectorConfigurations.Add(vectorPropertyName, new WeaviateCollectionSchemaVectorConfig
            {
                VectorIndexType = MapIndexKind(property.IndexKind, vectorPropertyName),
                VectorIndexConfig = new WeaviateCollectionSchemaVectorIndexConfig
                {
                    Distance = MapDistanceFunction(property.DistanceFunction, vectorPropertyName)
                }
            });
        }

        return schema;
    }

/// <summary>
/// Maps record type properties to Weaviate collection schema for collection creation.
/// </summary>
/// <param name="collectionName">The name of the vector store collection.</param>
/// <param name="dataProperties">Collection of record data properties.</param>
/// <param name="vectorProperties">Collection of record vector properties.</param>
/// <param name="storagePropertyNames">A dictionary that maps from a property name to the storage name that should be used when serializing it to JSON for data and vector properties.</param>
/// <returns>Weaviate collection schema.</returns>


[RequiresUnreferencedCode("This method uses reflection to serialize and deserialize the execution settings, making it incompatible with AOT scenarios.")]
    [RequiresDynamicCode("This method uses reflection to serialize and deserialize the execution settings, making it incompatible with AOT scenarios.")]
    public static OnnxRuntimeGenAIPromptExecutionSettings FromExecutionSettings(PromptExecutionSettings? executionSettings)
    {
        if (executionSettings is null)
        {
            return new OnnxRuntimeGenAIPromptExecutionSettings();
        }

        if (executionSettings is OnnxRuntimeGenAIPromptExecutionSettings settings)
        {
            return settings;
        }

        var json = JsonSerializer.Serialize(executionSettings, executionSettings.GetType());

        return JsonSerializer.Deserialize<OnnxRuntimeGenAIPromptExecutionSettings>(json, JsonOptionsCache.ReadPermissive)!;
    }

/// <summary>
/// Convert PromptExecutionSettings to OnnxRuntimeGenAIPromptExecutionSettings
/// </summary>
/// <param name="executionSettings">The <see cref="PromptExecutionSettings"/> to convert to <see cref="OnnxRuntimeGenAIPromptExecutionSettings"/>.</param>
/// <returns>Returns the <see cref="OnnxRuntimeGenAIPromptExecutionSettings"/> object.</returns>


[Fact]
    public void CanCreateCollectionWithMismatchedDefinitionAndType()
    {
        // Arrange.
        var definition = new VectorStoreRecordDefinition()
        {
            Properties = new List<VectorStoreRecordProperty>
            {
                new VectorStoreRecordKeyProperty("Id", typeof(ulong)),
                new VectorStoreRecordDataProperty("Text", typeof(string)),
                new VectorStoreRecordVectorProperty("Embedding", typeof(ReadOnlyMemory<float>)) { Dimensions = 4 },
            }
        };

        // Act.
        var sut = new QdrantVectorStoreRecordCollection<SinglePropsModel<ulong>>(
            this._qdrantClientMock.Object,
            TestCollectionName,
            new() { VectorStoreRecordDefinition = definition, PointStructCustomMapper = Mock.Of<IVectorStoreRecordMapper<SinglePropsModel<ulong>, PointStruct>>() });
    }

/// <summary>
/// Tests that the collection can be created even if the definition and the type do not match.
/// In this case, the expectation is that a custom mapper will be provided to map between the
/// schema as defined by the definition and the different data model.
/// </summary>


internal static void SetMaxTokens(this PromptTemplateConfig config, int maxTokens)
    {
        var executionSettings = config.ExecutionSettings;
        foreach (var setting in executionSettings)
        {
            if (setting.Value.ExtensionData is not null)
            {
                setting.Value.ExtensionData["max_tokens"] = maxTokens;
            }
        }
    }

/// <summary>
/// Set the max_tokens request setting to be used by OpenAI models
/// </summary>
/// <param name="config">PromptTemplateConfig instance</param>
/// <param name="maxTokens">Value of max tokens to set</param>


public static async Task<DaprKernelProcessContext> StartAsync(this KernelProcess process, KernelProcessEvent initialEvent, string? processId = null)
    {
        Verify.NotNull(process);
        Verify.NotNullOrWhiteSpace(process.State?.Name);
        Verify.NotNull(initialEvent);

        // Assign the process Id if one is provided and the processes does not already have an Id.
        if (!string.IsNullOrWhiteSpace(processId) && string.IsNullOrWhiteSpace(process.State.Id))
        {
            process = process with { State = process.State with { Id = processId } };
        }

        DaprKernelProcessContext processContext = new(process);
        await processContext.StartWithEventAsync(initialEvent).ConfigureAwait(false);
        return processContext;
    }

/// <summary>
/// Starts the specified process.
/// </summary>
/// <param name="process">Required: The <see cref="KernelProcess"/> to start running.</param>
/// <param name="initialEvent">Required: The initial event to start the process.</param>
/// <param name="processId">Optional: Used to specify the unique Id of the process. If the process already has an Id, it will not be overwritten and this parameter has no effect.</param>
/// <returns>An instance of <see cref="KernelProcess"/> that can be used to interrogate or stop the running process.</returns>


public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
    {
        this._output.WriteLine(state?.ToString());
    }


[Theory(Skip = "OpenAI will often throttle requests. This test is for manual verification.")]
    [InlineData(false)]
    [InlineData(true)]
    public async Task OpenAIMixedAgentTestAsync(bool useNewFunctionCallingModel)
    {
        OpenAIConfiguration openAISettings = this._configuration.GetSection("OpenAI").Get<OpenAIConfiguration>()!;
        Assert.NotNull(openAISettings);

        // Arrange, Act & Assert
        await this.VerifyAgentExecutionAsync(
            this.CreateChatCompletionKernel(openAISettings),
            OpenAIClientProvider.ForOpenAI(new ApiKeyCredential(openAISettings.ApiKey)),
            openAISettings.ChatModelId!,
            useNewFunctionCallingModel);
    }

/// <summary>
/// Integration test for <see cref="OpenAIAssistantAgent"/> using function calling
/// and targeting Open AI services.
/// </summary>


public override Task<ITextSearch> CreateTextSearchAsync()
    {
        if (this.VectorStore is null)
        {
            this.EmbeddingGenerator = fixture.EmbeddingGenerator;
            this.VectorStore = new QdrantVectorStore(fixture.QdrantClient);
        }

        var options = new QdrantVectorStoreRecordCollectionOptions<HotelInfo>
        {
            HasNamedVectors = true,
            VectorStoreRecordDefinition = fixture.HotelVectorStoreRecordDefinition,
        };
        var vectorSearch = new QdrantVectorStoreRecordCollection<HotelInfo>(fixture.QdrantClient, "namedVectorsHotels", options);
        var stringMapper = new HotelInfoTextSearchStringMapper();
        var resultMapper = new HotelInfoTextSearchResultMapper();

        var result = new VectorStoreTextSearch<HotelInfo>(vectorSearch, this.EmbeddingGenerator!, stringMapper, resultMapper);
        return Task.FromResult<ITextSearch>(result);
    }


public static HttpOperationException ToHttpOperationException(this ClientResultException exception)
    {
        const int NoResponseReceived = 0;

        string? responseContent = null;

        try
        {
            responseContent = exception.GetRawResponse()?.Content.ToString();
        }
#pragma warning disable CA1031 // Do not catch general exception types
        catch { } // We want to suppress any exceptions that occur while reading the content, ensuring that an HttpOperationException is thrown instead.
#pragma warning restore CA1031

        return new HttpOperationException(
            exception.Status == NoResponseReceived ? null : (HttpStatusCode?)exception.Status,
            responseContent,
            exception.Message,
            exception);
    }

/// <summary>
/// Converts a <see cref="ClientResultException"/> to an <see cref="HttpOperationException"/>.
/// </summary>
/// <param name="exception">The original <see cref="ClientResultException"/>.</param>
/// <returns>An <see cref="HttpOperationException"/> instance.</returns>


public static KernelProcessStateMetadata KernelProcessToProcessStateMetadata(KernelProcess kernelProcess)
    {
        KernelProcessStateMetadata metadata = new()
        {
            Name = kernelProcess.State.Name,
            Id = kernelProcess.State.Id,
            VersionInfo = kernelProcess.State.Version,
            StepsState = [],
        };

        foreach (KernelProcessStepInfo step in kernelProcess.Steps)
        {
            metadata.StepsState.Add(step.State.Name, step.ToProcessStateMetadata());
        }

        return metadata;
    }

/// <summary>
/// Captures Kernel Process State into <see cref="KernelProcessStateMetadata"/>
/// </summary>
/// <returns><see cref="KernelProcessStateMetadata"/></returns>


[MethodImpl(MethodImplOptions.AggressiveInlining)]
    internal static void NotNull([NotNull] object? obj, [CallerArgumentExpression(nameof(obj))] string? paramName = null)
    {
#if NET
        ArgumentNullException.ThrowIfNull(obj, paramName);
#else
        if (obj is null)
        {
            ThrowArgumentNullException(paramName);
        }
#endif
    }

/// <summary>
/// Equivalent of ArgumentNullException.ThrowIfNull
/// </summary>


[KernelFunction, Description("Adds an amount to a value")]
    [return: Description("The sum")]
    public int Add(
        [Description("The value to add")] int value,
        [Description("Amount to add")] int amount) =>
        value + amount;

/// <summary>
/// Returns the addition result of initial and amount values provided.
/// </summary>
/// <param name="value">Initial value to which to add the specified amount.</param>
/// <param name="amount">The amount to add as a string.</param>
/// <returns>The resulting sum as a string.</returns>


public TextSearchResult MapFromResultToTextSearchResult(object result)
        {
            if (result is not global::Google.Apis.CustomSearchAPI.v1.Data.Result googleResult)
            {
                throw new ArgumentException("Result must be a Google Result", nameof(result));
            }

            return new TextSearchResult(googleResult.Snippet) { Name = googleResult.Title, Link = googleResult.Link };
        }


public static async Task<TextContent> GetTextContentAsync(
        this ITextGenerationService textGenerationService,
        string prompt,
        PromptExecutionSettings? executionSettings = null,
        Kernel? kernel = null,
        CancellationToken cancellationToken = default)
        => (await textGenerationService.GetTextContentsAsync(prompt, executionSettings, kernel, cancellationToken).ConfigureAwait(false))
            .Single();

/// <summary>
/// Get a single text generation result for the prompt and settings.
/// </summary>
/// <param name="textGenerationService">Text generation service</param>
/// <param name="prompt">The standardized prompt input.</param>
/// <param name="executionSettings">The AI execution settings (optional).</param>
/// <param name="kernel">The <see cref="Kernel"/> containing services, plugins, and other state for use throughout the operation.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>Single text content generated by the remote model.</returns>


public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
    }


public static IPromptTemplate Create(this IPromptTemplateFactory factory, PromptTemplateConfig templateConfig)
    {
        Verify.NotNull(factory);
        Verify.NotNull(templateConfig);

        if (!factory.TryCreate(templateConfig, out IPromptTemplate? result))
        {
            throw new KernelException($"Prompt template format {templateConfig.TemplateFormat} is not supported.");
        }

        return result;
    }

/// <summary>
/// Creates an instance of <see cref="IPromptTemplate"/> from a <see cref="PromptTemplateConfig"/>.
/// </summary>
/// <param name="factory">The factory with which to create the template.</param>
/// <param name="templateConfig">Prompt template configuration</param>
/// <returns>The created template.</returns>
/// <exception cref="KernelException">The factory does not support the specified configuration.</exception>


public static bool HasExactly<TSource>(this IEnumerable<TSource> source, int count)
    {
        if (source is null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        if (source is ICollection<TSource> collectionoft)
        {
            return collectionoft.Count == count;
        }

        if (source is ICollection collection)
        {
            return collection.Count == count;
        }

        using var enumerator = source.GetEnumerator();
        while (count-- > 0)
        {
            if (!enumerator.MoveNext())
            {
                return false;
            }
        }

        return !enumerator.MoveNext();
    }


protected override void BuildTargetModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("ProductVersion", "8.0.0-preview.6.23329.4")
                .HasAnnotation("Relational:MaxIdentifierLength", 128);

            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole<int>", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));

                    b.Property<string>("ConcurrencyStamp")
                        .IsConcurrencyToken()
                        .HasColumnType("nvarchar(max)");

                    b.Property<string>("Name")
                        .HasMaxLength(256)
                        .HasColumnType("nvarchar(256)");

                    b.Property<string>("NormalizedName")
                        .HasMaxLength(256)
                        .HasColumnType("nvarchar(256)");

                    b.HasKey("Id");

                    b.HasIndex("NormalizedName")
                        .IsUnique()
                        .HasDatabaseName("RoleNameIndex")
                        .HasFilter("[NormalizedName] IS NOT NULL");

                    b.ToTable("AspNetRoles", (string)null);
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));

                    b.Property<string>("ClaimType")
                        .HasColumnType("nvarchar(max)");

                    b.Property<string>("ClaimValue")
                        .HasColumnType("nvarchar(max)");

                    b.Property<int>("RoleId")
                        .HasColumnType("int");

                    b.HasKey("Id");

                    b.HasIndex("RoleId");

                    b.ToTable("AspNetRoleClaims", (string)null);
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser<int>", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));

                    b.Property<int>("AccessFailedCount")
                        .HasColumnType("int");

                    b.Property<string>("ConcurrencyStamp")
                        .IsConcurrencyToken()
                        .HasColumnType("nvarchar(max)");

                    b.Property<string>("Email")
                        .HasMaxLength(256)
                        .HasColumnType("nvarchar(256)");

                    b.Property<bool>("EmailConfirmed")
                        .HasColumnType("bit");

                    b.Property<bool>("LockoutEnabled")
                        .HasColumnType("bit");

                    b.Property<DateTimeOffset?>("LockoutEnd")
                        .HasColumnType("datetimeoffset");

                    b.Property<string>("NormalizedEmail")
                        .HasMaxLength(256)
                        .HasColumnType("nvarchar(256)");

                    b.Property<string>("NormalizedUserName")
                        .HasMaxLength(256)
                        .HasColumnType("nvarchar(256)");

                    b.Property<string>("PasswordHash")
                        .HasColumnType("nvarchar(max)");

                    b.Property<string>("PhoneNumber")
                        .HasColumnType("nvarchar(max)");

                    b.Property<bool>("PhoneNumberConfirmed")
                        .HasColumnType("bit");

                    b.Property<string>("SecurityStamp")
                        .HasColumnType("nvarchar(max)");

                    b.Property<bool>("TwoFactorEnabled")
                        .HasColumnType("bit");

                    b.Property<string>("UserName")
                        .HasMaxLength(256)
                        .HasColumnType("nvarchar(256)");

                    b.HasKey("Id");

                    b.HasIndex("NormalizedEmail")
                        .HasDatabaseName("EmailIndex");

                    b.HasIndex("NormalizedUserName")
                        .IsUnique()
                        .HasDatabaseName("UserNameIndex")
                        .HasFilter("[NormalizedUserName] IS NOT NULL");

                    b.ToTable("AspNetUsers", (string)null);
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));

                    b.Property<string>("ClaimType")
                        .HasColumnType("nvarchar(max)");

                    b.Property<string>("ClaimValue")
                        .HasColumnType("nvarchar(max)");

                    b.Property<int>("UserId")
                        .HasColumnType("int");

                    b.HasKey("Id");

                    b.HasIndex("UserId");

                    b.ToTable("AspNetUserClaims", (string)null);
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
                {
                    b.Property<string>("LoginProvider")
                        .HasColumnType("nvarchar(450)");

                    b.Property<string>("ProviderKey")
                        .HasColumnType("nvarchar(450)");

                    b.Property<string>("ProviderDisplayName")
                        .HasColumnType("nvarchar(max)");

                    b.Property<int>("UserId")
                        .HasColumnType("int");

                    b.HasKey("LoginProvider", "ProviderKey");

                    b.HasIndex("UserId");

                    b.ToTable("AspNetUserLogins", (string)null);
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<int>", b =>
                {
                    b.Property<int>("UserId")
                        .HasColumnType("int");

                    b.Property<int>("RoleId")
                        .HasColumnType("int");

                    b.HasKey("UserId", "RoleId");

                    b.HasIndex("RoleId");

                    b.ToTable("AspNetUserRoles", (string)null);
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
                {
                    b.Property<int>("UserId")
                        .HasColumnType("int");

                    b.Property<string>("LoginProvider")
                        .HasColumnType("nvarchar(450)");

                    b.Property<string>("Name")
                        .HasColumnType("nvarchar(450)");

                    b.Property<string>("Value")
                        .HasColumnType("nvarchar(max)");

                    b.HasKey("UserId", "LoginProvider", "Name");

                    b.ToTable("AspNetUserTokens", (string)null);
                });

            modelBuilder.Entity("PackagesManagementDB.Models.Destination", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));

                    b.Property<string>("Country")
                        .IsRequired()
                        .HasMaxLength(128)
                        .HasColumnType("nvarchar(128)");

                    b.Property<string>("Description")
                        .HasColumnType("nvarchar(max)");

                    b.Property<string>("Name")
                        .IsRequired()
                        .HasMaxLength(128)
                        .HasColumnType("nvarchar(128)");

                    b.HasKey("Id");

                    b.HasIndex("Country");

                    b.HasIndex("Name");

                    b.ToTable("Destinations");
                });

            modelBuilder.Entity("PackagesManagementDB.Models.Package", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));

                    b.Property<string>("Description")
                        .HasMaxLength(128)
                        .HasColumnType("nvarchar(128)");

                    b.Property<int>("DestinationId")
                        .HasColumnType("int");

                    b.Property<int>("DurationInDays")
                        .HasColumnType("int");

                    b.Property<DateTime?>("EndValidityDate")
                        .HasColumnType("datetime2");

                    b.Property<long>("EntityVersion")
                        .IsConcurrencyToken()
                        .HasColumnType("bigint");

                    b.Property<string>("Name")
                        .IsRequired()
                        .HasMaxLength(128)
                        .HasColumnType("nvarchar(128)");

                    b.Property<decimal>("Price")
                        .HasColumnType("decimal(18,2)");

                    b.Property<DateTime?>("StartValidityDate")
                        .HasColumnType("datetime2");

                    b.HasKey("Id");

                    b.HasIndex("DestinationId");

                    b.HasIndex("Name");

                    b.HasIndex("StartValidityDate", "EndValidityDate");

                    b.ToTable("Packages");
                });

            modelBuilder.Entity("PackagesManagementDB.Models.PackageEvent", b =>
                {
                    b.Property<long>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("bigint");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Id"));

                    b.Property<decimal>("NewPrice")
                        .HasColumnType("decimal(18,2)");

                    b.Property<long?>("NewVersion")
                        .HasColumnType("bigint");

                    b.Property<long?>("OldVersion")
                        .HasColumnType("bigint");

                    b.Property<int>("PackageId")
                        .HasColumnType("int");

                    b.Property<int>("Type")
                        .HasColumnType("int");

                    b.HasKey("Id");

                    b.ToTable("PackageEvents");
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
                {
                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole<int>", null)
                        .WithMany()
                        .HasForeignKey("RoleId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
                {
                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser<int>", null)
                        .WithMany()
                        .HasForeignKey("UserId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
                {
                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser<int>", null)
                        .WithMany()
                        .HasForeignKey("UserId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<int>", b =>
                {
                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole<int>", null)
                        .WithMany()
                        .HasForeignKey("RoleId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();

                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser<int>", null)
                        .WithMany()
                        .HasForeignKey("UserId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                });

            modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
                {
                    b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser<int>", null)
                        .WithMany()
                        .HasForeignKey("UserId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();
                });

            modelBuilder.Entity("PackagesManagementDB.Models.Package", b =>
                {
                    b.HasOne("PackagesManagementDB.Models.Destination", "MyDestination")
                        .WithMany("Packages")
                        .HasForeignKey("DestinationId")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();

                    b.Navigation("MyDestination");
                });

            modelBuilder.Entity("PackagesManagementDB.Models.Destination", b =>
                {
                    b.Navigation("Packages");
                });
#pragma warning restore 612, 618
        }


[Benchmark]
        public void DynamicCallDotnetMethod()
        {
            _jsFunctionCallMethodDynamic.CallAsStatic(_jsHost);
        }


public void Unref()
        {
            _portRef.Run((port) => port.CallMethod("unref"));
        }


public static TEnum[] GetValues<TEnum>()
        where TEnum : struct, Enum
    {
#if NETCOREAPPX || NETFRAMEWORK || NETSTANDARD
        var values = Enum.GetValues(typeof(TEnum));
        var result = new TEnum[values.Length];
        Array.Copy(values, result, values.Length);
        return result;
#else
        return Enum.GetValues<TEnum>();
#endif
    }


public static async Task<Stream> GetStreamAsync(
        this HttpClient target,
        string requestUri,
        CancellationToken cancellationToken = default)
    {
        try
        {
            // Must not be disposed for the stream to be usable
            var response = await target.GetAsync(
                requestUri,
                HttpCompletionOption.ResponseHeadersRead,
                cancellationToken
            ).ConfigureAwait(false);

            response.EnsureSuccessStatusCode();

            return await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
        }
        // Older versions of HttpClient methods don't propagate the cancellation token inside the exception
        catch (OperationCanceledException ex) when (
            ex.CancellationToken != cancellationToken &&
            cancellationToken.IsCancellationRequested)
        {
            throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken);
        }
    }


public static Task SaveAsync(
        this XDocument target,
        XmlWriter writer,
        CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();
        target.Save(writer);
        return Task.CompletedTask;
    }


public static bool IsOSPlatform(string platform) =>
#if NET5_0_OR_GREATER
        OperatingSystem.IsOSPlatform(platform);
#else
        RuntimeInformation.IsOSPlatform(OSPlatform.Create(platform));
#endif

    /// <summary>
    /// Checks if the operating system version is greater than or equal to the specified platform version. This method can be used to guard APIs that were added in the specified OS version.
    /// </summary>
    /// <param name="platform">The case-insensitive platform name. Examples: Browser, Linux, FreeBSD, Android, iOS, macOS, tvOS, watchOS, Windows.</param>
    /// <param name="major">The major release number.</param>
    /// <param name="minor">The minor release number (optional).</param>
    /// <param name="build">The build release number (optional).</param>
    /// <param name="revision">The revision release number (optional).</param>
    /// <returns>true if the current application is running on the specified platform and is at least in the version specified in the parameters; false otherwise.</returns>
    ///Link: https://learn.microsoft.com/en-us/dotnet/api/system.operatingsystem.isosplatformversionatleast


public static bool TryParse(string? target, IFormatProvider? provider, out uint result) =>
#if NET7_0_OR_GREATER
        uint.TryParse(target, provider, out result);
#else
        uint.TryParse(target, NumberStyles.Integer, provider, out result);
#endif


public override void ReadXml(XmlNode node)
        {
            base.ReadXml(node);
            fValue = Xml.GetChildFloatAttribute(node, "fValue", "value");
        }


public override void ReadXml(XmlNode node)
        {
            base.ReadXml(node);
            pExtraBoneIds = Xml.GetChildRawIntArray(node, "pExtraBoneIds");
        }

// PsoDataType.Array, 40, 0, (MetaName)3)//ARRAYINFO, PsoDataType.SInt, 0, 0, 0),