Update comments to reflect that native double support is supported on the latest server.

--- AerospikeClient/Main/Bin.cs
+++ AerospikeClient/Main/Bin.cs
@@ -86,10 +86,13 @@

 		/// <summary>
 		/// Constructor, specifying bin name and double value.
-		/// The server does not support double, so the value is converted to long bits. On reads,
-		/// it's important to call <see cref="Aerospike.Client.Record.GetDouble(string)"/> to
-		/// indicate that the long returned by the server should be converted back to a double.
-		/// <para>
+		/// Aerospike server versions >= 3.5.15 natively support floating point values.  If your cluster
+		/// supports floating point values, then this is always the correct constructor for double.
+		/// Remember to also set <see cref="Aerospike.Client.Value.UseDoubleType"/> to true;
+		/// <para>
+		/// If your cluster does not support floating point, the value is converted to long bits.
+		/// On reads, it's important to call <see cref="Aerospike.Client.Record.GetDouble(string)"/>
+		/// to indicate that the long returned by the server should be converted back to a double.
 		/// If the same bin name holds different types for different records, then this constructor
 		/// should not be used because there is no way to know when reading if the long should be
 		/// converted to a double.  Instead, use <see cref="Aerospike.Client.Bin(string, object)"/>
@@ -117,10 +120,13 @@

 		/// <summary>
 		/// Constructor, specifying bin name and float value.
-		/// The server does not support float, so the value is converted to long bits. On reads,
-		/// it's important to call <see cref="Aerospike.Client.Record.GetFloat(string)"/> to
-		/// indicate that the long returned by the server should be converted back to a float.
-		/// <para>
+		/// Aerospike server versions >= 3.5.15 natively support floating point values.  If your cluster
+		/// supports floating point values, then this is always the correct constructor for float.
+		/// Remember to also set <see cref="Aerospike.Client.Value.UseDoubleType"/> to true;
+		/// <para>
+		/// If your cluster does not support floating point, the value is converted to long bits.
+		/// On reads, it's important to call <see cref="Aerospike.Client.Record.GetFloat(string)"/>
+		/// to indicate that the long returned by the server should be converted back to a float.
 		/// If the same bin name holds different types for different records, then this constructor
 		/// should not be used because there is no way to know when reading if the long should be
 		/// converted to a float.  Instead, use <see cref="Aerospike.Client.Bin(string, object)"/>


Make private fields readonly

Make private fields readonly

--- AhoCorasick/CharComparer.cs
+++ AhoCorasick/CharComparer.cs
@@ -8,7 +8,7 @@
 {
     class OrdinalCharComparer : CharComparer
     {
-        private bool _ignoreCase;
+        private readonly bool _ignoreCase;

         public OrdinalCharComparer(bool ignoreCase = false)
         {
@@ -30,7 +30,7 @@
 #if NET40
     class CultureCharComparer : CharComparer
     {
-        private StringComparer _stringComparer;
+        private readonly StringComparer _stringComparer;

         public CultureCharComparer(CultureInfo cultureInfo, bool ignoreCase = false)
         {
@@ -50,8 +50,8 @@
 #else
     class CultureCharComparer: CharComparer
     {
-        private CompareInfo _compareInfo;
-        private bool _ignoreCase;
+        private readonly CompareInfo _compareInfo;
+        private readonly bool _ignoreCase;

         public CultureCharComparer(CultureInfo cultureInfo, bool ignoreCase = false)
         {


Adding debug info for location and adapter .net framework  #786

--- src/NUnitTestAdapter/NUnitTestAdapter.cs
+++ src/NUnitTestAdapter/NUnitTestAdapter.cs
@@ -141,6 +141,16 @@
                 TestLog.Warning("Error initializing RunSettings. Default settings will be used");
                 TestLog.Warning(e.ToString());
             }
+            finally
+            {
+#if NET35
+                string fw = "Net Framework";
+#else
+                string fw = "Net Core";
+#endif
+                var assLoc = Assembly.GetExecutingAssembly().Location;
+                TestLog.Debug($"{fw} adapter running from {assLoc}");
+            }
         }

         public void InitializeForbiddenFolders()
@@ -306,6 +316,6 @@
             NUnitEngineAdapter = null;
         }

-        #endregion
+#endregion
     }
 }


fixed some strings, thx xnaas, closes #1093

--- src/NadekoBot/Modules/Utility/Utility.cs
+++ src/NadekoBot/Modules/Utility/Utility.cs
@@ -273,7 +273,7 @@
         [NadekoCommand, Usage, Description, Aliases]
         public async Task ChannelId()
         {
-            await ReplyConfirmLocalized("channelidd", "🆔", Format.Code(Context.Channel.Id.ToString()))
+            await ReplyConfirmLocalized("channelid", "🆔", Format.Code(Context.Channel.Id.ToString()))
                 .ConfigureAwait(false);
         }

@@ -439,7 +439,7 @@
             var result = string.Join("\n", tags.Select(m => GetText("showemojis", m, m.Url)));

             if (string.IsNullOrWhiteSpace(result))
-                await ReplyErrorLocalized("emojis_none").ConfigureAwait(false);
+                await ReplyErrorLocalized("showemojis_none").ConfigureAwait(false);
             else
                 await Context.Channel.SendMessageAsync(result).ConfigureAwait(false);
         }


Update Utility.cs

Update Utility.cs

--- src/NadekoBot/Modules/Utility/Utility.cs
+++ src/NadekoBot/Modules/Utility/Utility.cs
@@ -222,7 +222,8 @@
                         },

                     },
-                    Color = 0x00bbd6, 0xA8F307
+                    Color = 0x00bbd6
+                    Color = 0xA8F307
                 });
         }


Style refactoring

Style refactoring

- Fix typos in the parameter/method names.
- Rename private member to "_" prefix style.

--- Source/Controller.cs
+++ Source/Controller.cs
@@ -300,38 +300,38 @@
   }

   /// Vessel which is currently hovered.
-  Vessel hoveredVessel;
+  Vessel _hoveredVessel;

   /// Overaly window to show info about vessel under the mouse cursor.
-  HintOverlay mouseInfoOverlay;
+  HintOverlay _mouseInfoOverlay;

   /// Old vessel context.
-  VesselInfo oldInfo;
+  VesselInfo _oldInfo;

   /// New vessel context.
-  VesselInfo newInfo;
+  VesselInfo _newInfo;

   /// Defines if currently selected vessel was a result of EVS mouse click event.
-  bool evsSwitchAction;
+  bool _evsSwitchAction;

   /// Event to handle in the controller.
   /// <remarks>
   /// Controller code reacts to anything different from <see cref="SwitchEvent.Idle"/>. Once the
   /// event is handled it's reset to the default.
   /// </remarks>
-  SwitchEvent state = SwitchEvent.Idle;
+  SwitchEvent _state = SwitchEvent.Idle;

   /// Specifies if hovered vessel is attached to the ground.
   /// <remarks><c>null</c> means no static attachable parts found.</remarks>
-  bool? isKisStaticAttached;
+  bool? _isKisStaticAttached;

   /// If hovered vessel is a kerbal then this will be the component.
   /// <remarks><c>null</c> means hovered vessel is not a kerbal.</remarks>
-  KerbalEVA kerbalEva;
+  KerbalEVA _kerbalEva;

   /// Part that is currently hovered when EVS mode is enabled.
   /// <remarks>Used to determine part's focus change.</remarks>
-  Part lastHoveredPart;
+  Part _lastHoveredPart;

   /// Tells if the vessel highlighting logic should be presented.
   /// <remarks><c>true</c> if the hovered or selected vessel should be highlighted.</remarks>
@@ -340,9 +340,7 @@
   /// <c>0</c>, then no visual appearance will happen anyways. So don't event trigger the logic to
   /// not affect the part renderer states.
   /// </remarks>
-  bool isHighlighingEnabled {
-    get { return !Mathf.Approximately(targetVesselHighlightColor.a, 0); }
-  }
+  bool isHighlightingEnabled => !Mathf.Approximately(targetVesselHighlightColor.a, 0);
   #endregion

   #region MonoBehaviour methods
@@ -353,7 +351,7 @@
     GameEvents.onVesselChange.Add(OnVesselChange);
     GameEvents.onPartCouple.Add(OnPartCouple);
     ConfigAccessor.ReadFieldsInType(typeof(Controller), this);
-    mouseInfoOverlay = new HintOverlay(
+    _mouseInfoOverlay = new HintOverlay(
         infoOverlayFontSize, infoOverlayHintPadding, infoOverlayTextColor, infoOverlayBackgroundColor);

     // Drop vessel selection when main modifier is released.
@@ -377,24 +375,24 @@
       HandleVesselSelection();
     }
     if (partFocusSwitchKey.Update()) {
-      HanleCameraFocusSelection();
+      HandleCameraFocusSelection();
     }

     // Core KSP logic highlights hovered parts. Once focus is lost so does the highlight state on
     // the part. Here we detect changing focus in scope of the current vessel, and restore EVS
     // highlighting when mouse focus moves out.
-    if (hoveredVessel == null) {
-      lastHoveredPart = null;
-    } else if (lastHoveredPart != Mouse.HoveredPart) {
-      if (lastHoveredPart != null && lastHoveredPart.vessel == hoveredVessel) {
+    if (_hoveredVessel == null) {
+      _lastHoveredPart = null;
+    } else if (_lastHoveredPart != Mouse.HoveredPart) {
+      if (_lastHoveredPart != null && _lastHoveredPart.vessel == _hoveredVessel) {
         // Let game core to disable highlighter and then restore it.
-        var restoreHighlightPart = lastHoveredPart; // Make a cope for the delayed call.
-        if (isHighlighingEnabled) {
+        var restoreHighlightPart = _lastHoveredPart; // Make a cope for the delayed call.
+        if (isHighlightingEnabled) {
           AsyncCall.CallOnEndOfFrame(
               this, () => restoreHighlightPart.highlighter.ConstantOn(targetVesselHighlightColor));
         }
       }
-      lastHoveredPart = Mouse.HoveredPart;
+      _lastHoveredPart = Mouse.HoveredPart;
     }
   }

@@ -407,13 +405,13 @@
   /// </para>
   /// </remarks>
   void LateUpdate() {
-    if (state == SwitchEvent.VesselDocked) {
-      state = SwitchEvent.Idle;
+    if (_state == SwitchEvent.VesselDocked) {
+      _state = SwitchEvent.Idle;
       Debug.Log("Setting camera pivot to the new CoM.");
       var camera = FlightCamera.fetch;
-      camera.GetPivot().position = oldInfo.cameraPivotPos;
-      camera.SetCamCoordsFromPosition(oldInfo.cameraPos);
-      camera.GetCameraTransform().position = oldInfo.cameraPos;
+      camera.GetPivot().position = _oldInfo.cameraPivotPos;
+      camera.SetCamCoordsFromPosition(_oldInfo.cameraPos);
+      camera.GetCameraTransform().position = _oldInfo.cameraPos;

       StartCoroutine(TimedHighlightCoroutine(
           FlightGlobals.ActiveVessel, newVesselHighlightTimeout, targetVesselHighlightColor,
@@ -426,7 +424,7 @@
   /// Overridden from MonoBehaviour.
   /// <remarks>Persents hovered vessel info.</remarks>
   public void OnGUI() {
-    if (hoveredVessel != null) {
+    if (_hoveredVessel != null) {
       ShowHoveredVesselInfo();
     }
     if (partFocusSwitchKey.isHold) {
@@ -448,13 +446,13 @@
   void OnPartCouple(GameEvents.FromToAction<Part, Part> action) {
     // Only do camera fix if either the source or the destination is an active vessel.
     if (action.from.vessel.isActiveVessel) {
-      state = SwitchEvent.VesselDocked;
+      _state = SwitchEvent.VesselDocked;
       Debug.Log("Active vessel docked to a station. Waiting for LateUpdate...");
-      oldInfo = new VesselInfo(action.from.vessel, FlightCamera.fetch);
+      _oldInfo = new VesselInfo(action.from.vessel, FlightCamera.fetch);
     } else if (action.to.vessel.isActiveVessel) {
-      state = SwitchEvent.VesselDocked;
+      _state = SwitchEvent.VesselDocked;
       Debug.Log("Something has docked to the active vessel. Waiting for LateUpdate...");
-      oldInfo = new VesselInfo(action.to.vessel, FlightCamera.fetch);
+      _oldInfo = new VesselInfo(action.to.vessel, FlightCamera.fetch);
     }
   }

@@ -466,13 +464,13 @@
   /// <param name="fromVessel">A vessel prior the switch.</param>
   /// <param name="toVessel">A new active vessel.</param>
   void OnVesselSwitch(Vessel fromVessel, Vessel toVessel) {
-    if (state == SwitchEvent.Idle && cameraStabilizationMode != CameraStabilization.None
+    if (_state == SwitchEvent.Idle && cameraStabilizationMode != CameraStabilization.None
         && fromVessel != null && fromVessel.isActiveVessel) {
-      state = SwitchEvent.VesselSwitched;
+      _state = SwitchEvent.VesselSwitched;
       Debug.LogFormat(
           "Detected switch from {0} to {1}. Request camera stabilization.", fromVessel, toVessel);
-      newInfo = new VesselInfo(toVessel);
-      oldInfo = new VesselInfo(fromVessel, FlightCamera.fetch);
+      _newInfo = new VesselInfo(toVessel);
+      _oldInfo = new VesselInfo(fromVessel, FlightCamera.fetch);
     }
   }

@@ -481,80 +479,76 @@
   /// <param name="vessel">A new active vessel.</param>
   void OnVesselChange(Vessel vessel) {
     // Temporarily highlight the new vessel.
-    if (state == SwitchEvent.VesselSwitched || state == SwitchEvent.Idle) {
+    if (_state == SwitchEvent.VesselSwitched || _state == SwitchEvent.Idle) {
       StartCoroutine(TimedHighlightCoroutine(
           vessel, newVesselHighlightTimeout, targetVesselHighlightColor));
     }

-    if (state != SwitchEvent.VesselSwitched) {
+    if (_state != SwitchEvent.VesselSwitched) {
       return;
     }
-    state = SwitchEvent.Idle;
+    _state = SwitchEvent.Idle;

     var camera = FlightCamera.fetch;
-    newInfo.UpdateCameraFrom(camera);
+    _newInfo.UpdateCameraFrom(camera);
     // Camera position cannot be transitioned between any modes. Some modes (e.g. LOCKED) don't
-    // allow the camera to be placed at any place. Don't do camera stablization or
+    // allow the camera to be placed at any place. Don't do camera stabilization or
     // aligning for such modes. In the modes that allow free camera position the transformations
     // can be very different so, just copy source mode into the target vessel.
     // TODO(ihsoft): Find a way to do the translation between different modes.
-    if (Vector3.Distance(oldInfo.anchorPos, newInfo.anchorPos) > maxVesselDistance) {
+    if (Vector3.Distance(_oldInfo.anchorPos, _newInfo.anchorPos) > maxVesselDistance) {
       // On the distant vessels respect camera modes of the both vessels. If either of them is not
       // "free" then just fallback to the default behavior (restore latest known position).
-      if (IsFreeCameraPositionMode(oldInfo.cameraMode)
-          && IsFreeCameraPositionMode(newInfo.cameraMode)) {
-        SetCurrentCameraMode(oldInfo.cameraMode);  // Sync modes to match transformations.
+      if (IsFreeCameraPositionMode(_oldInfo.cameraMode)
+          && IsFreeCameraPositionMode(_newInfo.cameraMode)) {
+        SetCurrentCameraMode(_oldInfo.cameraMode);  // Sync modes to match transformations.
         AlignCamera();
       }
     } else {
       // On close vessels if source mode is "free" then substitute target mode with it. Only do so
       // when mouse select is used (i.e. it's an explicit EVS action). Fallback to the default
-      // behavior if it was an implicit switch (via a KSP hotkey) and the traget mode is not
+      // behavior if it was an implicit switch (via a KSP hotkey) and the target mode is not
       // "free".
-      if (IsFreeCameraPositionMode(oldInfo.cameraMode)
-          && (evsSwitchAction || IsFreeCameraPositionMode(newInfo.cameraMode))) {
-        SetCurrentCameraMode(oldInfo.cameraMode);  // Sync modes to match transformations.
+      if (IsFreeCameraPositionMode(_oldInfo.cameraMode)
+          && (_evsSwitchAction || IsFreeCameraPositionMode(_newInfo.cameraMode))) {
+        SetCurrentCameraMode(_oldInfo.cameraMode);  // Sync modes to match transformations.
         StabilizeCamera();
       }
     }
-    evsSwitchAction = false;
+    _evsSwitchAction = false;
   }

   /// Handles vessel selection logic.
   void HandleVesselSelection() {
     // Highlight focused vessel.
-    if (Mouse.HoveredPart) {
-      SetHoveredVessel(Mouse.HoveredPart.vessel);
-    } else {
-      SetHoveredVessel(null);  // Cancel highlight.
-    }
+    SetHoveredVessel(Mouse.HoveredPart? Mouse.HoveredPart.vessel : null);

     // Select vessel if clicked.
     if (Mouse.GetAllMouseButtonsDown() == switchMouseButton
-        && hoveredVessel != null && !hoveredVessel.isActiveVessel) {
-      if (hoveredVessel.DiscoveryInfo.Level != DiscoveryLevels.Owned) {
+        && _hoveredVessel != null && !_hoveredVessel.isActiveVessel) {
+      if (_hoveredVessel.DiscoveryInfo.Level != DiscoveryLevels.Owned) {
         // Cannot switch to unowned vessel. Invoke standard "soft" switch to have error message
         // triggered.
-        FlightGlobals.SetActiveVessel(hoveredVessel);
+        FlightGlobals.SetActiveVessel(_hoveredVessel);
       } else {
         // Use forced version since "soft" switch blocks on many normal situations (e.g. "on
         // ladder" or "in atmosphere").
-        var vesselToSelect = hoveredVessel;  // Save hovered vessel as it'll be reset on blur.
+        var vesselToSelect = _hoveredVessel;  // Save hovered vessel as it'll be reset on blur.
         SetHoveredVessel(null);
-        evsSwitchAction = true;
+        _evsSwitchAction = true;
         FlightGlobals.ForceSetActiveVessel(vesselToSelect);
       }
     }
   }

   /// Handles camera focus selection logic.
-  void HanleCameraFocusSelection() {
+  void HandleCameraFocusSelection() {
     var camera = FlightCamera.fetch;
     var targetPart = Mouse.HoveredPart;
     var targetTransform = targetPart != null ? targetPart.transform : null;
     if (Mouse.GetAllMouseButtonsDown() == switchMouseButton && targetTransform != camera.Target) {
       if (targetPart != null) {
-        oldInfo = VesselInfo.CaptureCurrentState();
+        _oldInfo = VesselInfo.CaptureCurrentState();
         if (targetPart.vessel == FlightGlobals.ActiveVessel
             && targetPart.vessel.parts.Count == 1) {
           // When moving focus back to a single part vessel reset to the vessel mode.
@@ -562,12 +556,12 @@
         } else {
           camera.SetTargetPart(Mouse.HoveredPart);
         }
-        newInfo = VesselInfo.CaptureCurrentState();
+        _newInfo = VesselInfo.CaptureCurrentState();
         StabilizeCamera();
       } else {
-        oldInfo = VesselInfo.CaptureCurrentState();
+        _oldInfo = VesselInfo.CaptureCurrentState();
         camera.TargetActiveVessel();
-        newInfo = VesselInfo.CaptureCurrentState();
+        _newInfo = VesselInfo.CaptureCurrentState();
         StabilizeCamera();
       }
     }
@@ -579,24 +573,24 @@
   /// new vessels are on the same line of view.
   /// </remarks>
   void AlignCamera() {
-    var oldCameraDistance = Vector3.Distance(oldInfo.cameraPos, oldInfo.cameraPivotPos);
-    var fromOldToNewDir = oldInfo.cameraPivotPos - newInfo.cameraPivotPos;
+    var oldCameraDistance = Vector3.Distance(_oldInfo.cameraPos, _oldInfo.cameraPivotPos);
+    var fromOldToNewDir = _oldInfo.cameraPivotPos - _newInfo.cameraPivotPos;

     Vector3 newCameraPos;
     if (FlightGlobals.ActiveVessel.Landed) {
       // When vessel is landed the new camera position may end up under the surface. To work it
       // around keep the same angle between line of sight and vessel's up axis as it was with the
       // previous vessel.
-      var oldPivotUp = FlightGlobals.getUpAxis(oldInfo.cameraPivotPos);
-      var oldCameraDir = oldInfo.cameraPivotPos - oldInfo.cameraPos;
+      var oldPivotUp = FlightGlobals.getUpAxis(_oldInfo.cameraPivotPos);
+      var oldCameraDir = _oldInfo.cameraPivotPos - _oldInfo.cameraPos;
       var angle = Vector3.Angle(oldPivotUp, oldCameraDir);
-      var newPivotUp = FlightGlobals.getUpAxis(newInfo.cameraPivotPos);
+      var newPivotUp = FlightGlobals.getUpAxis(_newInfo.cameraPivotPos);
       var rot = Quaternion.AngleAxis(angle, Vector3.Cross(newPivotUp, fromOldToNewDir));
-      newCameraPos = newInfo.cameraPivotPos - rot * (newPivotUp * oldCameraDistance);
+      newCameraPos = _newInfo.cameraPivotPos - rot * (newPivotUp * oldCameraDistance);
     } else {
       // In space just put camera on the opposite side and direct it to the old vessel. This way
-      // both old and new vessela will be in camera's field of view.
-      newCameraPos = newInfo.cameraPivotPos - fromOldToNewDir.normalized * oldCameraDistance;
+      // both old and new vessels will be in camera's field of view.
+      newCameraPos = _newInfo.cameraPivotPos - fromOldToNewDir.normalized * oldCameraDistance;
     }

     var camera = FlightCamera.fetch;
@@ -617,13 +611,13 @@
       // Then, either animate the pivot or set it instantly. KSP code will move the camera
       // following the pivot without changing its rotation or distance.
       Debug.Log("Fix camera position while keeping distance and orientation");
-      camera.GetPivot().position = oldInfo.cameraPivotPos;
-      camera.SetCamCoordsFromPosition(oldInfo.cameraPos);
+      camera.GetPivot().position = _oldInfo.cameraPivotPos;
+      camera.SetCamCoordsFromPosition(_oldInfo.cameraPos);
       if (cameraStabilizationAnimationDuration < float.Epsilon) {
-        camera.GetPivot().position = newInfo.cameraPivotPos;
+        camera.GetPivot().position = _newInfo.cameraPivotPos;
       } else {
         StartCoroutine(AnimateCameraPositionCoroutine(
-            camera.Target, oldInfo, newInfo, cameraStabilizationAnimationDuration));
+            camera.Target, _oldInfo, _newInfo, cameraStabilizationAnimationDuration));
       }
     }

@@ -634,11 +628,11 @@
       // and reset the camera position to have only direction recalculated.
       Debug.Log("Fix camera focus while keeping its position");
       if (cameraStabilizationAnimationDuration < float.Epsilon) {
-        camera.SetCamCoordsFromPosition(oldInfo.cameraPos);
-        camera.GetCameraTransform().position = oldInfo.cameraPos;
+        camera.SetCamCoordsFromPosition(_oldInfo.cameraPos);
+        camera.GetCameraTransform().position = _oldInfo.cameraPos;
       } else {
         StartCoroutine(AnimateCameraPivotCoroutine(
-            camera.Target, oldInfo, newInfo, cameraStabilizationAnimationDuration));
+            camera.Target, _oldInfo, _newInfo, cameraStabilizationAnimationDuration));
       }
     }
   }
@@ -650,18 +644,18 @@
   /// </remarks>
   /// <param name="vessel">A vessel to set as current.</param>
   void SetHoveredVessel(Vessel vessel) {
-    if (vessel != hoveredVessel) {
-      if (hoveredVessel != null) {
-        SetVesselHighlight(hoveredVessel, null);
-        isKisStaticAttached = null;
-        kerbalEva = null;
+    if (vessel != _hoveredVessel) {
+      if (_hoveredVessel != null) {
+        SetVesselHighlight(_hoveredVessel, null);
+        _isKisStaticAttached = null;
+        _kerbalEva = null;
       }
       if (vessel != null) {
         SetVesselHighlight(vessel, targetVesselHighlightColor);
-        isKisStaticAttached = IsAttachedToGround(vessel.rootPart);
-        kerbalEva = vessel.GetComponent<KerbalEVA>();
-      }
-      hoveredVessel = vessel;
+        _isKisStaticAttached = IsAttachedToGround(vessel.rootPart);
+        _kerbalEva = vessel.GetComponent<KerbalEVA>();
+      }
+      _hoveredVessel = vessel;
     }
   }

@@ -673,7 +667,7 @@
     var trgPart = Mouse.HoveredPart;
     if (trgPart != null) {
       if (camera.Target == trgPart.transform) {
-        sb.Add(CurrenPartInFocusStatusMsg);
+        sb.Add(CurrentPartInFocusStatusMsg);
         sb.Add(AnotherPartFocusHintMsg);
       } else {
         sb.Add(SetFocusToCurrentPartHintMsg.Format(
@@ -694,49 +688,50 @@
         sb.Add(SomePartFocusHintMsg);
       }
     }
-    mouseInfoOverlay.text = string.Join("\n", sb.ToArray());
-    mouseInfoOverlay.ShowAtCursor();
+    _mouseInfoOverlay.text = string.Join("\n", sb.ToArray());
+    _mouseInfoOverlay.ShowAtCursor();
   }

   /// Displays brief information about the vessel under mouse cursor.
   /// <remarks>
   /// It's called every frame so, don't put heavy code here. If focus change needs heavy processing
   /// do it in <see cref="SetHoveredVessel"/>.
-  /// <para><see cref="hoveredVessel"/> must not be <c>null</c>.</para>
+  /// <para><see cref="_hoveredVessel"/> must not be <c>null</c>.</para>
   /// </remarks>
   void ShowHoveredVesselInfo() {
-    var sb = new List<string>();
-    sb.Add(hoveredVessel.isActiveVessel
-        ? CurrentVesselMsg.Format()
-        : SwitchToMsg.Format(MouseButtonLookup.Lookup(switchMouseButton)));
-    sb.Add("");
+    var sb = new List<string> {
+        _hoveredVessel.isActiveVessel
+            ? CurrentVesselMsg.Format()
+            : SwitchToMsg.Format(MouseButtonLookup.Lookup(switchMouseButton)),
+        ""
+    };

     // Give a hint when distance is too long.
-    float distanceBetweenVessels = Vector3.Distance(
-        FlightGlobals.ActiveVessel.transform.position, hoveredVessel.transform.position);
+    var distanceBetweenVessels = Vector3.Distance(
+        FlightGlobals.ActiveVessel.transform.position, _hoveredVessel.transform.position);
     if (distanceBetweenVessels > maxVesselDistance) {
       sb.Add(DistantVesselTargetedMsg.Format(distanceBetweenVessels));
     }

-    if (kerbalEva != null) {
-      var protoCrewMember = hoveredVessel.GetVesselCrew()[0];
-      sb.Add(KerbalTitleMsg.Format(hoveredVessel.GetName(),
+    if (_kerbalEva != null) {
+      var protoCrewMember = _hoveredVessel.GetVesselCrew()[0];
+      sb.Add(KerbalTitleMsg.Format(_hoveredVessel.GetName(),
                                    protoCrewMember.experienceTrait.Title,
                                    protoCrewMember.experienceLevel));
-      sb.Add(KerbalEvaFuelMsg.Format(kerbalEva.Fuel));
+      sb.Add(KerbalEvaFuelMsg.Format(_kerbalEva.Fuel));
     } else {
-      sb.Add(GetShortVesselTitle(hoveredVessel));
-      sb.Add(VesselMassMsg.Format(hoveredVessel.GetTotalMass()));
-      sb.Add(hoveredVessel.IsControllable ? VesselIsControllableMsg : VesselIsNotControllableMsg);
-      if (isKisStaticAttached.HasValue) {
-        sb.Add(isKisStaticAttached.Value
+      sb.Add(GetShortVesselTitle(_hoveredVessel));
+      sb.Add(VesselMassMsg.Format(_hoveredVessel.GetTotalMass()));
+      sb.Add(_hoveredVessel.IsControllable ? VesselIsControllableMsg : VesselIsNotControllableMsg);
+      if (_isKisStaticAttached.HasValue) {
+        sb.Add(_isKisStaticAttached.Value
             ? VesselIsAttachedToTheGroundMsg
             : VesselIsNotAttachedToTheGroundMsg);
       }
     }

-    mouseInfoOverlay.text = string.Join("\n", sb.ToArray());
-    mouseInfoOverlay.ShowAtCursor();
+    _mouseInfoOverlay.text = string.Join("\n", sb.ToArray());
+    _mouseInfoOverlay.ShowAtCursor();
   }

   ///
@@ -792,7 +787,7 @@
   /// cancelled.
   /// </param>
   void SetVesselHighlight(Vessel vessel, Color? color) {
-    if (isHighlighingEnabled) {
+    if (isHighlightingEnabled) {
       foreach (var part in vessel.parts) {
         if (part == Mouse.HoveredPart) {
           continue;  // KSP core highlights hovered part with own color.
@@ -860,16 +855,16 @@
   /// <param name="target">A camera target. If it's changed the animation will abort.</param>
   /// <param name="oldInfo">Previous vessel info.</param>
   /// <param name="newInfo">New vessel info.</param>
-  /// <param name="trasitionDuration">The duration to play the transition animation.</param>
+  /// <param name="transitionDuration">The duration to play the transition animation.</param>
   /// <returns><c>null</c> until the animation is done or aborted.</returns>
   IEnumerator AnimateCameraPivotCoroutine(
-      Transform target, VesselInfo oldInfo, VesselInfo newInfo, float trasitionDuration) {
+      Transform target, VesselInfo oldInfo, VesselInfo newInfo, float transitionDuration) {
     float startTime = Time.unscaledTime;
     float progress;
     do {
       // Calculate vessel movement compensation offset.
       var movementOffset = FlightGlobals.ActiveVessel.transform.position - newInfo.anchorPos;
-      progress = (Time.unscaledTime - startTime) / trasitionDuration;
+      progress = (Time.unscaledTime - startTime) / transitionDuration;
       var camera = FlightCamera.fetch;
       camera.GetPivot().position =
           movementOffset + Vector3.Lerp(oldInfo.cameraPivotPos, newInfo.cameraPivotPos, progress);
@@ -892,17 +887,17 @@
   /// <param name="target">The camera target. If it's changed then the animation will abort.</param>
   /// <param name="oldInfo">The previous vessel info.</param>
   /// <param name="newInfo">The new vessel info.</param>
-  /// <param name="trasitionDuration">The duration to play the transition animation.</param>
+  /// <param name="transitionDuration">The duration to play the transition animation.</param>
   /// <returns><c>null</c> until the animation is done or aborted.</returns>
   IEnumerator AnimateCameraPositionCoroutine(
-      Transform target, VesselInfo oldInfo, VesselInfo newInfo, float trasitionDuration) {
+      Transform target, VesselInfo oldInfo, VesselInfo newInfo, float transitionDuration) {
     float startTime = Time.unscaledTime;
     float progress;
     do {
       // Calculate vessel movement compensation offset.
       var movementOffset = FlightGlobals.ActiveVessel.transform.position - newInfo.anchorPos;
-      progress = (Time.unscaledTime - startTime) / trasitionDuration;
-      // Only animate the pivot position. The camera's position will be adjusted by the FlighCamera
+      progress = (Time.unscaledTime - startTime) / transitionDuration;
+      // Only animate the pivot position. The camera's position will be adjusted by the FlightCamera
       // code.
       FlightCamera.fetch.GetPivot().transform.position =
           movementOffset + Vector3.Lerp(oldInfo.cameraPivotPos, newInfo.cameraPivotPos, progress);


everything it its right place

everything it its right place

--- Source/DMContract.cs
+++ Source/DMContract.cs
@@ -80,10 +80,9 @@
 			{
 				Debug.Log("[DM] Acceptable Science Subject Found");
 				sub.subjectValue = DMModuleScienceAnimate.fixSubjectValue(targetSituation, sub.subjectValue, 1f, body);
-			}
-
-			if (sub.scientificValue < 0.4f)
-				return false;
+				if (sub.scientificValue < 0.4f)
+					return false;
+			}

 			if (DMscience.agent != "Any")
 				this.agent = Contracts.Agents.AgentList.Instance.GetAgent(DMscience.agent);


Modified CookieBasedSessions initialization stage

--- src/Nancy/Session/CookieBasedSessions.cs
+++ src/Nancy/Session/CookieBasedSessions.cs
@@ -66,7 +66,7 @@
         {
             var sessionStore = new CookieBasedSessions(cryptographyConfiguration.EncryptionProvider, cryptographyConfiguration.HmacProvider, new DefaultObjectSerializer());

-            pipelines.BeforeRequest.AddItemToEndOfPipeline(ctx => LoadSession(ctx, sessionStore));
+            pipelines.BeforeRequest.AddItemToStartOfPipeline(ctx => LoadSession(ctx, sessionStore));
             pipelines.AfterRequest.AddItemToEndOfPipeline(ctx => SaveSession(ctx, sessionStore));

             return sessionStore;


Xbox shell now handles no-chrome pages correctly.

--- src/Neptunium/View/XboxShellView.xaml.cs
+++ src/Neptunium/View/XboxShellView.xaml.cs
@@ -1,4 +1,5 @@
 using Crystal3.Navigation;
+using Neptunium.Core.UI;
 using Neptunium.Glue;
 using Neptunium.ViewModel;
 using Neptunium.ViewModel.Dialog;
@@ -6,6 +7,7 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Reflection;
 using System.Runtime.InteropServices.WindowsRuntime;
 using Windows.Foundation;
 using Windows.Foundation.Collections;
@@ -35,6 +37,7 @@
             SplitViewNavigationList.SetBinding(ItemsControl.ItemsSourceProperty, NepApp.CreateBinding(NepApp.UI, nameof(NepApp.UI.NavigationItems)));
             inlineNavigationService = WindowManager.GetNavigationManagerForCurrentWindow().RegisterFrameAsNavigationService(InlineFrame, FrameLevel.Two);
             NepApp.UI.SetNavigationService(inlineNavigationService);
+            inlineNavigationService.Navigated += InlineNavigationService_Navigated;

             NepApp.UI.SetOverlayParent(OverlayPanel);

@@ -49,6 +52,29 @@
             NepApp.Media.IsPlayingChanged += Media_IsPlayingChanged;
         }

+        private bool isInNoChromeMode = false;
+        private void InlineNavigationService_Navigated(object sender, CrystalNavigationEventArgs e)
+        {
+            if (inlineNavigationService.NavigationFrame.Content?.GetType().GetTypeInfo().GetCustomAttribute<NepAppUINoChromePageAttribute>() != null)
+            {
+                //no chrome mode
+                RootSplitView.DisplayMode = SplitViewDisplayMode.Overlay;
+                RootSplitView.IsPaneOpen = false;
+                MediaGrid.Visibility = Visibility.Collapsed;
+                isInNoChromeMode = true;
+            }
+            else
+            {
+                //reactivate chrome
+
+                RootSplitView.DisplayMode = SplitViewDisplayMode.CompactInline;
+
+                if (NepApp.Media.IsPlaying)
+                    MediaGrid.Visibility = Visibility.Visible;
+
+                isInNoChromeMode = false;
+            }
+        }

         private void Overlay_DialogShown(object sender, EventArgs e)
         {
@@ -110,6 +136,7 @@
             if (e.Key == Windows.System.VirtualKey.GamepadY)
             {
                 if (NepApp.UI.Overlay.IsDialogVisible) return;
+                if (isInNoChromeMode) return;

                 if (TransportControlGrid.Visibility == Visibility.Collapsed)
                 {
@@ -139,6 +166,7 @@
             else if (e.Key == Windows.System.VirtualKey.GamepadMenu)
             {
                 if (NepApp.UI.Overlay.IsDialogVisible) return;
+                if (isInNoChromeMode) return;

                 e.Handled = true;
                 RootSplitView.IsPaneOpen = !RootSplitView.IsPaneOpen;


fixed menu input

fixed menu input

--- Source/InputState.cs
+++ Source/InputState.cs
@@ -407,7 +407,7 @@
 			return
 				IsNewKeyPress(Keys.Up) ||
 				IsNewButtonPress(Buttons.DPadUp, controllingPlayer, out playerIndex) ||
-				IsNewButtonPress(Buttons.LeftThumbstickDown, controllingPlayer, out playerIndex);
+				IsNewButtonPress(Buttons.LeftThumbstickUp, controllingPlayer, out playerIndex);
 		}

 		/// <summary>
@@ -422,7 +422,7 @@
 			return
 				IsNewKeyPress(Keys.Down) ||
 				IsNewButtonPress(Buttons.DPadDown, controllingPlayer, out playerIndex) ||
-				IsNewButtonPress(Buttons.LeftThumbstickUp, controllingPlayer, out playerIndex);
+				IsNewButtonPress(Buttons.LeftThumbstickDown, controllingPlayer, out playerIndex);
 		}

 		/// <summary>


implicit autoload in runtime

implicit autoload in runtime

autoload classes even no spl autoloader is registered
- in empty context and empty web context, any class gets autoloaded,
- otherwise; only classes in classmap or psr map

--- src/Peachpie.Runtime/Context.Autoload.cs
+++ src/Peachpie.Runtime/Context.Autoload.cs
@@ -115,12 +115,7 @@
         /// </summary>
         PhpTypeInfo? ImplicitAutoloadTypeByName(string fullName)
         {
-            if (EnableImplicitAutoload)
-            {
-                return AutoloadByTypeNameFromClassMap(fullName, onlyAllowed: false);
-            }
-
-            return null;
+            return AutoloadByTypeNameFromClassMap(fullName, onlyAllowed: !EnableImplicitAutoload);
         }

         /// <summary>


Add new ClearColorValue constructor taking r, g, b, a.

--- Src/CommandBuffer.cs
+++ Src/CommandBuffer.cs
@@ -1963,6 +1963,18 @@
         {
             UInt4 = value;
         }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ClearColorValue"/> structure.
+        /// </summary>
+        /// <param name="r">The red clear value.</param>
+        /// <param name="g">The green clear value.</param>
+        /// <param name="b">The blue clear value.</param>
+        /// <param name="a">The alpha clear value.</param>
+        public ClearColorValue(float r, float g, float b, float a = 1.0f) : this()
+        {
+            Float4 = new ColorF4(r, g, b, a);
+        }
     }

     /// <summary>


Added explanation for using FluentApi .Include()

--- Services/BookService.cs
+++ Services/BookService.cs
@@ -6,6 +6,9 @@

 // Explicit joins of entities is taken from here:
 // https://weblogs.asp.net/jeff/ef7-rc-navigation-properties-and-lazy-loading
+// At the time of committing 5da65e093a64d7165178ef47d5c21e8eeb9ae1fc, Entity
+// Framework Core had no built in support for Lazy Loading, so the above was
+// used on all DbSet queries.

 namespace dwCheckApi.Services
 {
@@ -53,4 +56,4 @@
                 .OrderBy(book => book.BookOrdinal);
         }
     }
-}+}


Separate twitter updates (for 140 characters limit)

--- Shanghai/HealthCheck.cs
+++ Shanghai/HealthCheck.cs
@@ -15,28 +15,35 @@

         public void Proc(TaskServer server, string taskName)
         {
-            var msg = new StringBuilder("[Health Check]\n");
+            {
+                var msg = new StringBuilder("[Health Check]\n");

-            msg.AppendFormat("CPU Temp: {0:F3}\n", GetCpuTemp());
+                msg.AppendFormat("CPU Temp: {0:F3}\n", GetCpuTemp());

-            List<CpuUsage> cpuUsage = GetCpuUsage(server.CancelToken);
-            cpuUsage.ForEach((usage) =>
+                List<CpuUsage> cpuUsage = GetCpuUsage(server.CancelToken);
+                cpuUsage.ForEach((usage) =>
+                {
+                    msg.AppendFormat("{0}:{1:F1}% ", usage.Name, usage.UsagePercent);
+                });
+                msg.Append('\n');
+
+                TwitterManager.Update(msg.ToString());
+            }
             {
-                msg.AppendFormat("{0}:{1:F1}% ", usage.Name, usage.UsagePercent);
-            });
-            msg.Append('\n');
+                var msg = new StringBuilder("[Health Check]\n");

-            double memTotal = 0.0, memFree = 0.0, memAvail = 0.0;
-            GetMemInfoM(ref memTotal, ref memFree, ref memAvail);
-            msg.AppendFormat("Memory: {0:F1}M Total, {1:F1}M Free ({2:F1}%), {3:F1}M Avail ({4:F1}%)\n",
-                memTotal, memFree, memFree * 100.0 / memTotal, memAvail, memAvail * 100.0 / memTotal);
+                double memTotal = 0.0, memFree = 0.0, memAvail = 0.0;
+                GetMemInfoM(ref memTotal, ref memFree, ref memAvail);
+                msg.AppendFormat("Memory: {0:F1}M Total, {1:F1}M Free ({2:F1}%), {3:F1}M Avail ({4:F1}%)\n",
+                    memTotal, memFree, memFree * 100.0 / memTotal, memAvail, memAvail * 100.0 / memTotal);

-            double diskFree, diskTotal;
-            GetDiskInfoG(out diskFree, out diskTotal);
-            msg.AppendFormat("Disk: {0:F1}G / {1:F1}G Free ({2}%)\n",
-                diskFree, diskTotal, (int)(diskFree * 100.0 / diskTotal));
+                double diskFree, diskTotal;
+                GetDiskInfoG(out diskFree, out diskTotal);
+                msg.AppendFormat("Disk: {0:F1}G / {1:F1}G Free ({2}%)\n",
+                    diskFree, diskTotal, (int)(diskFree * 100.0 / diskTotal));

-            TwitterManager.Update(msg.ToString());
+                TwitterManager.Update(msg.ToString());
+            }
         }

         private static double GetCpuTemp()


Set the goal to 0 if the input value is invalid.

--- Shared/MainPage.xaml.cs
+++ Shared/MainPage.xaml.cs
@@ -365,7 +365,18 @@

 		private void GoalBox_TextChanged(object sender, TextChangedEventArgs e)
 		{
-			Goal = Convert.ToInt32(GoalBox.Text);
+			try
+			{
+				Goal = Convert.ToInt32(GoalBox.Text);
+			}
+			catch (Exception ex)
+			{
+				// The value is invalid, so let's go with zero.
+				Debug.WriteLine(ex.Message);
+				Goal = 0;
+				GoalBox.Text = Goal.ToString();
+			}
+
 			UpdateGoalIndicator(true);
 		}


Update comments.

Update comments.

Former-commit-id: 2537679307846d5c0b0c608ec7d949bf0749a1ea

--- Sharpy/src/Productor.cs
+++ Sharpy/src/Productor.cs
@@ -35,12 +35,14 @@
         }

         /// <summary>
-        ///  Works like Yield except it will be deffered until produce gets called.
+        ///     Works like Yield except it will be deffered until produce gets called.
         /// </summary>
         /// <typeparam name="T"></typeparam>
         /// <param name="fn"></param>
         /// <returns></returns>
-        public static IProductor<T> Deferred<T>(Func<T> fn) => new Deferred<T>(fn);
+        public static IProductor<T> Deferred<T>(Func<T> fn) {
+            return new Deferred<T>(fn);
+        }

         /// <summary>
         ///     <para>
@@ -66,11 +68,8 @@
         }

         /// <summary>
-        ///     <para>
-        ///         Generates fn
-        ///     </para>
         ///     <remarks>
-        ///         This will be invoked for every element generated.
+        ///         Generates the result of the functions for every invokation of produce.
         ///     </remarks>
         /// </summary>
         /// <param name="productor"></param>
@@ -85,10 +84,11 @@

         /// <summary>
         ///     <para>
-        ///         Maps TSource to Tresult.
+        ///         Maps TSource to Tresult for one invokation of produce.
         ///     </para>
         ///     <remarks>
-        ///         This will be invoked once.
+        ///         If you call this after any Generate method all generation results will be the same.
+        ///         This should be used if you only want to Map once. for example System.Random.
         ///     </remarks>
         /// </summary>
         public static IProductor<TResult> Select<TSource, TResult>(this IProductor<TSource> productor,
@@ -99,6 +99,7 @@

         /// <summary>
         ///     <para>
+        ///         Zips two IProductors together and generates the result of the function for every invokation of produce.
         ///     </para>
         /// </summary>
         /// <param name="productor"></param>
@@ -113,12 +114,32 @@
             return Generate(() => func(productor.Produce(), secondProductor.Produce()));
         }

+        /// <summary>
+        ///     <para>
+        ///         Zips two IProductors together for one invokation of produce.
+        ///     </para>
+        ///     <remarks>
+        ///         If you call this after any Generate method all generation results will be the same.
+        ///         This should be used if you only want to Map once. for example System.Random.
+        ///     </remarks>
+        /// </summary>
+        /// <typeparam name="TResult"></typeparam>
+        /// <typeparam name="TSource"></typeparam>
+        /// <typeparam name="TSecond"></typeparam>
+        /// <param name="productor"></param>
+        /// <param name="secondProductor"></param>
+        /// <param name="func"></param>
+        /// <returns></returns>
         public static IProductor<TResult> Zip<TResult, TSource, TSecond>(this IProductor<TSource> productor,
             IProductor<TSecond> secondProductor, Func<TSource, TSecond, TResult> func) {
             return Deferred(() => func(productor.Produce(), secondProductor.Produce()));
         }

         /// <summary>
+        ///     <para>
+        ///         Zips a IProductor together with a IEnumerable and generates the result of the function for every invokation of
+        ///         produce.
+        ///     </para>
         /// </summary>
         /// <param name="productor"></param>
         /// <param name="secondEnumerable"></param>


fixing an issue

fixing an issue

--- Source/AlienRaceUtil.cs
+++ Source/AlienRaceUtil.cs
@@ -34,7 +34,7 @@
             return raceSettingsFieldInfo.GetValue(pawn.def);
         }

-        public static Dictionary<Type, AlienRace.StyleSettings> GetStyleSettings(Pawn pawn)
+        public static object GetStyleSettings(Pawn pawn)
         {
             object raceSettings = GetAlienRaceSettings(pawn);
             if (raceSettings == null)
@@ -58,7 +58,7 @@

         public static bool HasHair(Pawn pawn)
         {
-            Dictionary<Type, AlienRace.StyleSettings> styleSettings = GetStyleSettings(pawn);
+            Dictionary<Type, AlienRace.StyleSettings> styleSettings = GetStyleSettings(pawn) as Dictionary<Type, AlienRace.StyleSettings>;
             if (styleSettings == null)
             {
                 return false;
@@ -90,7 +90,7 @@

         public static List<string> GetHairTags(Pawn pawn)
         {
-            Dictionary<Type, AlienRace.StyleSettings> styleSettings = GetStyleSettings(pawn);
+            Dictionary<Type, AlienRace.StyleSettings> styleSettings = GetStyleSettings(pawn) as Dictionary<Type, AlienRace.StyleSettings>;
             AlienRace.StyleSettings s = null;
             if (styleSettings?.TryGetValue(typeof(HairDef), out s) == false)
             {


solve chain searching for Slot by provider extension

--- src/Spark.Engine/Model/SparkModelInfo.cs
+++ src/Spark.Engine/Model/SparkModelInfo.cs
@@ -14,7 +14,7 @@
             new SearchParamDefinition() {Resource = "Composition", Name = "custodian", Description = @"custom search parameter on Composition for generating $document", Type = SearchParamType.Reference, Path = new string[] {"Composition.custodian" }, XPath = "f:Composition/f:custodian", Expression = "Composition.custodian", Target =  new ResourceType[] { ResourceType.Organization}  }
             , new SearchParamDefinition() {Resource = "Composition", Name = "eventdetail", Description = @"custom search parameter on Composition for generating $document", Type = SearchParamType.Reference, Path = new string[] {"Composition.event.detail" }, XPath = "f:Composition/f:event/f:detail", Expression = "Composition.event.detail", Target =  Enum.GetValues(typeof(ResourceType)).Cast<ResourceType>().ToArray()  }
             , new SearchParamDefinition() {Resource = "Encounter", Name = "serviceprovider", Description = @"Organization that provides the Encounter services.", Type = SearchParamType.Reference, Path = new[] {"Encounter.serviceProvider"}, XPath = "f:Encounter/f:serviceProvider",Expression = "Encounter.serviceProvider", Target =  new ResourceType[] { ResourceType.Organization} }
-            , new SearchParamDefinition() {Resource = "Slot", Name = "provider", Description = @"Search Slot by provider extension", Type = SearchParamType.Reference, Path = new string[] { @"Slot.extension(url=http://fhir.blackpear.com/era/Slot/provider).valueReference" } }
+            , new SearchParamDefinition() {Resource = "Slot", Name = "provider", Description = @"Search Slot by provider extension", Type = SearchParamType.Reference, Path = new string[] { @"Slot.extension(url=http://fhir.blackpear.com/era/Slot/provider).valueReference" }, Target =  new ResourceType[] { ResourceType.Organization}}
         }).ToList();
     }
 }


Fix up static field names in Console (#28300)

--- src/System.Console/src/System/Console.cs
+++ src/System.Console/src/System/Console.cs
@@ -22,8 +22,8 @@
         private static bool s_isOutTextWriterRedirected = false;
         private static bool s_isErrorTextWriterRedirected = false;

-        private static ConsoleCancelEventHandler _cancelCallbacks;
-        private static ConsolePal.ControlCHandlerRegistrar _registrar;
+        private static ConsoleCancelEventHandler s_cancelCallbacks;
+        private static ConsolePal.ControlCHandlerRegistrar s_registrar;

         internal static T EnsureInitialized<T>(ref T field, Func<T> initializer) where T : class =>
             LazyInitializer.EnsureInitialized(ref field, ref InternalSyncObject, initializer);
@@ -334,13 +334,13 @@
             {
                 lock (InternalSyncObject)
                 {
-                    _cancelCallbacks += value;
+                    s_cancelCallbacks += value;

                     // If we haven't registered our control-C handler, do it.
-                    if (_registrar == null)
+                    if (s_registrar == null)
                     {
-                        _registrar = new ConsolePal.ControlCHandlerRegistrar();
-                        _registrar.Register();
+                        s_registrar = new ConsolePal.ControlCHandlerRegistrar();
+                        s_registrar.Register();
                     }
                 }
             }
@@ -348,11 +348,11 @@
             {
                 lock (InternalSyncObject)
                 {
-                    _cancelCallbacks -= value;
-                    if (_registrar != null && _cancelCallbacks == null)
+                    s_cancelCallbacks -= value;
+                    if (s_registrar != null && s_cancelCallbacks == null)
                     {
-                        _registrar.Unregister();
-                        _registrar = null;
+                        s_registrar.Unregister();
+                        s_registrar = null;
                     }
                 }
             }
@@ -690,7 +690,7 @@

         internal static bool HandleBreakEvent(ConsoleSpecialKey controlKey)
         {
-            ConsoleCancelEventHandler handler = _cancelCallbacks;
+            ConsoleCancelEventHandler handler = s_cancelCallbacks;
             if (handler == null)
             {
                 return false;


Completar DBUtility

Completar DBUtility

+ boolean registerUser(correo, password...);
+ boolean login(correo, password);
+ boolean isUserRegistered(correo);
+ boolean isUserConfirmed(correo);
+ boolean isConfirmCodeSame(correo, numConfirmacion);
+ string getRecoveryQuestion(correo);
+ boolean checkRecoveryQuestion(correo, answer);
+ boolean changePassword(correo, newPassword);
+ boolean confirmUser(correo);

--- AppOverlay/DBUtility.cs
+++ AppOverlay/DBUtility.cs
@@ -10,7 +10,7 @@
 {
     public class DBUtility
     {
-        static SqlConnection connection;
+        public static SqlConnection connection;
         static SqlCommand command;
         public static Boolean connect()
         {
@@ -31,7 +31,7 @@
         public static Boolean registerUser(String correo, String nombre, String apellidos, String DNI, String password, String preguntaSecreta, String respuestaSecreta, int numConfirmacion, Boolean confirmado)
         {
             Random random = new Random((int)DateTime.Now.Ticks & 0x0000FFFF); // Seed depende del tiempo
-            numConfirmacion = (int) (random.NextDouble() * 9000000) + 1000000;
+            numConfirmacion = (int)(random.NextDouble() * 9000000) + 1000000;
             string commandString = "INSERT INTO USUARIOS VALUES ('" + correo + "', '" + nombre + "', '" + apellidos + "', '" + DNI + "', '" + password + "', '" + preguntaSecreta + "', '" + respuestaSecreta + "', '" + numConfirmacion + "', '" + confirmado + "')";
             command = new SqlCommand(commandString, connection);
             try
@@ -46,7 +46,152 @@
             AppSecurity.AppSecurity.sendConfirmEmail(correo, numConfirmacion);
             return true;
         }
-
+        public static Boolean login(String correo, String password)
+        {
+            int count;
+            string commandString = "SELECT count(*) FROM USUARIOS where correo = '" + correo + "' and password = '" + password + "'";
+            command = new SqlCommand(commandString, connection);
+            try
+            {
+                count = (int)command.ExecuteScalar();
+            }
+            catch (SqlException ex)
+            {
+                Console.WriteLine("[Error] Unable to execute command. " + ex);
+                return false;
+            }
+            if (count == 1)
+            {
+                return true;
+            }
+            return false;
+        }
+        public static Boolean isUserRegistered(String correo)
+        {
+            int count;
+            string commandString = "SELECT count(*) FROM USUARIOS where correo = '" + correo + "'";
+            command = new SqlCommand(commandString, connection);
+            try
+            {
+                count = (int)command.ExecuteScalar();
+            }
+            catch (SqlException ex)
+            {
+                Console.WriteLine("[Error] Unable to execute command. " + ex);
+                return false;
+            }
+            if (count == 1)
+            {
+                return true;
+            }
+            return false;
+        }
+        public static Boolean isUserConfirmed(String correo)
+        {
+            int count;
+            string commandString = "SELECT count(*) FROM USUARIOS where correo = '" + correo + "' and confirmado = 'True'";
+            command = new SqlCommand(commandString, connection);
+            try
+            {
+                count = (int)command.ExecuteScalar();
+            }
+            catch (SqlException ex)
+            {
+                Console.WriteLine("[Error] Unable to execute command. " + ex);
+                return false;
+            }
+            if (count == 1)
+            {
+                return true;
+            }
+            return false;
+        }
+        public static Boolean isConfirmCodeSame(String correo, String numConfirmacion)
+        {
+            int count;
+            string commandString = "SELECT count(*) FROM USUARIOS where correo = '" + correo + "' and numConfirmacion = '" + numConfirmacion + "'";
+            command = new SqlCommand(commandString, connection);
+            try
+            {
+                count = (int)command.ExecuteScalar();
+            }
+            catch (SqlException ex)
+            {
+                Console.WriteLine("[Error] Unable to execute command. " + ex);
+                return false;
+            }
+            if (count == 1)
+            {
+                return true;
+            }
+            return false;
+        }
+        public static Boolean confirmUser (String correo)
+        {
+            string commandString = "UPDATE USUARIOS SET confirmado= 'True' WHERE correo = '" + correo + "'";
+            command = new SqlCommand(commandString, connection);
+            try
+            {
+                command.ExecuteNonQuery();
+            }
+            catch (SqlException ex)
+            {
+                Console.WriteLine("[Error] Unable to execute command. " + ex);
+                return false;
+            }
+            return true;
+        }
+        public static string getRecoveryQuestion(string correo)
+        {
+            string preguntaSecreta;
+            string commandString = "SELECT preguntaSecreta FROM USUARIOS where correo = '" + correo + "'";
+            command = new SqlCommand(commandString, connection);
+            try
+            {
+                preguntaSecreta = command.ExecuteScalar().ToString();
+            }
+            catch (SqlException ex)
+            {
+                Console.WriteLine("[Error] Unable to execute command. " + ex);
+                return null;
+            }
+            return preguntaSecreta;
+        }
+        public static Boolean checkRecoveryQuestion(string correo, string answer)
+        {
+            string respuestaSecreta;
+            string commandString = "SELECT respuestaSecreta FROM USUARIOS where correo = '" + correo + "'";
+            command = new SqlCommand(commandString, connection);
+            try
+            {
+                respuestaSecreta = command.ExecuteScalar().ToString();
+            }
+            catch (SqlException ex)
+            {
+                Console.WriteLine("[Error] Unable to execute command. " + ex);
+                return false;
+            }
+            if (String.Compare(respuestaSecreta, answer) == 0)
+            {
+                return true;
+            }
+            return false;
+        }
+        public static Boolean changePassword(string correo, string newPassword)
+        {
+            string commandString = "UPDATE USUARIOS SET password= '" + newPassword + "' WHERE correo = '" + correo + "'";
+            command = new SqlCommand(commandString, connection);
+            try
+            {
+                command.ExecuteNonQuery();
+            }
+            catch (SqlException ex)
+            {
+                Console.WriteLine("[Error] Unable to execute command. " + ex);
+                return false;
+            }
+            return true;
+        }
         public static void close()
         {
             connection.Close();


debug lines

debug lines

--- TCC.Core/App.xaml.cs
+++ TCC.Core/App.xaml.cs
@@ -4,9 +4,11 @@
 using System.IO;
 using System.Reflection;
 using System.Windows;
+using System.Windows.Threading;
 using TCC.Data;
 using TCC.Data.Databases;
 using TCC.Parsing;
+using TCC.Parsing.Messages;
 using TCC.ViewModels;
 using TCC.Windows;

@@ -17,6 +19,7 @@
     /// </summary>
     public partial class App
     {
+        public static bool Debug = true;
         private static void GlobalUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
         {
             var ex = (Exception)e.ExceptionObject;
@@ -52,7 +55,7 @@
             UpdateManager.CheckDatabaseVersion();

             SkillsDatabase.Load();
-            BroochesDatabase.SetBroochesIcons();
+            ItemSkillsDatabase.SetBroochesIcons();
             SettingsManager.LoadWindowSettings();
             SettingsManager.LoadSettings();
             WindowManager.Init();
@@ -91,6 +94,52 @@
             var ver = $"TCC v{v.Major}.{v.Minor}.{v.Build}";
             ChatWindowViewModel.Instance.AddChatMessage(new ChatMessage(ChatChannel.TCC, "System", $"<FONT>{ver}</FONT>"));

+            return;
+
+            SessionManager.CurrentPlayer = new Player(1, "Foglio");
+            for (uint i = 0; i < 1; i++)
+            {
+                var u = new User(GroupWindowViewModel.Instance.GetDispatcher());
+                u.Name = "Test_Dps" + i;
+                u.PlayerId = i;
+                u.Online = true;
+                u.UserClass = Class.Warrior;
+                if (i == 1) u.HasAggro = true;
+                if (i == 0) u.IsLeader = true;
+
+                GroupWindowViewModel.Instance.AddOrUpdateMember(u);
+            }
+            for (uint i = 0; i < 2; i++)
+            {
+                var u = new User(GroupWindowViewModel.Instance.GetDispatcher());
+                u.Name = "Test_Healer" + i;
+                u.PlayerId = i +10;
+                u.Online = true;
+                u.UserClass = Class.Elementalist;
+                if (i == 1) u.Alive = false;
+                if (i == 0) u.Name = "Foglio";
+
+                GroupWindowViewModel.Instance.AddOrUpdateMember(u);
+            }
+            for (uint i = 0; i < 4; i++)
+            {
+                var u = new User(GroupWindowViewModel.Instance.GetDispatcher());
+                u.Name = "Test_Tank" + i;
+                u.PlayerId = i + 100;
+                u.Online = true;
+                u.UserClass = Class.Lancer;
+                GroupWindowViewModel.Instance.AddOrUpdateMember(u);
+            }
+            foreach (var user in GroupWindowViewModel.Instance.All)
+            {
+                user.AddOrRefreshBuff(new Abnormality(4611, true, true, false, AbnormalityType.Buff),60*100*60,1);
+                user.AddOrRefreshBuff(new Abnormality(46126, true, true, false, AbnormalityType.Buff),60*100*60,1);
+                user.AddOrRefreshDebuff(new Abnormality(89308100, true, false, false, AbnormalityType.DamageOverTime),60*100*60,5);
+                user.AddOrRefreshDebuff(new Abnormality(89308101, true, false, false, AbnormalityType.DamageOverTime),60*100*60,5);
+
+            }
+            //GroupWindowViewModel.Instance.StartRoll();
+            //GroupWindowViewModel.Instance.SetReadyStatus(new ReadyPartyMember());
         }

         public static void CloseApp()


changed messageFactory

changed messageFactory

--- TCC.Core/App.xaml.cs
+++ TCC.Core/App.xaml.cs
@@ -27,7 +27,7 @@
     /// </summary>
     public partial class App
     {
-        public static bool Debug = false;
+        public static bool Debug = true;
         public static TCC.Windows.SplashScreen SplashScreen;
         public static string Version;
         private static void GlobalUnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
@@ -48,7 +48,7 @@
             System.Windows.MessageBox.Show("An error occured and TCC will now close. Check error.txt for more info.", "TCC",
                 MessageBoxButton.OK, MessageBoxImage.Error);

-            if(Proxy.IsConnected) Proxy.CloseConnection();
+            if (Proxy.IsConnected) Proxy.CloseConnection();
             if (WindowManager.TrayIcon != null)
             {
                 WindowManager.TrayIcon.Dispose();
@@ -71,8 +71,16 @@
             js.Add("inner_exception", new JValue(ex.InnerException != null ? ex.InnerException.Message.ToString() : "undefined"));
             js.Add("exception", new JValue(ex.Message.ToString()));
             js.Add("game_version", new JValue(PacketProcessor.Version));
-            js.Add("region", new JValue(PacketProcessor.Region));
-            js.Add("server_id", new JValue(PacketProcessor.ServerId));
+            if (PacketProcessor.Server != null)
+            {
+                js.Add("region", new JValue(PacketProcessor.Server.Region));
+                js.Add("server_id", new JValue(PacketProcessor.Server.ServerId));
+            }
+            else
+            {
+                js.Add("region", new JValue(""));
+                js.Add("server_id", new JValue(""));
+            }
             c.Encoding = Encoding.UTF8;
             c.UploadString(new Uri("https://us-central1-tcc-report.cloudfunctions.net/crash"), Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(js.ToString())));
         }
@@ -112,9 +120,9 @@
                 c.Headers.Add(HttpRequestHeader.AcceptCharset, "utf-8");
                 var js = new JObject()
                 {
-                    { "server", PacketProcessor.ServerId},
+                    { "server", PacketProcessor.Server.ServerId},
                     { "id", InfoWindowViewModel.Instance.Characters == null ?0 : InfoWindowViewModel.Instance.Characters.Count == 0 ? 0 : InfoWindowViewModel.Instance.Characters.FirstOrDefault(x => x.Position == 1).Id },
-                    { "region", PacketProcessor.Region },
+                    { "region", PacketProcessor.Server.Region },
                 };
                 c.Encoding = Encoding.UTF8;
                 c.UploadStringAsync(new Uri("https://us-central1-tcc-report.cloudfunctions.net/stat"), Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(js.ToString())));
@@ -126,7 +134,7 @@
             Version = $"TCC v{v.Major}.{v.Minor}.{v.Build}";
             InitSS();
             var cd = AppDomain.CurrentDomain;
-            //cd.UnhandledException += GlobalUnhandledExceptionHandler;
+            cd.UnhandledException += GlobalUnhandledExceptionHandler;
             Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Normal;
             try
             {
@@ -140,8 +148,6 @@

             UpdateManager.CheckDatabaseVersion();

-            SplashScreen.SetText("Loading skills...");
-            SkillsDatabase.Load();
             SplashScreen.SetText("Loading settings...");
             SettingsManager.LoadWindowSettings();
             SettingsManager.LoadSettings();
@@ -156,6 +162,7 @@

             TeraSniffer.Instance.NewConnection += (srv) =>
             {
+                PacketProcessor.Server = srv;
                 SkillManager.Clear();
                 WindowManager.TrayIcon.Icon = WindowManager.ConnectedIcon;
                 ChatWindowViewModel.Instance.AddTccMessage($"Connected to {srv.Name}.");
@@ -187,6 +194,7 @@
             if (!Debug) return;
             SessionManager.CurrentPlayer = new Player(1, "Foglio");
             SessionManager.CurrentPlayer.Class = Class.Warrior;
+            SkillsDatabase.Load("EU-EN");
             CooldownWindowViewModel.Instance.LoadSkills(Utils.ClassEnumToString(Class.Warrior).ToLower() + "-skills.xml", Class.Warrior);
             AbnormalityManager.CurrentDb = new AbnormalityDatabase("EU-EN");
             var s = AbnormalityManager.CurrentDb.Abnormalities[4];


clean up

clean up

--- bstrkr.mobile/bstrkr.mvvm/ViewModels/RouteViewModel.cs
+++ bstrkr.mobile/bstrkr.mvvm/ViewModels/RouteViewModel.cs
@@ -6,6 +6,8 @@
 using bstrkr.core;
 using bstrkr.mvvm.viewmodels;
 using bstrkr.providers;
+using System.Threading.Tasks;
+using Xamarin;

 namespace bstrkr.mvvm.viewmodels
 {
@@ -110,8 +112,15 @@
 			}
 		}

-		private void ShowRouteVehicles(IEnumerable<Vehicle> vehicles)
+		private void ShowRouteVehicles(Task<IEnumerable<Vehicle>> task)
 		{
+			if (task.Status != TaskStatus.RanToCompletion)
+			{
+				Insights.Report(task.Exception, ReportSeverity.Error);
+				return;
+			}
+
+			var vehicles = task.Result;
 			if (vehicles != null)
 			{
 				var vms = vehicles.Where(x => x.RouteInfo != null && x.RouteInfo.RouteId.Equals(this.Id))


Setting up code for sprite array

Setting up code for sprite array

--- Assets/Scripts/Flags.cs
+++ Assets/Scripts/Flags.cs
@@ -7,9 +7,18 @@

     public GameObject[] flagAnwsers;
     public string[] flagArray;
+
+    public Sprite[] allFlags;

 	// Use this for initialization
 	void Start () {
+        Object[] imports = Resources.LoadAll.<Sprite>("/Sprites");
+
+        allFlags = new Sprite[allFlags.Length];
+
+        for (var i = 0 ; i < allFlags.Length; i++){
+            allFlags[i] = imports[i];
+        }
         //sorts them wierdly :p 3,4,1,2?? :P
         //flagAnwsers = GameObject.FindGameObjectsWithTag("Flag");


用虚线给每个字形描边

用虚线给每个字形描边

--- TTF2Bmps/FormMain.cs
+++ TTF2Bmps/FormMain.cs
@@ -199,8 +199,8 @@
         private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
         {
             WorkerData data = e.Argument as WorkerData;
-            int count = data.selectedTTFFiles.Length;
-            int index = 1;
+            int fontFileCount = data.selectedTTFFiles.Length;
+            int fontFileIndex = 1;
             const int magicNumber = 100;

             WorkerResult result = new WorkerResult(null, data);
@@ -210,7 +210,7 @@

             foreach (var fontFullname in this.selectedTTFFiles)
             {
-                builder.Append(index); builder.Append("/"); builder.Append(count);
+                builder.Append(fontFileIndex); builder.Append("/"); builder.Append(fontFileCount);
                 builder.Append(": "); builder.AppendLine(fontFullname);

                 string destFullname = fontFullname + ".png";
@@ -219,27 +219,53 @@

                 try
                 {
-                    foreach (var progress in FontTextureYieldHelper.GetTTFTexture(
-                        fontFullname, data.fontHeight, data.maxTexturWidth, data.firstChar, data.lastChar))
                     {
-                        ttfTexture = progress.ttfTexture;
-                        var singleFileProgress = new SingleFileProgress() { progress = progress.percent, message = progress.message };
-                        bgWorker.ReportProgress(index * magicNumber / count, singleFileProgress);
+                        int lastPercent = 0;
+                        foreach (var progress in FontTextureYieldHelper.GetTTFTexture(
+                            fontFullname, data.fontHeight, data.maxTexturWidth, data.firstChar, data.lastChar))
+                        {
+                            ttfTexture = progress.ttfTexture;
+                            if (progress.percent != lastPercent)
+                            {
+                                var singleFileProgress = new SingleFileProgress() { progress = progress.percent, message = progress.message };
+                                bgWorker.ReportProgress(fontFileIndex * magicNumber / fontFileCount, singleFileProgress);
+                                lastPercent = progress.percent;
+                            }
+                        }
                     }

                     if (data.drawHeightLine)
                     {
                         System.Drawing.Bitmap bigBitmap = new System.Drawing.Bitmap(ttfTexture.BigBitmap);
                         Graphics g = Graphics.FromImage(bigBitmap);
-                        for (int row = 0; row < bigBitmap.Height; row += ttfTexture.FontHeight)
+                        int vertialLineIndex = 0;
+                        int characterCount = ttfTexture.CharInfoDict.Values.Count;
+                        int lastPercent = 0;
+                        foreach (var item in ttfTexture.CharInfoDict.Values)
                         {
-                            Pen pen = (row / ttfTexture.FontHeight) % 2 == 0 ? evenLinePen : oddLinePen;
+                            // 上边
                             g.DrawLine(pen,
-                                new Point(0, row),
-                                new Point(bigBitmap.Width, row));
+                                new Point(item.xoffset, item.yoffset),
+                                new Point(item.xoffset + item.width - 1, item.yoffset));
+                            // 下边
                             g.DrawLine(pen,
-                                new Point(0, row + ttfTexture.FontHeight - 1),
-                                new Point(bigBitmap.Width, row + ttfTexture.FontHeight - 1));
+                                new Point(item.xoffset, item.yoffset + ttfTexture.FontHeight - 1),
+                                new Point(item.xoffset + item.width - 1, item.yoffset + ttfTexture.FontHeight - 1));
+                            // 左边
+                            g.DrawLine(pen,
+                                new Point(item.xoffset, item.yoffset),
+                                new Point(item.xoffset, item.yoffset + ttfTexture.FontHeight));
+                            // 右边
+                            g.DrawLine(pen,
+                                new Point(item.xoffset + item.width - 1, item.yoffset),
+                                new Point(item.xoffset + item.width - 1, item.yoffset + ttfTexture.FontHeight));
+                            int percent = vertialLineIndex++ * 100 / characterCount;
+                            if (percent != lastPercent)
+                            {
+                                var singleFileProgress = new SingleFileProgress() { progress = percent, message = "drawing vertial lines" };
+                                bgWorker.ReportProgress(fontFileIndex * magicNumber / fontFileCount, singleFileProgress);
+                                lastPercent = percent;
+                            }
                         }
                         bigBitmap.Save(destFullname);
                         bigBitmap.Dispose();
@@ -259,7 +285,7 @@
                         FontTexturePNGPrinter printer = new FontTexturePNGPrinter(ttfTexture);
                         foreach (var progress in printer.Print(fontFullname, data.maxTexturWidth))
                         {
-                            bgWorker.ReportProgress(index * magicNumber / count, progress);
+                            bgWorker.ReportProgress(fontFileIndex * magicNumber / fontFileCount, progress);
                         }
                     }
                 }
@@ -281,15 +307,20 @@
                     progress = magicNumber,
                     message = string.Format("All is done for {0}", fileInfo.Name),
                 };
-                bgWorker.ReportProgress(index++ * magicNumber / count, thisFileDone);
+                bgWorker.ReportProgress(fontFileIndex++ * magicNumber / fontFileCount, thisFileDone);
                 //bgWorker.ReportProgress(magicNumber, thisFileDone);

                 //Process.Start("explorer", destFullname);
             }
         }

-        Pen evenLinePen = new Pen(Color.Red) { DashStyle = System.Drawing.Drawing2D.DashStyle.Custom, DashPattern = new float[] { 5, 15 }, };
-        Pen oddLinePen = new Pen(Color.Red) { DashStyle = System.Drawing.Drawing2D.DashStyle.Custom, DashPattern = new float[] { 5, 15 }, DashOffset = 10 };
+        const int horizontalFactor = 1;
+        const int verticalFactor = 1;
+        Pen pen = new Pen(Color.Red) { DashStyle = System.Drawing.Drawing2D.DashStyle.Custom, DashPattern = new float[] { horizontalFactor, horizontalFactor }, };
+        Pen evenHorizontalLinePen = new Pen(Color.Red) { DashStyle = System.Drawing.Drawing2D.DashStyle.Custom, DashPattern = new float[] { horizontalFactor, horizontalFactor }, };
+        Pen oddHorizontalLinePen = new Pen(Color.Red) { DashStyle = System.Drawing.Drawing2D.DashStyle.Custom, DashPattern = new float[] { horizontalFactor, horizontalFactor }, DashOffset = horizontalFactor };
+        Pen evenVerticalLinePen = new Pen(Color.Red) { DashStyle = System.Drawing.Drawing2D.DashStyle.Custom, DashPattern = new float[] { verticalFactor, verticalFactor }, };
+        Pen oddVerticalLinePen = new Pen(Color.Red) { DashStyle = System.Drawing.Drawing2D.DashStyle.Custom, DashPattern = new float[] { verticalFactor, verticalFactor }, DashOffset = verticalFactor };

         private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
         {


feat: helpers

feat: helpers

--- Assets/src/data/Game.cs
+++ Assets/src/data/Game.cs
@@ -13,6 +13,23 @@
   }

   public Winner Check(Vector click) {
+    var gridV = ClickToGrid(click);
+    var grid = FromGridVector(gridV);
+
+    // TODO: Check if there is a winner
+
     return new Winner();
   }
+
+  Vector ClickToGrid(Vector click) {
+    var x = click.x % 3;
+    var y = click.y % 3;
+    return new Vector(x,y);
+  }
+
+  Grid FromGridVector(Vector click) {
+    Grid grid = null;
+    map.TryGetValue(click, grid);
+    return grid;
+  }
 }


Fixes U4-1542

Fixes U4-1542

--- src/Umbraco.Tests/Models/MediaXmlTest.cs
+++ src/Umbraco.Tests/Models/MediaXmlTest.cs
@@ -61,7 +61,6 @@
             Assert.AreEqual(media.Id.ToString(), (string)element.Attribute("id"));
             Assert.AreEqual(media.ParentId.ToString(), (string)element.Attribute("parentID"));
             Assert.AreEqual(media.Level.ToString(), (string)element.Attribute("level"));
-            //Assert.AreEqual(media.CreatorId.ToString(), (string)element.Attribute("creatorID"));
             Assert.AreEqual(media.SortOrder.ToString(), (string)element.Attribute("sortOrder"));
             Assert.AreEqual(media.CreateDate.ToString("s"), (string)element.Attribute("createDate"));
             Assert.AreEqual(media.UpdateDate.ToString("s"), (string)element.Attribute("updateDate"));
@@ -70,7 +69,6 @@
             Assert.AreEqual(media.Path, (string)element.Attribute("path"));
             Assert.AreEqual("", (string)element.Attribute("isDoc"));
             Assert.AreEqual(media.ContentType.Id.ToString(), (string)element.Attribute("nodeType"));
-            //Assert.AreEqual(media.GetCreatorProfile().Name, (string)element.Attribute("creatorName"));
             Assert.AreEqual(media.GetCreatorProfile().Name, (string)element.Attribute("writerName"));
             Assert.AreEqual(media.CreatorId.ToString(), (string)element.Attribute("writerID"));
             Assert.AreEqual(media.Version.ToString(), (string)element.Attribute("version"));


Adds UmbracoFeatures to the Composition to allow user components to do something like this - composition.Features().Disabled.Controllers.Add<LogViewerTreeController>()

--- src/Umbraco.Web/CompositionExtensions.cs
+++ src/Umbraco.Web/CompositionExtensions.cs
@@ -11,6 +11,7 @@
 using Umbraco.Web.PublishedCache;
 using Umbraco.Web.Routing;
 using Umbraco.Web.ContentApps;
+using Umbraco.Web.Features;

 // the namespace here is intentional -  although defined in Umbraco.Web assembly,
 // this class should be visible when using Umbraco.Core.Components, alongside
@@ -57,6 +58,9 @@
         /// <returns></returns>
         internal static EditorValidatorCollectionBuilder EditorValidators(this Composition composition)
             => composition.Container.GetInstance<EditorValidatorCollectionBuilder>();
+
+        public static UmbracoFeatures Features(this Composition composition)
+            => composition.Container.GetInstance<UmbracoFeatures>();

         /// <summary>
         /// Gets the filtered controller factories collection builder.


fixes minor issue with the backing up of the install folder

--- src/Umbraco.Web/Install/InstallHelper.cs
+++ src/Umbraco.Web/Install/InstallHelper.cs
@@ -69,7 +69,21 @@
         internal void DeleteLegacyInstaller()
         {
             if (Directory.Exists(IOHelper.MapPath(SystemDirectories.Install)))
-                Directory.Move(IOHelper.MapPath(SystemDirectories.Install), IOHelper.MapPath("~/app_data/temp/install_backup"));
+            {
+                if (Directory.Exists(IOHelper.MapPath("~/app_data/temp/install_backup")))
+                {
+                    //this means the backup already exists with files but there's no files in it, so we'll delete the backup and re-run it
+                    if (Directory.GetFiles(IOHelper.MapPath("~/app_data/temp/install_backup")).Any() == false)
+                    {
+                        Directory.Delete(IOHelper.MapPath("~/app_data/temp/install_backup"), true);
+                        Directory.Move(IOHelper.MapPath(SystemDirectories.Install), IOHelper.MapPath("~/app_data/temp/install_backup"));
+                    }
+                }
+                else
+                {
+                    Directory.Move(IOHelper.MapPath(SystemDirectories.Install), IOHelper.MapPath("~/app_data/temp/install_backup"));
+                }
+            }

             if (Directory.Exists(IOHelper.MapPath("~/Areas/UmbracoInstall")))
             {


Updated WebSocketHandler to invoke client methods

--- src/WebSocketManager/WebSocketHandler.cs
+++ src/WebSocketManager/WebSocketHandler.cs
@@ -3,13 +3,19 @@
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;

 namespace WebSocketManager
 {
     public abstract class WebSocketHandler
     {
         protected WebSocketConnectionManager WebSocketConnectionManager { get; set; }
-
+
+        private JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings()
+        {
+            ContractResolver = new CamelCasePropertyNamesContractResolver()
+        };
         public WebSocketHandler(WebSocketConnectionManager webSocketConnectionManager)
         {
             WebSocketConnectionManager = webSocketConnectionManager;
@@ -18,6 +24,11 @@
         public virtual async Task OnConnected(WebSocket socket)
         {
             WebSocketConnectionManager.AddSocket(socket);
+
+            await SendMessageAsync(socket, new Message(){
+                MessageType = MessageType.ConnectionEvent,
+                Data = WebSocketConnectionManager.GetId(socket)
+            });
         }

         public virtual async Task OnDisconnected(WebSocket socket)
@@ -25,6 +36,59 @@
             await WebSocketConnectionManager.RemoveSocket(WebSocketConnectionManager.GetId(socket));
         }

+        public async Task SendMessageAsync(WebSocket socket, Message message)
+        {
+            if(socket.State != WebSocketState.Open)
+                return;
+
+            var serializedMessage = JsonConvert.SerializeObject(message, _jsonSerializerSettings);
+            await socket.SendAsync(buffer: new ArraySegment<byte>(array: Encoding.ASCII.GetBytes(serializedMessage),
+                                                                  offset: 0,
+                                                                  count: serializedMessage.Length),
+                                   messageType: WebSocketMessageType.Text,
+                                   endOfMessage: true,
+                                   cancellationToken: CancellationToken.None);
+        }
+
+        public async Task SendMessageAsync(string socketId, Message message)
+        {
+            await SendMessageAsync(WebSocketConnectionManager.GetSocketById(socketId), message);
+        }
+
+        public async Task SendMessageToAllAsync(Message message)
+        {
+            foreach(var pair in WebSocketConnectionManager.GetAll())
+            {
+                if(pair.Value.State == WebSocketState.Open)
+                    await SendMessageAsync(pair.Value, message);
+            }
+        }
+
+        public async Task InvokeClientMethodAsync(string socketId, string methodName, object[] arguments)
+        {
+            var message = new Message()
+            {
+                MessageType = MessageType.ClientMethodInvocation,
+                Data = JsonConvert.SerializeObject(new MethodInvocationDescriptor()
+                {
+                    MethodName = methodName,
+                    Arguments = arguments
+                }, _jsonSerializerSettings)
+            };
+
+            await SendMessageAsync(socketId, message);
+        }
+
+        public async Task InvokeClientMethodToAllAsync(string methodName, params object[] arguments)
+        {
+            foreach(var pair in WebSocketConnectionManager.GetAll())
+            {
+                if(pair.Value.State == WebSocketState.Open)
+                    await InvokeClientMethodAsync(pair.Key, methodName, arguments);
+            }
+        }
+
+/*
         public async Task SendMessageAsync(WebSocket socket, string message)
         {
             if(socket.State != WebSocketState.Open)
@@ -51,6 +115,8 @@
                     await SendMessageAsync(pair.Value, message);
             }
         }
+*/
+

         //TODO - decide if exposing the message string is better than exposing the result and buffer
         public abstract Task ReceiveAsync(WebSocket socket, WebSocketReceiveResult result, byte[] buffer);


Called OnDisconnected from exception

Called OnDisconnected from exception

--- src/WebSocketManager/WebSocketHandler.cs
+++ src/WebSocketManager/WebSocketHandler.cs
@@ -70,7 +70,7 @@
                 {
                     if (e.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely)
                     {
-                        await WebSocketConnectionManager.RemoveSocket(pair.Key);
+                        await OnDisconnected(pair.Value);
                     }
                 }
             }
@@ -104,7 +104,7 @@
                 {
                     if (e.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely)
                     {
-                        await WebSocketConnectionManager.RemoveSocket(pair.Key);
+                        await OnDisconnected(pair.Value);
                     }
                 }
             }


Method BaseCodecTest.CopyOfRange() added.

--- ocsbincodec-test/BaseCodecTest.cs
+++ ocsbincodec-test/BaseCodecTest.cs
@@ -36,6 +36,15 @@
 	{
 		protected System.Random random = new System.Random();

+		protected static T[] CopyOfRange<T>(T [] src,  int offs, int size)
+		{
+			T [] dst;
+
+			dst = new T[size];
+			Array.Copy(src, offs, dst, 0, size);
+			return dst;
+		}
+
 		protected void TestEncodeDecodeCore(ICodec c) {

 			for (int size = 1; size <= 1024; size++) {


Controller: invert if and use early return in Attach

--- ToolbarController.cs
+++ ToolbarController.cs
@@ -32,13 +32,13 @@
                 AttachFirst(processName, engines) :
                 AttachAll(processName, engines);

-            if (!found)
-            {
-                MessageBox.Show( $"No processes with name {processName} are found.",
-                    "Attach Toolbar",
-                    MessageBoxButtons.OK,
-                    MessageBoxIcon.Error );
-            }
+            if (found)
+                return;
+
+            MessageBox.Show( $"No processes with name {processName} are found.",
+                "Attach Toolbar",
+                MessageBoxButtons.OK,
+                MessageBoxIcon.Error );
         }

         private bool AttachFirst(string processName, Engine[] engines)


Minor fix

Minor fix

--- UnitTest/UnitTest.cs
+++ UnitTest/UnitTest.cs
@@ -28,7 +28,7 @@
         string serverConnectionString = "";
         #endregion

-        #region once for all tests - build order
+        //once for all tests - build order
         public TestContext()
         {
             try
@@ -65,14 +65,12 @@
             if (sqlController.SettingRead(Settings.token) == "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                 at.DbSetup("unittest");
         }
-        #endregion
-
-        #region once for all tests - teardown
+
+        //once for all tests - teardown
         public void Dispose()
         {
             //sqlController.UnitTest_DeleteDb();
         }
-        #endregion

         public string GetConnectionString()
         {


Remove unused piece of code

Remove unused piece of code

--- ProjectExcluder/ProjectExcluder/Program.cs
+++ ProjectExcluder/ProjectExcluder/Program.cs
@@ -11,13 +11,11 @@
 {
 	class Program
 	{
-		private static int _counter = 0;
 		private static List<string> _processedFiles = new List<string>();

 		static void Main(string[] args)
 		{
 			var mainProjectFilePath = string.Empty;
-
 #if DEBUG
 			mainProjectFilePath = @"C:\dvlp\Project\ASPNET4\Report2\Report2.Web\Report2.Web.csproj";
 #else
@@ -26,38 +24,26 @@

 			mainProjectFilePath = args[0];
 #endif
-
 			if (!File.Exists(mainProjectFilePath))
-				throw new FileNotFoundException("not found !");
-
-			var document = XDocument.Load(mainProjectFilePath);
+				throw new FileNotFoundException($"Not found: {mainProjectFilePath}");

 			FindChildProjects(mainProjectFilePath);

+			Console.WriteLine($"The End: {_processedFiles.Count} files have been processed");
 #if DEBUG
-			Console.ForegroundColor = ConsoleColor.Red;
-			Console.WriteLine($"Save main project file: {Path.GetFileName(mainProjectFilePath)}");
-			Console.ForegroundColor = ConsoleColor.Gray;
-#else
-			document.Save(mainProjectFilePath);
+			Console.Read();
 #endif
-			Console.WriteLine("End");
-			Console.Read();
-			//}
-
 		}

 		private static void FindChildProjects(string filePath)
 		{
-			//counter++;
-
 			var di = new DirectoryInfo(filePath);
 			filePath = di.FullName;

 			var document = XDocument.Load(filePath);
 			var baseDirectory = Path.GetDirectoryName(filePath);

-			Console.WriteLine($"FindChildProjects from: {Path.GetFileName(filePath)}");
+			//Console.WriteLine($"FindChildProjects from: {Path.GetFileName(filePath)}");

 			#region Content elements are empty
 			/*
@@ -81,14 +67,18 @@

 			foreach (var itemGroup in document.Root.Elements().Where(e => e.Name.LocalName == "ItemGroup" && !e.HasAttributes && e.HasElements))
 			{
-				var referenceElements = GetReferenceElement(itemGroup);
-				if (referenceElements.Any())
+				var projectReferenceElements = FindReferenceElement(itemGroup);
+				if (projectReferenceElements.Any())
 				{
-					Console.WriteLine($"We have {referenceElements.Count()} Project reference included in {Path.GetFileName(filePath)}");
+					//Console.WriteLine($"We have {referenceElements.Count()} Project reference included in {Path.GetFileName(filePath)}");

-					foreach (var contentElement in referenceElements.Where(c => c.Attribute("Include").Value.Contains(".csproj")))
+					foreach (var contentElement in projectReferenceElements.Where(c => c.Attribute("Include").Value.Contains(".csproj")))
 					{
 						var childProjectFullPath = Path.Combine(baseDirectory, GetRelativeProjectFilePath(contentElement));
+
+						if (!File.Exists(childProjectFullPath))
+							throw new FileNotFoundException($"Not found: {childProjectFullPath}");
+
 						AddSonarQubeElement(childProjectFullPath);
 						FindChildProjects(childProjectFullPath);
 					}
@@ -106,7 +96,7 @@
 		//	return itemGroup.Elements().Where(e => e.Name.LocalName == "Content" && e.HasAttributes).ToList();
 		//}

-		private static IEnumerable<XElement> GetReferenceElement(XElement itemGroup)
+		private static IEnumerable<XElement> FindReferenceElement(XElement itemGroup)
 		{
 			return itemGroup.Elements().Where(e => e.Name.LocalName == "ProjectReference" && e.HasAttributes).ToList();
 		}
@@ -119,29 +109,19 @@
 			{
 				var document = XDocument.Load(filePath);
 				var parentNameSpace = document.Root.Name.Namespace;
-
 				var propertyGroup = document.Root.Elements().Where(e => e.Name.LocalName == "PropertyGroup" && !e.HasAttributes && e.HasElements).FirstOrDefault();
-
-				//var sonarQubeAttribute = propertyGroup.Elements().SingleOrDefault(p => p.Name.LocalName == "SonarQubeExclude");
-
-				//if (sonarQubeAttribute == null)
-				//{
 #if DEBUG
-				Console.WriteLine($"Add SonarQubeExclude attribute to: {fileName}");
+				//Console.WriteLine($"Add SonarQubeExclude attribute to: {fileName}");
 #else
 				propertyGroup.Add(new XElement(parentNameSpace + "SonarQubeExclude", true));
 #endif
 				_processedFiles.Add(fileName);
-				//}
-
 #if DEBUG
-				Console.ForegroundColor = ConsoleColor.Red;
-				Console.WriteLine($"Save project file: {fileName}");
-				Console.ForegroundColor = ConsoleColor.Gray;
+				Console.WriteLine($"Save project file: {fileName}");
 #else
-			document.Save(filePath);
+				document.Save(filePath);
 #endif
 			}
 		}
 	}
-}
+}


Added regular expression for workgroupAddress zip.

--- Purchasing.Core/Domain/WorkgroupAddress.cs
+++ Purchasing.Core/Domain/WorkgroupAddress.cs
@@ -1,4 +1,5 @@
-using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
+using DataAnnotationsExtensions;
 using FluentNHibernate.Mapping;
 using UCDArch.Core.DomainModel;

@@ -31,6 +32,7 @@
         public virtual string State { get; set; }
         [Required]
         [StringLength(10)]
+        [RegularExpression(@"^\d{5}$|^\d{5}-\d{4}$", ErrorMessage = "Zip must be ##### or #####-####")]
         public virtual string Zip { get; set; }
         [StringLength(15)]
         public virtual string Phone { get; set; }


More fixes to vote!

More fixes to vote!

--- RealPollSignalR/Views/Question/Vote.cshtml
+++ RealPollSignalR/Views/Question/Vote.cshtml
@@ -21,7 +21,7 @@
                 $("#nameForm").submit(function () {
                     $("#nameForm").hide();
                     $("#answerForm").show();
-                    event.preventDefault();
+                    return false;
                 });

                 $("#answerForm").submit(function () {
@@ -32,7 +32,7 @@
                     $("#thanks").show();
                     $("form").hide();
                     actor = null;
-                    event.preventDefault();
+                    return false;
                 });
             });
         });


added GetMaxInstallGroupNumberWithOffset() to Utils. Will get max number of the list's InstallGroup factored with the category tree view offset

--- RelhaxModpack/RelhaxModpack/Utils/Utils.cs
+++ RelhaxModpack/RelhaxModpack/Utils/Utils.cs
@@ -2034,6 +2034,16 @@
         }

         /// <summary>
+        /// Gets the maximum InstallGroup number from a list of Packages factoring in the offset that a category may apply to it
+        /// </summary>
+        /// <param name="listToCheck">The list of DatabasePackages</param>
+        /// <returns>The maximum InstallGroup number</returns>
+        public static int GetMaxInstallGroupNumberWithOffset(List<DatabasePackage> listToCheck)
+        {
+            return listToCheck.Max(ma => ma.InstallGroupWithOffset);
+        }
+
+        /// <summary>
         /// Gets the maximum PatchGroup number from a list of Packages
         /// </summary>
         /// <param name="listToCheck">The list of DatabasePackages</param>


no lifetime validation

no lifetime validation

--- Grafika.Web/Extensions/JwtOAuthExtensions.cs
+++ Grafika.Web/Extensions/JwtOAuthExtensions.cs
@@ -37,6 +37,7 @@
                     IssuerSigningKey = tokenProvider.SecurityKey,
                     ValidateAudience = false,
                     ValidateIssuer = false,
+                    ValidateLifetime = false,
                     AuthenticationType = "Bearer"
                 },
                 Events = new JwtBearerEvents { OnMessageReceived = FindToken }


removed overriding of default logger factory

--- GridDomain.Node/Actors/GridNodeController.cs
+++ GridDomain.Node/Actors/GridNodeController.cs
@@ -4,7 +4,6 @@
 using GridDomain.CQRS;
 using GridDomain.CQRS.Messaging;
 using GridDomain.CQRS.Messaging.Akka;
-using GridDomain.Logging;
 using GridDomain.Node.AkkaMessaging;
 using GridDomain.Node.AkkaMessaging.Waiting;

@@ -12,7 +11,6 @@
 {
     public class GridNodeController : TypedActor
     {
-        private readonly ISoloLogger _log = LogManager.GetLogger();
         private readonly IPublisher _messagePublisher;
         private readonly IMessageRouteMap _messageRouting;
         private readonly IActorSubscriber _subscriber;
@@ -30,8 +28,6 @@
         public void Handle(Start msg)
         {
             _monitor.IncrementMessagesReceived();
-            LogManager.SetLoggerFactory(new DefaultLoggerFactory());
-
             var system = Context.System;
             var routingActor = system.ActorOf(system.DI().Props(msg.RoutingActorType),msg.RoutingActorType.Name);


Change MOTD button text to "MOTD *updated*" on new MOTD.

--- game/client/ui/shell/motd.cs
+++ game/client/ui/shell/motd.cs
@@ -37,11 +37,13 @@

 	if(MotdWindow.isAwake())
 	{
+		RootMenuMotdButton.setText("MOTD");
 		hilightControl(RootMenuMotdButton, false);
 		$Pref::MOTD::Text = $MOTD::Text;
 	}
 	else if($MOTD::Text !$= $Pref::MOTD::Text)
 	{
+		RootMenuMotdButton.setText("MOTD *updated*");
 		hilightControl(RootMenuMotdButton, true);
 	}
 }


Setting Assembly(File)Version to use with CI

--- IdleStartWatchdog/Properties/AssemblyInfo.cs
+++ IdleStartWatchdog/Properties/AssemblyInfo.cs
@@ -28,4 +28,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.1.0")]
+[assembly: AssemblyFileVersion("1.0.1.0")]


Fixed the bug with fluent scanner not catching exceptions properly

--- Bddify/Core/Scenario.cs
+++ Bddify/Core/Scenario.cs
@@ -60,22 +60,22 @@
             }
             catch (Exception ex)
             {
-                if (ex.InnerException == null)
-                    throw;
+                // ToDo: more thought should be put into this. Is it safe to get the exception?
+                var exception = ex.InnerException ?? ex;

-                if (ex.InnerException is NotImplementedException)
+                if (exception is NotImplementedException)
                 {
                     executionStep.Result = StepExecutionResult.NotImplemented;
-                    executionStep.Exception = ex.InnerException;
+                    executionStep.Exception = exception;
                 }
-                else if (IsInconclusive(ex.InnerException))
+                else if (IsInconclusive(exception))
                 {
                     executionStep.Result = StepExecutionResult.Inconclusive;
-                    executionStep.Exception = ex.InnerException;
+                    executionStep.Exception = exception;
                 }
                 else
                 {
-                    executionStep.Exception = ex.InnerException;
+                    executionStep.Exception = exception;
                     executionStep.Result = StepExecutionResult.Failed;
                 }
             }


Code cleanup

Code cleanup

--- BullsAndCows/Program.cs
+++ BullsAndCows/Program.cs
@@ -49,7 +49,7 @@
     {
         if (position < 0)
         {
-            yield return Enumerable.Repeat(new int[0], guess.Length).ToArray();
+            yield return validValues;
             yield break;
         }

@@ -59,34 +59,30 @@
             var valueForPosition = new[] { guess[position] };
             if (validValues[position].Contains(valueForPosition.Single()))
             {
-                var solutions = solve(validValues, guess, bulls - 1, cows, position - 1).ToArray();
+                var solutionValues = remove(validValues, position, validValues[position].Except(valueForPosition));
+                var solutions = solve(solutionValues, guess, bulls - 1, cows, position - 1).ToArray();
                 foreach (var solution in solutions)
-                {
-                    solution[position] = valueForPosition;
                     yield return solution;
-                }
             }
         }

         validValues = remove(validValues, position, new[] { guess[position] });

         var unspokenGuesses = guess.Distinct();
+        //TODO: Need to strip out guess-values already used as bulls and cows

         if (cows > 0)
         {
             var possibilities = unspokenGuesses.Intersect(validValues[position]);
-            //TODO: Need to strip out guess-values already used as bulls and cows
             foreach (var possibility in possibilities)
             {
                 var valueForPosition = new[] { possibility };
                 if (validValues[position].Contains(valueForPosition.Single()))
                 {
-                    var solutions = solve(validValues, guess, bulls, cows - 1, position - 1).ToArray();
+                    var solutionValues = remove(validValues, position, validValues[position].Except(valueForPosition));
+                    var solutions = solve(solutionValues, guess, bulls, cows - 1, position - 1).ToArray();
                     foreach (var solution in solutions)
-                    {
-                        solution[position] = valueForPosition;
                         yield return solution;
-                    }
                 }
             }
         }
@@ -97,10 +93,7 @@
         {
             var solutions = solve(validValues, guess, bulls, cows, position - 1).ToArray();
             foreach (var solution in solutions)
-            {
-                solution[position] = validValues[position];
                 yield return solution;
-            }
         }
     }


Move from implicit to explicit serialisation of object members

--- KaomojiTray/KaomojiTrayApplicationContext.cs
+++ KaomojiTray/KaomojiTrayApplicationContext.cs
@@ -1,13 +1,8 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
-using System.Linq;
 using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Controls.Primitives;
+using System.Runtime.Serialization;

 namespace KaomojiTray
 {
@@ -50,20 +45,28 @@
     }
   }

+  [DataContract]
   public class KaomojiLibrary
   {
+    [DataMember]
     public List<KaomojiCategory> category { get; set; }
   }

+  [DataContract]
   public class KaomojiCategory
   {
+    [DataMember]
     public string id { get; set; }
+    [DataMember]
     public List<KaomojiSection> sections { get; set; }
   }

+  [DataContract]
   public class KaomojiSection
   {
+    [DataMember]
     public string id { get; set; }
+    [DataMember]
     public List<string> kaomoji { get; set; }
   }
 }