Update frmMain.cs

Update frmMain.cs

Fix file name on ReadDumpExample

--- VBot/frmMain.cs
+++ VBot/frmMain.cs
@@ -402,7 +402,7 @@
         private void ReadDumpExample()
         {
             string line;
-            System.IO.StreamReader file = new System.IO.StreamReader(@"D:\Wikipedia\Dump\w020n90.tar.gz", Encoding.UTF8);
+            System.IO.StreamReader file = new System.IO.StreamReader(@"D:\Wikipedia\Dump\20150427.json", Encoding.UTF8);
             line = file.ReadLine(); // first line is "["
             EntitiesDump item = new EntitiesDump();
             txtPageList.Text = "";


Improve error handling. Add stats for all/curernt view/selected items

--- Vss3WayMerge.cs
+++ Vss3WayMerge.cs
@@ -95,8 +95,13 @@
 				_theirsVss = null;
 			}

-			var theirsSsIni = GetIniPath(textBoxVssIniTheirs.Text);
-			var mineSsIni = GetIniPath(textBoxVssIniMine.Text);
+			var theirsSsIni = GetIniPath(textBoxVssIniTheirs.Text, "'theirs'");
+			if (theirsSsIni == null)
+				return;
+
+			var mineSsIni = GetIniPath(textBoxVssIniMine.Text, "'mine'");
+			if (mineSsIni == null)
+				return;

 			_mineVss = new VSSDatabase();
 			_mineVss.Open(mineSsIni, textBoxMineUser.Text, textBoxMinePwd.Text);
@@ -149,7 +154,7 @@

 		void AddLog(string msg, bool activateLog = true)
 		{
-			textBoxLog.Text += msg + "\r\n";
+			textBoxLog.Text += msg.Replace("\r", "").Replace("\n", "\r\n") + "\r\n";
 			if (activateLog)
 				tabControl.SelectedIndex = 2;
 		}
@@ -451,23 +456,23 @@
 			return localSpec;
 		}

-		public static string GetIniPath(string enteredValue)
+		public string GetIniPath(string enteredValue, string hint)
 		{
 			var ssIni = enteredValue;
-			if (Directory.Exists(ssIni))
+			if (!string.IsNullOrWhiteSpace(ssIni) && Directory.Exists(ssIni))
 			{
 				ssIni = Path.Combine(ssIni, "srcsafe.ini");

 				if (!File.Exists(ssIni))
 				{
-					MessageBox.Show("srcsafe.ini not found in " + enteredValue);
+					ShowError("srcsafe.ini not found in '" + enteredValue + "' path for " + hint);
 					return null;
 				}
 			}

 			if (Path.GetFileName(ssIni).ToLowerInvariant() != "srcsafe.ini")
 			{
-				MessageBox.Show("Should be specified VSS dir or scrsafe.ini path");
+				ShowError("Should be specified VSS dir or scrsafe.ini path for " + hint);
 				return null;
 			}

@@ -1197,8 +1202,12 @@

 		void buttonFindJournal_Click(object sender, EventArgs e)
 		{
+			var ssIniPath = GetIniPath(textBoxVssIniTheirs.Text, "'theirs'");
+			if (ssIniPath == null)
+				return;
+
 			// find journal file:
-			textBoxJournal.Text = File.ReadAllLines(textBoxVssIniTheirs.Text)
+			textBoxJournal.Text = File.ReadAllLines(ssIniPath)
 				.Select(l => l.Trim().ToLowerInvariant())
 				.Where(l => l.StartsWith("journal_file"))
 				.Select(l => l.Substring(l.IndexOf('=') + 1).Trim())
@@ -1279,15 +1288,42 @@

 		void statsToolStripMenuItem_Click(object sender, EventArgs e)
 		{
-			var total = _listItems.Count;
-			var unmergeable = _listItems.Count(ca => ca.Status == Status.Unmergeable);
-			var mergeable = _listItems.Count(ca => ca.Status != Status.Unmergeable);
-			var mergedAndResolved = _listItems.Count(ca => ca.Status == Status.Merged || ca.Status == Status.MergedNoChanges || ca.Status == Status.ResolvedAsMine || ca.Status == Status.ResolvedAsTheirs);
-			var conflicted = _listItems.Count(ca => ca.Status == Status.Conflicted);
-			var pending = _listItems.Count(ca => ca.Status == Status.Nothing);
-			var errored = _listItems.Count(ca => ca.Status == Status.Error);
-
 			var sb = new StringBuilder();
+			sb.AppendLine("=== All items ===");
+			CalcStats(_listItemsNonFiltered, sb);
+
+			if (_listItems.Count != _listItemsNonFiltered.Count)
+			{
+				sb.AppendLine("\n");
+				sb.AppendLine("=== Filtered view ===");
+				CalcStats(_listItems, sb);
+			}
+			if (listViewChanged.SelectedIndices.Count != 0 && listViewChanged.SelectedIndices.Count != _listItems.Count)
+			{
+				sb.AppendLine("\n");
+				sb.AppendLine("=== Selected items ===");
+				CalcStats(listViewChanged.SelectedIndices.Cast<int>().Select(i => _listItems[i]).ToList(), sb);
+			}
+
+			AddLog(sb.ToString());
+
+			MessageBox.Show(this, sb.ToString(), "Stats", MessageBoxButtons.OK, MessageBoxIcon.Information);
+		}
+
+		static void CalcStats(ICollection<VssChangeAtom> list, StringBuilder sb)
+		{
+			var total = list.Count;
+			var unmergeable = list.Count(ca => ca.Status == Status.Unmergeable);
+			var mergeable = list.Count(ca => ca.Status != Status.Unmergeable);
+			var mergedAndResolved =
+				list.Count(
+					ca =>
+					ca.Status == Status.Merged || ca.Status == Status.MergedNoChanges || ca.Status == Status.ResolvedAsMine ||
+					ca.Status == Status.ResolvedAsTheirs);
+			var conflicted = list.Count(ca => ca.Status == Status.Conflicted);
+			var pending = list.Count(ca => ca.Status == Status.Nothing);
+			var errored = list.Count(ca => ca.Status == Status.Error);
+
 			sb.AppendFormat("Total items: {0}:\r\n", total);
 			sb.AppendFormat("    Unmergeable: {0}\r\n", unmergeable);
 			sb.AppendFormat("    Mergeable: {0}:\r\n", mergeable);
@@ -1295,10 +1331,6 @@
 			sb.AppendFormat("        Conflicted: {0}\r\n", conflicted);
 			sb.AppendFormat("        Erroneous: {0}\r\n", errored);
 			sb.AppendFormat("        Pending for merge: {0}", pending);
-
-			AddLog(sb.ToString());
-
-			MessageBox.Show(this, sb.ToString(), "Stats", MessageBoxButtons.OK, MessageBoxIcon.Information);
 		}

 		#region Files filter


Added SlideCompleted event to SlidingSprite

--- FontEffectsLib/SpriteTypes/SlidingSprite.cs
+++ FontEffectsLib/SpriteTypes/SlidingSprite.cs
@@ -5,12 +5,23 @@
 using FontEffectsLib.SpriteTypes;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
+using FontEffectsLib.CoreTypes;

 namespace FontEffectsLib.SpriteTypes
 {
     public class SlidingSprite : GameSprite
     {
         protected Vector2? _slideTo;
+
+        /// <summary>
+        /// Delegate type for SlideCompleted event
+        /// </summary>
+        public delegate void SlideCompletedState();
+
+        /// <summary>
+        /// Raised when SlidingSprite completes sliding to the SlideTo position
+        /// </summary>
+        public SlideCompletedState SlideCompleted;

         /// <summary>
         /// Slide to position. Default is null (not sliding).
@@ -65,6 +76,13 @@
                 _slideTo = null;
                 _currentStep = null;

+                //Raise SlideCompleted event if there are any subscribers
+                SlideCompletedState handler = SlideCompleted;
+                if (handler != null)
+                {
+                    handler();
+                }
+
                 return;
             }


Fixed the edit/reply buttons being hard to click sometimes.

--- Forum/Views/Messages/_DisplayMessage.cshtml
+++ Forum/Views/Messages/_DisplayMessage.cshtml
@@ -25,31 +25,31 @@
 			@if (Model.ShowControls) {

 					@if (Model.CanThought) {
-
+

 					}

 					@if (Model.CanReply) {
-
+

 					}

 					@if (Model.CanEdit) {
-
+

 					}

 					@if (Model.CanDelete) {
 						@if (Model.ParentId == 0) {
-
+

 						}
 						else {
-
+

 						}


remove commented code

remove commented code

--- src/Radical/ChangeTracking/ChangeTrackingService.cs
+++ src/Radical/ChangeTracking/ChangeTrackingService.cs
@@ -361,7 +361,7 @@
             lock (SyncRoot)
             {
                 var last = backwardChangesStack.LastOrDefault();
-                return /*this.EnsureIsDefined( bookmark ) &&*/ (bookmark.Position != last || transientEntities
+                return (bookmark.Position != last || transientEntities
                     .Any(kvp => kvp.Value && !bookmark.TransientEntities.Contains(kvp.Key)));
             }
         }


Fix #678

Fix #678

--- src/ScriptEngine.HostedScript/Library/Http/HttpConnectionContext.cs
+++ src/ScriptEngine.HostedScript/Library/Http/HttpConnectionContext.cs
@@ -245,7 +245,6 @@
         {
             var webRequest = CreateRequest(request.ResourceAddress);
             webRequest.Method = method;
-            webRequest.KeepAlive = false;
             SetRequestHeaders(request, webRequest);
             SetRequestBody(request, webRequest);

@@ -298,7 +297,7 @@
                 var key = item.Key.AsString();
                 var value = item.Value.AsString();

-                switch(key.ToUpperInvariant())
+                switch (key.ToUpperInvariant())
                 {
                     case "CONTENT-TYPE":
                         webRequest.ContentType = value;
@@ -323,7 +322,18 @@
                         webRequest.TransferEncoding = value;
                         break;
                     case "CONNECTION":
-                        webRequest.Connection = value;
+                        if (value.Equals("KEEP-ALIVE", StringComparison.OrdinalIgnoreCase))
+                        {
+                            webRequest.KeepAlive = true;
+                        }
+                        else if (value.Equals("CLOSE", StringComparison.OrdinalIgnoreCase))
+                        {
+                            webRequest.KeepAlive = false;
+                        }
+                        else
+                        {
+                            webRequest.Connection = value;
+                        }
                         break;
                     case "DATE":
                         try


refs #43 Allow the SearchTransition method to work :footprints:

--- GeroMachine/GeroMachine/TransitionMatrix.cs
+++ GeroMachine/GeroMachine/TransitionMatrix.cs
@@ -42,7 +42,12 @@
 		/// 状態遷移表に存在しない.</exception>
 		public Transition SearchTransition(State currentState, Trigger trigger)
 		{
-			throw new NotImplementedException();
+			if (MatrixData[currentState].ContainsKey(trigger))
+			{
+				return MatrixData[currentState][trigger];
+			}
+
+			return null;
 		}
 	}
 }


Increase version number

Increase version number

--- GitAutoUpdateGUI/Properties/AssemblyInfo.cs
+++ GitAutoUpdateGUI/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@
 // Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
 // en utilisant '*', comme indiqué ci-dessous :
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.7.0.0")]
-[assembly: AssemblyFileVersion("1.7.0.0")]
+[assembly: AssemblyVersion("1.7.1.0")]
+[assembly: AssemblyFileVersion("1.7.1.0")]


fixes path to TestRunner scene

fixes path to TestRunner scene

--- GivenWhenUnity/Assets/Editor/TestResults.cs
+++ GivenWhenUnity/Assets/Editor/TestResults.cs
@@ -158,7 +158,7 @@
         previousScene = EditorApplication.currentScene;
         EditorApplication.SaveScene();

-        EditorApplication.OpenScene("Assets/Scenes/packages/invisibledrygoods/BDD/TestRunner.unity");
+        EditorApplication.OpenScene("Assets/Scenes/packages/invisibledrygoods/GivenWhenUnity/TestRunner.unity");
         if (EditorApplication.currentScene == previousScene)
         {
             EditorApplication.OpenScene("Assets/Scenes/TestRunner.unity");


Improve message about wrong system time

Improve message about wrong system time

--- src/BloomExe/WebLibraryIntegration/BookTransfer.cs
+++ src/BloomExe/WebLibraryIntegration/BookTransfer.cs
@@ -395,7 +395,7 @@
 					if (e.Message.Contains("The difference between the request time and the current time is too large"))
 					{
 						progress.WriteError(LocalizationManager.GetString("PublishTab.Upload.TimeProblem",
-							"There was a problem uploading your book. This is probably because the system time on your computer is not correct for the timezone the computer is set to."));
+							"There was a problem uploading your book. This is probably because your computer is set to use the wrong timezone or your system time is badly wrong. See http://www.di-mgt.com.au/wclock/help/wclo_setsysclock.html for how to fix this."));
 						if (!UseSandbox)
 							Analytics.Track("UploadBook-Failure-SystemTime");
 					}


don't cascade errors in assignments

don't cascade errors in assignments

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@2181 2c1201b4-01cd-e047-a400-b836ae1fbc61

--- src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
+++ src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
@@ -4672,6 +4672,12 @@

 		bool AssertTypeCompatibility(Node sourceNode, IType expectedType, IType actualType)
 		{
+			if (TypeSystemServices.IsError(expectedType)
+				|| TypeSystemServices.IsError(actualType))
+			{
+				return false;
+			}
+
 			if (!TypeSystemServices.AreTypesRelated(expectedType, actualType))
 			{
 				Error(CompilerErrorFactory.IncompatibleExpressionType(sourceNode, expectedType.ToString(), actualType.ToString()));


Added try/catch to prevent logging errors from crashing service.

--- HelloSvc/HelloSvc/Logging/EventLogLogger.cs
+++ HelloSvc/HelloSvc/Logging/EventLogLogger.cs
@@ -19,21 +19,42 @@

 		public void Message(string message)
 		{
-			Log.WriteEntry(message);
+			try
+			{
+				Log.WriteEntry(message);
+			}
+			catch
+			{
+				// Suppress. Nothing can be done except to not let logging crash the service.
+			}
 		}

 		public void ExceptionWithMessage(Exception ex, string message)
 		{
-			var formatter = new StringBuilder(message);
-			formatter.AppendLine();
-			formatter.AppendLine(ex.ToString());
-
-			Log.WriteEntry(formatter.ToString());
+			try
+			{
+				var formatter = new StringBuilder(message);
+				formatter.AppendLine();
+				formatter.AppendLine(ex.ToString());
+
+				Log.WriteEntry(formatter.ToString());
+			}
+			catch
+			{
+				// Suppress. Nothing can be done except to not let logging crash the service.
+			}
 		}

 		public void ExceptionAlone(Exception ex)
 		{
-			Log.WriteEntry(ex.ToString());
+			try
+			{
+				Log.WriteEntry(ex.ToString());
+			}
+			catch
+			{
+				// Suppress. Nothing can be done except to not let logging crash the service.
+			}
 		}
 	}
 }


Cloning TFS Folders

Cloning TFS Folders

These changes will allow users to clone TFS folders as well as TFS branches IF the branch strategy is none

--- src/GitTfs/Commands/Clone.cs
+++ src/GitTfs/Commands/Clone.cs
@@ -169,7 +169,7 @@
                     throw new GitTfsException("error: the path " + tfsRepositoryPath + " you want to clone doesn't exist!")
                         .WithRecommendation("To discover which branch to clone, you could use the command :\ngit tfs list-remote-branches " + remote.TfsUrl);

-                if (!remote.Tfs.CanGetBranchInformation)
+                if (!remote.Tfs.CanGetBranchInformation || _fetch.BranchStrategy == BranchStrategy.None)
                     return;
                 var tfsTrunkRepository = remote.Tfs.GetRootTfsBranchForRemotePath(tfsRepositoryPath, false);
                 if (tfsTrunkRepository == null)


Simplify tests, remove duplicate test

Simplify tests, remove duplicate test

--- src/System.Drawing.Common/tests/mono/System.Imaging/MetafileTest.cs
+++ src/System.Drawing.Common/tests/mono/System.Imaging/MetafileTest.cs
@@ -48,12 +48,6 @@
         public const string Emf = "milkmateya01.emf";

         [ConditionalFact(Helpers.GdiplusIsAvailable)]
-        public void Metafile_String_Empty()
-        {
-            Assert.Throws<ArgumentException>(() => new Metafile(String.Empty));
-        }
-
-        [ConditionalFact(Helpers.GdiplusIsAvailable)]
         public void Metafile_String()
         {
             string filename = Helpers.GetTestBitmapPath(WmfPlaceable);
@@ -178,18 +172,7 @@
             Assert.Equal(0, header.Bounds.X);
             Assert.Equal(0, header.Bounds.Y);

-            try
-            {
-                Assert.NotNull(header.WmfHeader);
-                Assert.True(false, "WmfHeader didn't throw an ArgumentException");
-            }
-            catch (ArgumentException)
-            {
-            }
-            catch (Exception e)
-            {
-                Assert.True(false, "WmfHeader didn't throw an ArgumentException but: " + e.ToString());
-            }
+            Assert.Throws<ArgumentException>(() => header.WmfHeader);

             Assert.False(header.IsDisplay());
             Assert.True(header.IsEmf());


let TypeSystemServices and DowncastPermissions decide if the downcast is allowed or not

--- src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
+++ src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
@@ -6474,9 +6474,6 @@

 		bool CanBeReachedFrom(Node anchor, IType expectedType, IType actualType)
 		{
-            if (TypeSystemServices.IsSystemObject(actualType))
-                return true;
-
 			bool byDowncast;
 			bool result = TypeSystemServices.CanBeReachedFrom(expectedType, actualType, out byDowncast);
 			if (!result)


Encode oauth_token. Fixes #1495

Encode oauth_token. Fixes #1495

--- src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs
+++ src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs
@@ -10,7 +10,7 @@
 //   distributed under the License is distributed on an "AS IS" BASIS,
 //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 //   See the License for the specific language governing permissions and
-//   limitations under the License.
+//   limitations under the License.

 using System;
 using System.Collections.Generic;
@@ -215,7 +215,7 @@
                 new WebPair("oauth_version", Version ?? "1.0")
             };

-            if (!Token.IsEmpty()) authParameters.Add(new WebPair("oauth_token", Token));
+            if (!Token.IsEmpty()) authParameters.Add(new WebPair("oauth_token", Token, true));

             if (!CallbackUrl.IsEmpty()) authParameters.Add(new WebPair("oauth_callback", CallbackUrl, true));


Added locking mechanism

Added locking mechanism

--- LMP.MasterServer/Structure/Server.cs
+++ LMP.MasterServer/Structure/Server.cs
@@ -2,14 +2,18 @@
 using LunaCommon.Message.Data.MasterServer;
 using LunaCommon.Time;
 using System;
+using System.Collections.Concurrent;
 using System.Linq;
 using System.Net;
 using System.Net.Http;
+using System.Threading.Tasks;

 namespace LMP.MasterServer.Structure
 {
     public class Server
     {
+        private static readonly ConcurrentDictionary<IPEndPoint, object> LockDictionary = new ConcurrentDictionary<IPEndPoint, object>();
+
         private static readonly TimeoutConcurrentDictionary<IPEndPoint, string> EndpointCountries =
             new TimeoutConcurrentDictionary<IPEndPoint, string>(TimeSpan.FromHours(24).TotalMilliseconds);

@@ -109,27 +113,33 @@
             }
         }

-        private static async void SetCountryFromEndpoint(ServerInfo server, IPEndPoint externalEndpoint)
+        private static void SetCountryFromEndpoint(ServerInfo server, IPEndPoint externalEndpoint)
         {
-            try
+            Task.Run(() =>
             {
-                if (EndpointCountries.TryGet(externalEndpoint, out var countryCode))
+                lock (LockDictionary.GetOrAdd(externalEndpoint, new object()))
                 {
-                    server.Country = countryCode;
-                }
-                else
-                {
-                    using (var client = new HttpClient())
+                    try
                     {
-                        server.Country = await client.GetStringAsync($"https://ipapi.co/{externalEndpoint.Address}/country/");
-                        EndpointCountries.TryAdd(externalEndpoint, server.Country);
+                        if (EndpointCountries.TryGet(externalEndpoint, out var countryCode))
+                        {
+                            server.Country = countryCode;
+                        }
+                        else
+                        {
+                            using (var client = new HttpClient())
+                            {
+                                server.Country = client.GetStringAsync($"https://ipapi.co/{externalEndpoint.Address}/country/").Result;
+                                EndpointCountries.TryAdd(externalEndpoint, server.Country);
+                            }
+                        }
+                    }
+                    catch (Exception)
+                    {
+                        // ignored
                     }
                 }
-            }
-            catch (Exception)
-            {
-                // ignored
-            }
+            });
         }

         public static bool IsLocalIpAddress(IPAddress host)


add more logging on authentication controller

--- source/Core/Endpoints/AuthenticationController.cs
+++ source/Core/Endpoints/AuthenticationController.cs
@@ -216,6 +216,8 @@
                 return await RenderLoginPage(signInMessage, signin, authResult.ErrorMessage, model.Username, model.RememberMe == true);
             }

+            Logger.Info("Login credentials successfully validated by user service");
+
             eventService.RaiseLocalLoginSuccessEvent(model.Username, signin, signInMessage, authResult);

             lastUserNameCookie.SetValue(model.Username);
@@ -268,6 +270,8 @@
             {
                 RedirectUri = Url.Route(Constants.RouteNames.LoginExternalCallback, null)
             };
+
+            Logger.Info("Triggering challenge for external identity provider");

             // add the id to the dictionary so we can recall the cookie id on the callback
             authProp.Dictionary.Add(Constants.Authentication.SigninId, signin);
@@ -340,6 +344,8 @@
                 return await RenderLoginPage(signInMessage, signInId, authResult.ErrorMessage);
             }

+            Logger.Info("External identity successfully validated by user service");
+
             eventService.RaiseExternalLoginSuccessEvent(externalIdentity, signInId, signInMessage, authResult);

             return SignInAndRedirect(signInMessage, signInId, authResult);
@@ -432,6 +438,8 @@
                     Claims = user.Claims
                 };

+                Logger.InfoFormat("external user provider: {0}, provider ID: {1}", externalId.Provider, externalId.ProviderId);
+
                 result = await userService.AuthenticateExternalAsync(externalId, signInMessage);

                 if (result == null)
@@ -453,6 +461,8 @@
                     return await RenderLoginPage(signInMessage, signInId, result.ErrorMessage);
                 }

+                Logger.Info("External identity successfully validated by user service");
+
                 eventService.RaiseExternalLoginSuccessEvent(externalId, signInId, signInMessage, result);
             }

@@ -495,12 +505,16 @@
         [ValidateAntiForgeryToken]
         public async Task<IHttpActionResult> Logout(string id = null)
         {
+            Logger.Info("Logout endpoint submitted");
+
             var user = (ClaimsPrincipal)User;
             if (user != null && user.Identity.IsAuthenticated)
             {
                 var sub = user.GetSubjectId();
                 Logger.InfoFormat("Logout requested for subject: {0}", sub);
             }
+
+            Logger.Info("Clearing cookies");

             sessionCookie.ClearSessionId();
             signOutMessageCookie.Clear(id);


preserve lexical info for event reference

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@3482 2c1201b4-01cd-e047-a400-b836ae1fbc61

--- src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
+++ src/Boo.Lang.Compiler/Steps/ProcessMethodBodies.cs
@@ -3824,34 +3824,29 @@
 				 || EntityType.Ambiguous == entity.EntityType))
 			{
 				BindEventSubscription(node);
-			}
-			else
-			{
-				BindInPlaceArithmeticOperator(node);
-			}
+			    return;
+			}
+
+            BindInPlaceArithmeticOperator(node);
 		}

 		void BindEventSubscription(BinaryExpression node)
 		{
-			IEntity tag = GetEntity(node.Left);
-			if (EntityType.Event != tag.EntityType)
-			{
-				if (EntityType.Ambiguous == tag.EntityType)
-				{
-					IList found = ((Ambiguous)tag).Select(IsPublicEvent);
-					if (found.Count != 1)
-					{
-						tag = null;
-					}
-					else
-					{
-						tag = (IEntity)found[0];
-						Bind(node.Left, tag);
-					}
-				}
-			}
-
-			IEvent eventInfo = (IEvent)tag;
+			IEntity entity = GetEntity(node.Left);
+		    if (EntityType.Ambiguous == entity.EntityType)
+		    {
+		        IList found = ((Ambiguous) entity).Select(IsPublicEvent);
+		        if (found.Count != 1)
+		        {
+		            Error(node);
+                    return;
+		        }
+
+                entity = (IEntity) found[0];
+                Bind(node.Left, entity);
+		    }
+
+		    IEvent eventInfo = (IEvent)entity;
 			IType rtype = GetExpressionType(node.Right);
 			if (!AssertDelegateArgument(node, eventInfo, rtype))
 			{
@@ -3879,10 +3874,11 @@
 				}
 			}

-			MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation(
-				((MemberReferenceExpression)node.Left).Target,
-				method,
-				node.Right);
+		    var methodTarget = CodeBuilder.CreateMemberReference(node.Left.LexicalInfo, ((MemberReferenceExpression) node.Left).Target, method);
+		    var mie = new MethodInvocationExpression(methodTarget);
+		    mie.Arguments.Add(node.Right);
+            BindExpressionType(mie, method.ReturnType);
+
 			node.ParentNode.Replace(node, mie);
 		}


Added link to correct page

Added link to correct page

--- src/SFA.DAS.EAS.Web/Views/EmployerTeam/Index.cshtml
+++ src/SFA.DAS.EAS.Web/Views/EmployerTeam/Index.cshtml
@@ -99,7 +99,7 @@

Start adding apprentices now

                                                 break;
                                             case "ApprenticeChangesToReview":
-
@task.ItemsDueCount apprentice change@(task.ItemsDueCount > 1 ? "s" : "") to review View changes

+
@task.ItemsDueCount apprentice change@(task.ItemsDueCount > 1 ? "s" : "") to review View changes

                                                 break;
                                             case "CohortRequestReadyForApproval":

@task.ItemsDueCount cohort request@(task.ItemsDueCount > 1 ? "s" : "") ready for approval View cohorts


#9 - Web API ExceptionLogger should not filter exceptions based on whether the calling HttpHandler is top-level or not.

--- src/LogJam.WebApi/LogJamExceptionLogger.cs
+++ src/LogJam.WebApi/LogJamExceptionLogger.cs
@@ -41,25 +41,21 @@

 		public Task LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken)
 		{
-			if (context.CatchBlock.IsTopLevel)
+			var request = context.Request;
+			var exception = context.Exception;
+
+			if (request.HasRequestExceptionBeenLogged(exception))
 			{
-				// Only log top-level exceptions
-				var request = context.Request;
-				var exception = context.Exception;
-
-				if (request.HasRequestExceptionBeenLogged(exception))
-				{
-					// Don't repeatedly log the same exception
-					_tracer.Error("Exception thrown handling Web API request: {0} {1}\n    (exception already logged)", request.Method,
-						request.RequestUri.OriginalString);
-				}
-				else
-				{
-					// exception hasn't previously been logged
-					_tracer.Error(exception, "Exception thrown handling Web API request: {0} {1}", request.Method,
-						request.RequestUri.OriginalString);
-					request.LoggedRequestException(exception);
-				}
+				// Don't repeatedly log the same exception
+				_tracer.Error("Exception thrown handling Web API request: {0} {1}\n    (exception already logged)", request.Method,
+					request.RequestUri.OriginalString);
+			}
+			else
+			{
+				// exception hasn't previously been logged
+				_tracer.Error(exception, "Exception thrown handling Web API request: {0} {1}", request.Method,
+					request.RequestUri.OriginalString);
+				request.LoggedRequestException(exception);
 			}

 			return TaskHelper.Completed;


[gh-77] Added fallback for x-target-language.

--- source/Server/MirrorSharp/SetOptionsFromClient.cs
+++ source/Server/MirrorSharp/SetOptionsFromClient.cs
@@ -7,7 +7,7 @@
         private const string Target = "x-target";

         public bool TrySetOption(IWorkSession session, string name, string value) {
-            if (name != Target)
+            if (name != Target && name != "x-target-language" /* TODO: remove once all branches and main are updated */)
                 return false;

             session.SetTargetName(value);


Wildcard matching backtrack

Wildcard matching backtrack

--- LeetCode/remote/wildcard_matching.cs
+++ LeetCode/remote/wildcard_matching.cs
@@ -33,3 +33,43 @@
         return dp[0, 0];
     }
 }
+
+//  Poor man's DP but still TLE
+public class Solution {
+    public bool IsMatch(string s, string p, bool[,] hash = null) {
+        if (hash == null)
+        {
+            hash = new bool[s.Length + 1, p.Length + 1];
+        }
+
+        if (String.IsNullOrWhiteSpace(s))
+        {
+            hash[s.Length, p.Length] = String.IsNullOrWhiteSpace(p) || p == "*";
+            return hash[s.Length, p.Length];
+        }
+
+        if (String.IsNullOrWhiteSpace(p))
+        {
+            hash[s.Length, p.Length] = p == s;
+            return hash[s.Length, p.Length];
+        }
+
+        if (p[0] == '?' || s[0] == p[0])
+        {
+            hash[s.Length, p.Length] = IsMatch(s.Substring(1), p.Substring(1), hash);
+            return hash[s.Length, p.Length];
+        }
+
+        if (p[0] == '*')
+        {
+            hash[s.Length, p.Length] = Enumerable
+                                       .Range(0, s.Length)
+                                       .Select(x => IsMatch(s.Substring(x), p.Substring(1)))
+                                       .Aggregate((acc, x) => acc || x);
+            return hash[s.Length, p.Length];
+        }
+
+        hash[s.Length, p.Length] = false;
+        return hash[s.Length, p.Length];
+    }
+}


support uInt32

support uInt32

--- src/Umbraco.Web/PublishedCache/NuCache/DataSource/SerializerBase.cs
+++ src/Umbraco.Web/PublishedCache/NuCache/DataSource/SerializerBase.cs
@@ -10,6 +10,7 @@
         private const char PrefixString = 'S';
         private const char PrefixInt32 = 'I';
         private const char PrefixUInt16 = 'H';
+        private const char PrefixUInt32 = 'J';
         private const char PrefixLong = 'L';
         private const char PrefixFloat = 'F';
         private const char PrefixDouble = 'B';
@@ -68,6 +69,8 @@
                     return PrimitiveSerializer.Int32.ReadFrom(stream);
                 case PrefixUInt16:
                     return PrimitiveSerializer.UInt16.ReadFrom(stream);
+                case PrefixUInt32:
+                    return PrimitiveSerializer.UInt32.ReadFrom(stream);
                 case PrefixByte:
                     return PrimitiveSerializer.Byte.ReadFrom(stream);
                 case PrefixLong:
@@ -129,6 +132,11 @@
                 PrimitiveSerializer.Char.WriteTo(PrefixDateTime, stream);
                 PrimitiveSerializer.DateTime.WriteTo(dateValue, stream);
             }
+            else if (value is uint uInt32Value)
+            {
+                PrimitiveSerializer.Char.WriteTo(PrefixUInt32, stream);
+                PrimitiveSerializer.UInt32.WriteTo(uInt32Value, stream);
+            }
             else
                 throw new NotSupportedException("Value type " + value.GetType().FullName + " cannot be serialized.");
         }


StyleCop the fix!

StyleCop the fix!

--- src/Shinoa/Services/TimedServices/AnilistService.cs
+++ src/Shinoa/Services/TimedServices/AnilistService.cs
@@ -74,7 +74,7 @@
         {
             try
             {
-                var responseText = await (await httpClient.GetAsync($"{query}?access_token={accessToken}")).Content.ReadAsStringAsync();
+                var responseText = await (await this.httpClient.GetAsync($"{query}?access_token={this.accessToken}")).Content.ReadAsStringAsync();
                 dynamic responseObject = JsonConvert.DeserializeObject(responseText);

                 dynamic firstResult = responseObject[0];


Simplify code

Simplify code

--- src/Workspaces/CSharp/Portable/CodeGeneration/NamedTypeGenerator.cs
+++ src/Workspaces/CSharp/Portable/CodeGeneration/NamedTypeGenerator.cs
@@ -104,6 +104,9 @@
             ImmutableArray<ISymbol> members,
             CancellationToken cancellationToken)
         {
+            if (!options.GenerateMembers)
+                members = ImmutableArray<ISymbol>.Empty;
+
             // For a record, add record parameters if we have a primary constructor.
             var primaryConstructor = members.OfType<IMethodSymbol>().FirstOrDefault(m => CodeGenerationConstructorInfo.GetIsPrimaryConstructor(m));
             if (primaryConstructor != null)
@@ -132,10 +135,8 @@
                 recordDeclaration = recordDeclaration.WithOpenBraceToken(SyntaxFactory.Token(SyntaxKind.OpenBraceToken))
                                                      .WithCloseBraceToken(SyntaxFactory.Token(SyntaxKind.CloseBraceToken))
                                                      .WithSemicolonToken(default);
-            }
-
-            if (options.GenerateMembers)
                 recordDeclaration = service.AddMembers(recordDeclaration, members, options, cancellationToken);
+            }

             return recordDeclaration;
         }


Check that segwit activates on a c# node (#1073)

* Check that segwit activates on a c# node

* Remove wallet creation and fix comments

* Update some comments

* Act on review

--- src/Stratis.Bitcoin.IntegrationTests/SegWitTests.cs
+++ src/Stratis.Bitcoin.IntegrationTests/SegWitTests.cs
@@ -1,26 +1,24 @@
-using NBitcoin;
+using System;
+using NBitcoin;
 using NBitcoin.RPC;
 using Stratis.Bitcoin.Base.Deployments;
-using Stratis.Bitcoin.Features.Api;
 using Stratis.Bitcoin.Features.BlockStore;
 using Stratis.Bitcoin.Features.Consensus;
 using Stratis.Bitcoin.Features.Consensus.Interfaces;
 using Stratis.Bitcoin.Features.MemoryPool;
 using Stratis.Bitcoin.Features.Miner;
-using Stratis.Bitcoin.Features.Notifications;
 using Stratis.Bitcoin.Features.RPC;
 using Stratis.Bitcoin.Features.Wallet;
-using Stratis.Bitcoin.Features.Wallet.Interfaces;
 using Stratis.Bitcoin.IntegrationTests.EnvironmentMockUpHelpers;
+using Stratis.Bitcoin.Utilities.Extensions;
 using Xunit;
-using static NBitcoin.Consensus;

 namespace Stratis.Bitcoin.IntegrationTests
 {
     public class SegWitTests
     {
         [Fact]
-        public void TestSegwitActivation()
+        public void TestSegwit_MinedOnCore_ActivatedOn_StratisNode()
         {
             using (NodeBuilder builder = NodeBuilder.Create(version: "0.15.1"))
             {
@@ -30,44 +28,68 @@
                 coreNode.ConfigParameters.AddOrReplace("printtoconsole", "0");
                 coreNode.Start();

-                CoreNode node1 = builder.CreateStratisPowNode(true, fullNodeBuilder =>
+                CoreNode stratisNode = builder.CreateStratisPowNode(true, fullNodeBuilder =>
                 {
                     fullNodeBuilder
                         .UseConsensus()
                         .UseBlockStore()
+                        .UseWallet()
                         .UseMempool()
-                        .UseBlockNotification()
-                        .UseTransactionNotification()
                         .AddMining()
-                        .UseWallet()
-                        .UseApi()
                         .AddRPC();
                 });

-                WalletManager wm1 = node1.FullNode.NodeService<IWalletManager>() as WalletManager;
-                wm1.CreateWallet("Test1", "alice1");
-
-                RPCClient rpc1 = node1.CreateRPCClient();
+                RPCClient stratisNodeRpc = stratisNode.CreateRPCClient();
                 RPCClient coreRpc = coreNode.CreateRPCClient();

-                coreRpc.AddNode(node1.Endpoint, false);
-                rpc1.AddNode(coreNode.Endpoint, false);
+                coreRpc.AddNode(stratisNode.Endpoint, false);
+                stratisNodeRpc.AddNode(coreNode.Endpoint, false);

-                coreRpc.Generate(450);
+                // core (in version 0.15.1) only mines segwit blocks above a certain height on regtest
+                // future versions of core will change that behaviour so this test may need to be changed in the future
+                // see issue for more details https://github.com/stratisproject/StratisBitcoinFullNode/issues/1028
+                BIP9DeploymentsParameters prevSegwitDeployment = Network.RegTest.Consensus.BIP9Deployments[BIP9Deployments.Segwit];
+                Network.RegTest.Consensus.BIP9Deployments[BIP9Deployments.Segwit] = new BIP9DeploymentsParameters(1, 0, DateTime.Now.AddDays(50).ToUnixTimestamp());

-                BIP9DeploymentsArray bip9Constants = node1.FullNode.Network.Consensus.BIP9Deployments;
-                IConsensusLoop consensusLoop = node1.FullNode.NodeService<IConsensusLoop>();
-                ThresholdState[] bip9State = consensusLoop.NodeDeployments.BIP9.GetStates(node1.FullNode.Chain.Tip.Previous);
+                try
+                {
+                    // generate 450 blocks, block 431 will be segwit activated.
+                    coreRpc.Generate(450);

-                Money amount = new Money(5.0m, MoneyUnit.BTC);
-                HdAddress destination1 = wm1.GetUnusedAddress(new WalletAccountReference("alice1", "account 0"));
+                    TestHelper.WaitLoop(() => stratisNode.CreateRPCClient().GetBestBlockHash() == coreNode.CreateRPCClient().GetBestBlockHash());

-                coreRpc.SendToAddress(BitcoinAddress.Create(destination1.Address, Network.RegTest), amount);
+                    // segwit activation on Bitcoin regtest.
+                    // - On regtest deployment state changes every 144 block, the threshold for activating a rule is 108 blocks.
+                    // segwit deployment status should be:
+                    // - Defined up to block 142.
+                    // - Started at block 143 to block 286 .
+                    // - LockedIn 287 (as segwit should already be signaled in blocks).
+                    // - Active at block 431.

-                coreRpc.Generate(1);
+                    IConsensusLoop consensusLoop = stratisNode.FullNode.NodeService<IConsensusLoop>();
+                    ThresholdState[] segwitDefinedState = consensusLoop.NodeDeployments.BIP9.GetStates(stratisNode.FullNode.Chain.GetBlock(142));
+                    ThresholdState[] segwitStartedState = consensusLoop.NodeDeployments.BIP9.GetStates(stratisNode.FullNode.Chain.GetBlock(143));
+                    ThresholdState[] segwitLockedInState = consensusLoop.NodeDeployments.BIP9.GetStates(stratisNode.FullNode.Chain.GetBlock(287));
+                    ThresholdState[] segwitActiveState = consensusLoop.NodeDeployments.BIP9.GetStates(stratisNode.FullNode.Chain.GetBlock(431));

-                Assert.Equal(ThresholdState.Active, bip9State.GetValue((int)BIP9Deployments.Segwit));
+                    // check that segwit is got activated at block 431
+                    Assert.Equal(ThresholdState.Defined, segwitDefinedState.GetValue((int)BIP9Deployments.Segwit));
+                    Assert.Equal(ThresholdState.Started, segwitStartedState.GetValue((int)BIP9Deployments.Segwit));
+                    Assert.Equal(ThresholdState.LockedIn, segwitLockedInState.GetValue((int)BIP9Deployments.Segwit));
+                    Assert.Equal(ThresholdState.Active, segwitActiveState.GetValue((int)BIP9Deployments.Segwit));
+                }
+                finally
+                {
+                    Network.RegTest.Consensus.BIP9Deployments[BIP9Deployments.Segwit] = prevSegwitDeployment;
+                }
             }
+        }
+
+        private void TestSegwit_MinedOnStratisNode_ActivatedOn_CoreNode()
+        {
+            // TODO: mine segwit onh a stratis node on the bitcoin network
+            // write a tests that mines segwit blocks on the stratis node
+            // and signals them to a core not, then segwit will get activated on core
         }
     }
 }


Fix for MD_ImageDescription_Type

Fix for MD_ImageDescription_Type

--- MetadataCSW.cs
+++ MetadataCSW.cs
@@ -25303,6 +25303,7 @@

         [XmlElement(Type = typeof(MD_FeatureCatalogueDescription_Type), ElementName = "MD_FeatureCatalogueDescription", Namespace = "http://www.isotc211.org/2005/gmd")]
         [XmlElement(Type = typeof(MD_CoverageDescription_Type), ElementName = "MD_CoverageDescription", Namespace = "http://www.isotc211.org/2005/gmd")]
+        [XmlElement(Type = typeof(MD_ImageDescription_Type), ElementName = "MD_ImageDescription", Namespace = "http://www.isotc211.org/2005/gmd")]
         public AbstractMD_ContentInformation_Type AbstractMD_ContentInformation
         {
             get


ArgumentException: use system-supplied message if message is null (#25115)

Enable using a system-supplied message while also providing an argument/parameter name by passing in a null message. Made to match the behavior of FileNotFoundException.

Signed-off-by: dotnet-bot <03c4cb6107ae99956a7681f2c97ff7104809a2bd@microsoft.com>

--- src/Common/src/CoreLib/System/ArgumentException.cs
+++ src/Common/src/CoreLib/System/ArgumentException.cs
@@ -78,6 +78,8 @@
         {
             get
             {
+                SetMessageField();
+
                 string s = base.Message;
                 if (!string.IsNullOrEmpty(_paramName))
                 {
@@ -89,6 +91,14 @@
             }
         }

+        private void SetMessageField()
+        {
+            if (_message == null && HResult == System.HResults.COR_E_ARGUMENT)
+            {
+                _message = SR.Arg_ArgumentException;
+            }
+        }
+
         public virtual string? ParamName
         {
             get { return _paramName; }


Detect BadFormatException also as an InnerException in test execution

The same as it is already detected in test discovery,
then reported as a warning.

--- src/NUnitTestAdapter/NUnit3TestExecutor.cs
+++ src/NUnitTestAdapter/NUnit3TestExecutor.cs
@@ -299,6 +299,15 @@
                 // we skip the native c++ binaries that we don't support.
                 TestLog.Warning("   Assembly not supported: " + assemblyPath);
             }
+            catch( NUnitEngineException e )
+            {
+                if( e.InnerException is BadImageFormatException )
+                {
+                    // we skip the native c++ binaries that we don't support.
+                    TestLog.Warning( "   Assembly not supported: " + assemblyPath );
+                }
+                throw;
+            }
             catch (FileNotFoundException ex)
             {
                 // Probably from the GetExportedTypes in NUnit.core, attempting to find an assembly, not a problem if it is not NUnit here


We dont really need this prepare watcher anymore.

--- src/Manos/Manos.IO/IOLoop.cs
+++ src/Manos/Manos.IO/IOLoop.cs
@@ -46,7 +46,6 @@

 		private Loop evloop;
 		private Libeio.Libeio eio;
-		private PrepareWatcher prepare_watcher;

 		public IOLoop ()
 		{
@@ -54,9 +53,6 @@
 			eio = new Libeio.Libeio ();

 			eio.Initialize (evloop);
-
-			prepare_watcher = new PrepareWatcher (evloop, HandlePrepareEvent);
-			prepare_watcher.Start ();
 		}

 		public static IOLoop Instance {
@@ -83,14 +79,6 @@
 			running = false;
 		}

-		private void HandlePrepareEvent (Loop loop, PrepareWatcher watcher, EventTypes revents)
-		{
-			if (!running) {
-			   loop.Unloop (UnloopType.All);
-			   prepare_watcher.Stop ();
-		        }
-		}
-
 		public void AddTimeout (Timeout timeout)
 		{
 			TimerWatcher t = new TimerWatcher (timeout.begin, timeout.span, evloop, HandleTimeout);


IDE: Fix adding/removing files to/from projects.

--- Ide/NitraCommonVSIX/NitraCommonVsPackage.cs
+++ Ide/NitraCommonVSIX/NitraCommonVsPackage.cs
@@ -135,10 +135,24 @@

     private void PrjItemsEvents_ItemRemoved(ProjectItem projectItem)
     {
+      ThreadHelper.ThrowIfNotOnUIThread();
+      var filePath    = (string)projectItem.Properties.Item("FullPath").Value;
+      var project     = projectItem.ContainingProject;
+      var projectPath = project.FullName;
+      var ext         = Path.GetExtension(filePath);
+      var id          = new FileId(_stringManager.GetId(filePath));
+      var projectId   = GetProjectId(project);
+
+      foreach (var server in _servers)
+        if (server.IsSupportedExtension(ext))
+          server.FileUnloaded(projectId, id);
+
+      Debug.WriteLine($"tr: FileAdded(FileName='{filePath}' id={id} projectPath='{projectPath}')");
     }

     private void PrjItemsEvents_ItemAdded(ProjectItem projectItem)
     {
+      ThreadHelper.ThrowIfNotOnUIThread();
       AddFile(projectItem, projectItem.Properties.Item("FullPath").Value);
     }

@@ -549,6 +563,11 @@
         server.BeforeCloseProject(id);
     }

+    static bool CanIncludeInProject(string action)
+    {
+      return action == "Compile" || action == "Nitra" || action == "None" || string.IsNullOrEmpty(action);
+    }
+
     void FileAdded(object sender, HierarchyItemEventArgs e)
     {
       ThreadHelper.ThrowIfNotOnUIThread();
@@ -556,18 +575,13 @@
       var action = e.Hierarchy.GetProp<string>(e.ItemId, __VSHPROPID4.VSHPROPID_BuildAction);
       var path   = e.FileName;

-      if (action == "Compile" || action == "Nitra" || action == null)
+      if (CanIncludeInProject(action))
       {
         object obj;
         var hr2 = e.Hierarchy.GetProperty(e.ItemId, (int)__VSHPROPID.VSHPROPID_ExtObject, out obj);

         if (ErrorHelper.Succeeded(hr2) && obj is ProjectItem projectItem && projectItem != null)
         {
-          if (action == null && projectItem.ContainingProject.UniqueName != "<MiscFiles>")
-          {
-            Debug.WriteLine($"tr: FileAdded(BuildAction='{action}', FileName='{path}') (skipped)");
-            return;
-          }
           AddFile(projectItem, path);
           Debug.WriteLine($"tr: FileAdded(BuildAction='{action}', FileName='{path}')");
           return;
@@ -579,6 +593,7 @@

     private void AddFile(ProjectItem projectItem, string path)
     {
+      ThreadHelper.ThrowIfNotOnUIThread();
       var ext = Path.GetExtension(path);
       var id = new FileId(_stringManager.GetId(path));
       var project = projectItem.ContainingProject;
@@ -601,7 +616,7 @@
       var project   = e.Hierarchy.GetProp<Project>(VSConstants.VSITEMID_ROOT, __VSHPROPID.VSHPROPID_ExtObject);
       var projectId = GetProjectId(project);

-      if (action == "Compile" || action == "Nitra" || (action == null && string.IsNullOrEmpty(project.FileName)))
+      if (CanIncludeInProject(action))
         foreach (var server in _servers)
           if (server.IsSupportedExtension(ext))
             server.FileUnloaded(projectId, id);


Textboxes should take whitespace into account when calculating size.

--- src/Avalonia.Controls/Presenters/TextPresenter.cs
+++ src/Avalonia.Controls/Presenters/TextPresenter.cs
@@ -219,7 +219,7 @@
         {
             var text = Text;

-            if (!string.IsNullOrWhiteSpace(text))
+            if (!string.IsNullOrEmpty(text))
             {
                 return base.MeasureOverride(availableSize);
             }


sun color added to weather

sun color added to weather

--- src/NadekoBot/Modules/Searches/Searches.cs
+++ src/NadekoBot/Modules/Searches/Searches.cs
@@ -48,12 +48,12 @@
                 .AddField(fb => fb.WithName("📏 Lat,Long").WithValue($"{obj["latitude"]}, {obj["longitude"]}").WithIsInline(true))
                 .AddField(fb => fb.WithName("☁ Condition").WithValue($"{obj["condition"]}").WithIsInline(true))
                 .AddField(fb => fb.WithName("😓 Humidity").WithValue($"{obj["humidity"]}%").WithIsInline(true))
-                .AddField(fb => fb.WithName("💨 Wind Speed").WithValue($"{obj["windspeedk"]}km/h / {obj["windspeedm"]}mph").WithIsInline(true))
-                .AddField(fb => fb.WithName("🌡 Temperature").WithValue($"{obj["centigrade"]}°C / {obj["fahrenheit"]}°F").WithIsInline(true))
+                .AddField(fb => fb.WithName("💨 Wind Speed").WithValue($"{obj["windspeedk"]}km/h ({obj["windspeedm"]}mph)").WithIsInline(true))
+                .AddField(fb => fb.WithName("🌡 Temperature").WithValue($"{obj["centigrade"]}°C ({obj["fahrenheit"]}°F)").WithIsInline(true))
                 .AddField(fb => fb.WithName("🔆 Feels like").WithValue($"{obj["feelscentigrade"]}°C / {obj["feelsfahrenheit"]}°F").WithIsInline(true))
                 .AddField(fb => fb.WithName("🌄 Sunrise").WithValue($"{obj["sunrise"]}").WithIsInline(true))
                 .AddField(fb => fb.WithName("🌇 Sunset").WithValue($"{obj["sunset"]}").WithIsInline(true))
-                .WithColor(NadekoBot.OkColor);
+                .WithColor(NadekoBot.SunColor);
             await channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
         }


Beispielhafte Ausführung einer StoredProcedure mit einem SqlProcedureObject.

--- src/Micro.Program/Program.cs
+++ src/Micro.Program/Program.cs
@@ -14,7 +14,7 @@
             {
                 //IDbTransaction transaction = session.BeginTransaction();

-                session.ExecuteCommand("select * from Posts where Title=@0 and Id=@1", "Mark", 3);
+                //session.ExecuteCommand("select * from Posts where Title=@0 and Id=@1", "Mark", 3);
                 //var objectSet = session.GetObjectSet<Post>(); // holt alle Posts
                 //objectSet = session.GetObjectSet<Post>("select * from Posts where Title=@title OR Id=@id", new { title = "Mark", id = 5 });
                 //// das gleich nur ohne anonyme Argumente
@@ -24,7 +24,11 @@
                 //session.GetObject<Post>(post => post.Title == "Mark" && post.Id == 6); // holt alle Posts die diese Kriterien erfüllen
                 //session.GetValue<int>("select COUNT(*) from Posts"); // holt einen Wert
                 // Stored Procedures werde ich auch noch einbauen
-                session.ExecuteStoredProcedure(new ImportPrepareProcedureObject());
+
+                ImportPrepareProcedureObject procedureObject = new ImportPrepareProcedureObject();
+                procedureObject.TicketID = "blah";
+
+                session.ExecuteStoredProcedure(procedureObject);

                 //transaction.Commit();
             }


convert osx special key codes.

convert osx special key codes.

--- src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
+++ src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
@@ -5,12 +5,89 @@
 using System.Text;
 using Avalonia.Controls;
 using Avalonia.Controls.Platform;
+using Avalonia.Input;
 using Avalonia.Native.Interop;
 using Avalonia.Platform.Interop;
 using Avalonia.Threading;

 namespace Avalonia.Native
 {
+    enum OsxUnicodeSpecialKey
+    {
+        NSUpArrowFunctionKey = 0xF700,
+        NSDownArrowFunctionKey = 0xF701,
+        NSLeftArrowFunctionKey = 0xF702,
+        NSRightArrowFunctionKey = 0xF703,
+        NSF1FunctionKey = 0xF704,
+        NSF2FunctionKey = 0xF705,
+        NSF3FunctionKey = 0xF706,
+        NSF4FunctionKey = 0xF707,
+        NSF5FunctionKey = 0xF708,
+        NSF6FunctionKey = 0xF709,
+        NSF7FunctionKey = 0xF70A,
+        NSF8FunctionKey = 0xF70B,
+        NSF9FunctionKey = 0xF70C,
+        NSF10FunctionKey = 0xF70D,
+        NSF11FunctionKey = 0xF70E,
+        NSF12FunctionKey = 0xF70F,
+        NSF13FunctionKey = 0xF710,
+        NSF14FunctionKey = 0xF711,
+        NSF15FunctionKey = 0xF712,
+        NSF16FunctionKey = 0xF713,
+        NSF17FunctionKey = 0xF714,
+        NSF18FunctionKey = 0xF715,
+        NSF19FunctionKey = 0xF716,
+        NSF20FunctionKey = 0xF717,
+        NSF21FunctionKey = 0xF718,
+        NSF22FunctionKey = 0xF719,
+        NSF23FunctionKey = 0xF71A,
+        NSF24FunctionKey = 0xF71B,
+        NSF25FunctionKey = 0xF71C,
+        NSF26FunctionKey = 0xF71D,
+        NSF27FunctionKey = 0xF71E,
+        NSF28FunctionKey = 0xF71F,
+        NSF29FunctionKey = 0xF720,
+        NSF30FunctionKey = 0xF721,
+        NSF31FunctionKey = 0xF722,
+        NSF32FunctionKey = 0xF723,
+        NSF33FunctionKey = 0xF724,
+        NSF34FunctionKey = 0xF725,
+        NSF35FunctionKey = 0xF726,
+        NSInsertFunctionKey = 0xF727,
+        NSDeleteFunctionKey = 0xF728,
+        NSHomeFunctionKey = 0xF729,
+        NSBeginFunctionKey = 0xF72A,
+        NSEndFunctionKey = 0xF72B,
+        NSPageUpFunctionKey = 0xF72C,
+        NSPageDownFunctionKey = 0xF72D,
+        NSPrintScreenFunctionKey = 0xF72E,
+        NSScrollLockFunctionKey = 0xF72F,
+        NSPauseFunctionKey = 0xF730,
+        NSSysReqFunctionKey = 0xF731,
+        NSBreakFunctionKey = 0xF732,
+        NSResetFunctionKey = 0xF733,
+        NSStopFunctionKey = 0xF734,
+        NSMenuFunctionKey = 0xF735,
+        NSUserFunctionKey = 0xF736,
+        NSSystemFunctionKey = 0xF737,
+        NSPrintFunctionKey = 0xF738,
+        NSClearLineFunctionKey = 0xF739,
+        NSClearDisplayFunctionKey = 0xF73A,
+        NSInsertLineFunctionKey = 0xF73B,
+        NSDeleteLineFunctionKey = 0xF73C,
+        NSInsertCharFunctionKey = 0xF73D,
+        NSDeleteCharFunctionKey = 0xF73E,
+        NSPrevFunctionKey = 0xF73F,
+        NSNextFunctionKey = 0xF740,
+        NSSelectFunctionKey = 0xF741,
+        NSExecuteFunctionKey = 0xF742,
+        NSUndoFunctionKey = 0xF743,
+        NSRedoFunctionKey = 0xF744,
+        NSFindFunctionKey = 0xF745,
+        NSHelpFunctionKey = 0xF746,
+        NSModeSwitchFunctionKey = 0xF747
+    }
+
     public class MenuActionCallback : CallbackBase, IAvnActionCallback
     {
         private Action _action;
@@ -50,6 +127,11 @@
         private IAvnWindow _nativeWindow;
         private List<NativeMenuItem> _menuItems = new List<NativeMenuItem>();

+        private static Dictionary<Key, OsxUnicodeSpecialKey> osxKeys = new Dictionary<Key, OsxUnicodeSpecialKey>
+        {
+            { Key.F1, OsxUnicodeSpecialKey.NSF1FunctionKey },
+        };
+
         public AvaloniaNativeMenuExporter(IAvnWindow nativeWindow, IAvaloniaNativeFactory factory)
         {
             _factory = factory;
@@ -147,6 +229,18 @@
             }
         }

+        private static string ConvertOSXSpecialKeyCodes(Key key)
+        {
+            if (osxKeys.ContainsKey(key))
+            {
+                return Encoding.UTF8.GetString(BitConverter.GetBytes((ushort)osxKeys[key]));
+            }
+            else
+            {
+                return key.ToString().ToLower();
+            }
+        }
+
         private void SetChildren(IAvnAppMenu menu, ICollection<NativeMenuItemBase> children)
         {
             foreach (var i in children)
@@ -164,7 +258,7 @@

                     if (item.Gesture != null)
                     {
-                        using (var buffer = new Utf8Buffer(item.Gesture.Key.ToString().ToLower()))
+                        using (var buffer = new Utf8Buffer(ConvertOSXSpecialKeyCodes(item.Gesture.Key)))
                         {
                             menuItem.SetGesture(buffer.DangerousGetHandle(), (AvnInputModifiers)item.Gesture.KeyModifiers);
                         }


Update to ssh library to lock the hashtable before adding new config key

--- Jovice.Common/Library/SharpSSH/jsch/JSch.cs
+++ Jovice.Common/Library/SharpSSH/jsch/JSch.cs
@@ -35,57 +35,60 @@
 	public class JSch
 	{

-		static System.Collections.Hashtable config;
-
-		public static void Init()
-		{
-			config=new System.Collections.Hashtable();
-
-			//  config.Add("kex", "diffie-hellman-group-exchange-sha1");
-			config.Add("kex", "diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1");
-			config.Add("server_host_key", "ssh-rsa,ssh-dss");
-			//config.Add("server_host_key", "ssh-dss,ssh-rsa");
-
-			//			config.Add("cipher.s2c", "3des-cbc,blowfish-cbc");
-			//			config.Add("cipher.c2s", "3des-cbc,blowfish-cbc");
-
-			config.Add("cipher.s2c", "3des-cbc,aes128-cbc");
-			config.Add("cipher.c2s", "3des-cbc,aes128-cbc");
-
-			//			config.Add("mac.s2c", "hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96");
-			//			config.Add("mac.c2s", "hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96");
-			config.Add("mac.s2c", "hmac-md5,hmac-sha1");
-			config.Add("mac.c2s", "hmac-md5,hmac-sha1");
-			config.Add("compression.s2c", "none");
-			config.Add("compression.c2s", "none");
-			config.Add("lang.s2c", "");
-			config.Add("lang.c2s", "");
-
-			config.Add("diffie-hellman-group-exchange-sha1",
-				"Tamir.SharpSsh.jsch.DHGEX");
-			config.Add("diffie-hellman-group1-sha1",
-				"Tamir.SharpSsh.jsch.DHG1");
-
-			config.Add("dh",            "Tamir.SharpSsh.jsch.jce.DH");
-			config.Add("3des-cbc",      "Tamir.SharpSsh.jsch.jce.TripleDESCBC");
-			//config.Add("blowfish-cbc",  "Tamir.SharpSsh.jsch.jce.BlowfishCBC");
-			config.Add("hmac-sha1",     "Tamir.SharpSsh.jsch.jce.HMACSHA1");
-			config.Add("hmac-sha1-96",  "Tamir.SharpSsh.jsch.jce.HMACSHA196");
-			config.Add("hmac-md5",      "Tamir.SharpSsh.jsch.jce.HMACMD5");
-			config.Add("hmac-md5-96",   "Tamir.SharpSsh.jsch.jce.HMACMD596");
-			config.Add("sha-1",         "Tamir.SharpSsh.jsch.jce.SHA1");
-			config.Add("md5",           "Tamir.SharpSsh.jsch.jce.MD5");
-			config.Add("signature.dss", "Tamir.SharpSsh.jsch.jce.SignatureDSA");
-			config.Add("signature.rsa", "Tamir.SharpSsh.jsch.jce.SignatureRSA");
-			config.Add("keypairgen.dsa",   "Tamir.SharpSsh.jsch.jce.KeyPairGenDSA");
-			config.Add("keypairgen.rsa",   "Tamir.SharpSsh.jsch.jce.KeyPairGenRSA");
-			config.Add("random",        "Tamir.SharpSsh.jsch.jce.Random");
-
-			config.Add("aes128-cbc",    "Tamir.SharpSsh.jsch.jce.AES128CBC");
-
-			//config.Add("zlib",          "com.jcraft.jsch.jcraft.Compression");
-
-			config.Add("StrictHostKeyChecking",  "ask");
+        static System.Collections.Hashtable config;
+
+        public static void Init()
+		{
+            config = new System.Collections.Hashtable();
+
+            lock (config)
+            {
+                //  config.Add("kex", "diffie-hellman-group-exchange-sha1");
+                config.Add("kex", "diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1");
+                config.Add("server_host_key", "ssh-rsa,ssh-dss");
+                //config.Add("server_host_key", "ssh-dss,ssh-rsa");
+
+                //			config.Add("cipher.s2c", "3des-cbc,blowfish-cbc");
+                //			config.Add("cipher.c2s", "3des-cbc,blowfish-cbc");
+
+                config.Add("cipher.s2c", "3des-cbc,aes128-cbc");
+                config.Add("cipher.c2s", "3des-cbc,aes128-cbc");
+
+                //			config.Add("mac.s2c", "hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96");
+                //			config.Add("mac.c2s", "hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96");
+                config.Add("mac.s2c", "hmac-md5,hmac-sha1");
+                config.Add("mac.c2s", "hmac-md5,hmac-sha1");
+                config.Add("compression.s2c", "none");
+                config.Add("compression.c2s", "none");
+                config.Add("lang.s2c", "");
+                config.Add("lang.c2s", "");
+
+                config.Add("diffie-hellman-group-exchange-sha1",
+                    "Tamir.SharpSsh.jsch.DHGEX");
+                config.Add("diffie-hellman-group1-sha1",
+                    "Tamir.SharpSsh.jsch.DHG1");
+
+                config.Add("dh", "Tamir.SharpSsh.jsch.jce.DH");
+                config.Add("3des-cbc", "Tamir.SharpSsh.jsch.jce.TripleDESCBC");
+                //config.Add("blowfish-cbc",  "Tamir.SharpSsh.jsch.jce.BlowfishCBC");
+                config.Add("hmac-sha1", "Tamir.SharpSsh.jsch.jce.HMACSHA1");
+                config.Add("hmac-sha1-96", "Tamir.SharpSsh.jsch.jce.HMACSHA196");
+                config.Add("hmac-md5", "Tamir.SharpSsh.jsch.jce.HMACMD5");
+                config.Add("hmac-md5-96", "Tamir.SharpSsh.jsch.jce.HMACMD596");
+                config.Add("sha-1", "Tamir.SharpSsh.jsch.jce.SHA1");
+                config.Add("md5", "Tamir.SharpSsh.jsch.jce.MD5");
+                config.Add("signature.dss", "Tamir.SharpSsh.jsch.jce.SignatureDSA");
+                config.Add("signature.rsa", "Tamir.SharpSsh.jsch.jce.SignatureRSA");
+                config.Add("keypairgen.dsa", "Tamir.SharpSsh.jsch.jce.KeyPairGenDSA");
+                config.Add("keypairgen.rsa", "Tamir.SharpSsh.jsch.jce.KeyPairGenRSA");
+                config.Add("random", "Tamir.SharpSsh.jsch.jce.Random");
+
+                config.Add("aes128-cbc", "Tamir.SharpSsh.jsch.jce.AES128CBC");
+
+                //config.Add("zlib",          "com.jcraft.jsch.jcraft.Compression");
+
+                config.Add("StrictHostKeyChecking", "ask");
+            }
 		}

 		internal Tamir.SharpSsh.java.util.Vector pool=new Tamir.SharpSsh.java.util.Vector();


added support for equals?

added support for equals?

--- Joyride.Specflow/Support/PredicateParser.cs
+++ Joyride.Specflow/Support/PredicateParser.cs
@@ -27,7 +27,7 @@

         #region built-in reserved words

-        protected static readonly string[] ReservedWords = { "StartsWith?", "EndsWith?", "Containing?", "Matching?" };
+        protected static readonly string[] ReservedWords = { "StartsWith?", "EndsWith?", "Containing?", "Matching?", "Equals?" };

         protected static MethodInfo GetMethodInfo(string name, Type[] types) { return typeof(string).GetMethod(name, types); }

@@ -49,7 +49,8 @@
                                  Expression.PropertyOrField(result, "Success")
                     );
                     return block;
-                }}
+                }},
+              { "Equals?", (instance, args) => Expression.Call(instance, GetMethodInfo("Equals" , new [] { typeof(string)}), args) },
           };

         #endregion
@@ -151,6 +152,7 @@
               { "EndsWith?", (a,b)=> ReservedWordPredicate("EndsWith?", Coerce(a,typeof(string)), Coerce(b,typeof(string))) },
               { "Containing?", (a,b)=> ReservedWordPredicate("Containing?", Coerce(a,typeof(string)), Coerce(b,typeof(string))) },
               { "Matching?", (a,b)=> ReservedWordPredicate("Matching?", Coerce(a,typeof(string)), Coerce(b,typeof(string))) },
+              { "Equals?", (a,b)=> ReservedWordPredicate("Equals?", Coerce(a,typeof(string)), Coerce(b,typeof(string))) }
           };

         /// <summary>
@@ -188,13 +190,7 @@
                 return Expression.PropertyOrField(_param, s);

             Expression key = Expression.Constant(s, typeof(string));
-            var result = Expression.Parameter(typeof(object), "result");
-            var block = Expression.Block(
-                new[] { result },               //make the result a variable in scope for the block
-                Expression.Assign(result, Expression.Property(_param, "Item", key)),
-                result                          //last value Expression becomes the return of the block
-                );
-            return block;
+            return Expression.Property(_param, "Item", key);
         }

         /// <summary>create lambda expression</summary>
@@ -214,7 +210,7 @@
         private Expression ParseAnd() { return ParseBinary(ParseEquality, "&&"); }
         private Expression ParseEquality() { return ParseBinary(ParseRelation, "==", "!="); }
         private Expression ParseRelation() { return ParseBinary(ParseReservedWord, "<", "<=", ">=", ">"); }
-        private Expression ParseReservedWord() { return ParseBinary(ParseSum, "StartsWith?", "EndsWith?", "Containing?", "Matching?"); }
+        private Expression ParseReservedWord() { return ParseBinary(ParseSum, "StartsWith?", "EndsWith?", "Containing?", "Matching?", "Equals?"); }
         private Expression ParseSum() { return ParseBinary(ParseMul, "+", "-"); }
         private Expression ParseMul() { return ParseBinary(ParseUnary, "/", "*", "%"); }


React to API changes in aspnet-contrib/AspNet.Security.OpenIdConnect.Server

https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/commit/bc2f454df60e8381732bc4580f187f840e15e235

--- src/OpenIddict.Mvc/OpenIddictController.cs
+++ src/OpenIddict.Mvc/OpenIddictController.cs
@@ -67,7 +67,7 @@
             if (!User.Identities.Any(identity => identity.IsAuthenticated)) {
                 return Challenge(new AuthenticationProperties {
                     RedirectUri = Url.Action(nameof(Authorize), new {
-                        request_id = request.GetRequestIdentifier()
+                        request_id = request.GetRequestId()
                     })
                 });
             }


Fixing unit tests

Fixing unit tests

--HG--
branch : 1.x

--- src/Orchard/Environment/IAssemblyLoader.cs
+++ src/Orchard/Environment/IAssemblyLoader.cs
@@ -15,7 +15,7 @@
         private readonly ConcurrentDictionary<string, Assembly> _loadedAssemblies = new ConcurrentDictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);

         public DefaultAssemblyLoader(IEnumerable<IAssemblyNameResolver> assemblyNameResolvers) {
-            _assemblyNameResolvers = assemblyNameResolvers.OrderBy(l => l.Order).ToList();
+            _assemblyNameResolvers = assemblyNameResolvers.OrderBy(l => l.Order);
             Logger = NullLogger.Instance;
         }


コメント修正

コメント修正

--- Sdx.Web/Url.cs
+++ Sdx.Web/Url.cs
@@ -168,7 +168,7 @@
     }

     /// <summary>
-    /// ParamList の各キー毎のループ回数を管理するプロパティ
+    /// ParamList の各キー毎の要素数を管理するプロパティ
     /// 同じ名前のキーがセットされたらカウントをアップし、
     /// 削除されたらカウントを0に戻す
     /// </summary>


JSON_PRETTY_PRINT

JSON_PRETTY_PRINT

closes https://github.com/peachpiecompiler/peachpie/issues/392

--- src/Peachpie.Library/Serialization.Json.cs
+++ src/Peachpie.Library/Serialization.Json.cs
@@ -70,13 +70,15 @@
                 internal const string TrueLiteral = "true";
                 internal const string FalseLiteral = "false";

+                internal const string PrettySpaceString = " "; // whitespace for pretty printing
+                internal const string PrettyNewLine = "\n"; // whitespace for pretty printing
             }

             #endregion

             #region ObjectWriter

-            sealed class ObjectWriter : PhpVariableVisitor
+            sealed class ObjectWriter : PhpVariableVisitor // TODO: :FormatterVisitor
             {
                 Encoding Encoding => _ctx.StringEncoding;

@@ -90,6 +92,74 @@
                 readonly Context _ctx;
                 readonly RuntimeTypeHandle _caller;
                 readonly JsonEncodeOptions _encodeOptions;
+                readonly IPrettyPrinter _pretty;
+
+                #region IPrettyPrinter
+
+                ///
+                /// Used to output pretty printing whitespaces if enabled.
+                ///
+                interface IPrettyPrinter
+                {
+                    void Indent();
+                    void Unindent();
+
+                    /// Writes a single whitespace, if <see cref="JSON_PRETTY_PRINT"/> is enabled.
+                    void Space();
+
+                    /// Writes new line and indentation, if <see cref="JSON_PRETTY_PRINT"/> is enabled.
+                    void NewLine();
+                }
+
+                sealed class PrettyPrintOff : IPrettyPrinter
+                {
+                    public void Indent() { }
+                    public void NewLine() { }
+                    public void Space() { }
+                    public void Unindent() { }
+                }
+
+                sealed class PrettyPrintOn : IPrettyPrinter
+                {
+                    int _indent = 0;
+                    string _indentStr = null;
+                    readonly PhpString.Blob _output;
+
+                    public PrettyPrintOn(PhpString.Blob output)
+                    {
+                        _output = output ?? throw new ArgumentNullException();
+                    }
+
+                    public void Indent()
+                    {
+                        _indent++;
+                        _indentStr = null;
+                    }
+
+                    public void NewLine()
+                    {
+                        if (_indentStr == null)
+                        {
+                            _indentStr = Tokens.PrettyNewLine + new string(' ', _indent * 4);
+                        }
+
+                        _output.Add(_indentStr);
+                    }
+
+                    public void Space()
+                    {
+                        _output.Add(Tokens.PrettySpaceString);
+                    }
+
+                    public void Unindent()
+                    {
+                        _indent--;
+                        _indentStr = null;
+                        Debug.Assert(_indent >= 0);
+                    }
+                }
+
+                #endregion

                 #region Options

@@ -111,6 +181,7 @@
                     _ctx = ctx;
                     _encodeOptions = encodeOptions;
                     _caller = caller;
+                    _pretty = HasPrettyPrint ? (IPrettyPrinter)new PrettyPrintOn(_result) : new PrettyPrintOff();
                 }

                 public static PhpString Serialize(Context ctx, PhpValue variable, JsonEncodeOptions encodeOptions, RuntimeTypeHandle caller)
@@ -155,6 +226,7 @@
                 }

                 void Write(string str) => _result.Append(str);
+
                 void Write(char ch) => _result.Append(ch.ToString());

                 public override void AcceptNull()
@@ -451,6 +523,8 @@
                     //
                     if (array.Count != 0)
                     {
+                        _pretty.Indent();
+
                         bool bFirst = true;

                         var enumerator = array.GetFastEnumerator();
@@ -460,11 +534,16 @@
                             if (bFirst) bFirst = false;
                             else Write(Tokens.ItemsSeparatorString);

+                            _pretty.NewLine();
+
                             Debug.Assert(enumerator.CurrentKey.IsInteger);

                             // value
                             Accept(enumerator.CurrentValue);
                         }
+
+                        _pretty.Unindent();
+                        _pretty.NewLine();
                     }

                     // ]
@@ -476,17 +555,35 @@
                     // {
                     Write(Tokens.ObjectOpen);

+                    _pretty.Indent();
+
                     bool bFirst = true;
                     foreach (var pair in properties)
                     {
                         // ,
-                        if (bFirst) bFirst = false;
-                        else Write(Tokens.ItemsSeparatorString);
-
-                        // "key":value
+                        if (bFirst)
+                        {
+                            bFirst = false;
+                        }
+                        else
+                        {
+                            Write(Tokens.ItemsSeparatorString);
+                        }
+
+                        _pretty.NewLine();
+
+                        // "key": value
                         WriteString(pair.Key);
                         Write(Tokens.PropertyKeyValueSeparatorString);
+                        _pretty.Space();
                         pair.Value.Accept(this);
+                    }
+
+                    _pretty.Unindent();
+
+                    if (!bFirst)
+                    {
+                        _pretty.NewLine();
                     }

                     // }


SplPriorityQueue, SplHeap

SplPriorityQueue, SplHeap

- cleanup and perf. fixes

--- src/Peachpie.Library/Spl/Datastructures.cs
+++ src/Peachpie.Library/Spl/Datastructures.cs
@@ -687,7 +687,7 @@
         public virtual void setIteratorMode(int mode)
         {
             if (((SplIteratorMode)mode & SplIteratorMode.Lifo) == 0)
-                    throw new RuntimeException("Iteration direction of SplQueue can not be changed to FIFO.");
+                throw new RuntimeException("Iteration direction of SplQueue can not be changed to FIFO.");

             // mode can only be set to values with SplIteratorMode.Lifo set
             if (mode >= IT_MODE_KEEP && mode <= (IT_MODE_LIFO + IT_MODE_DELETE))
@@ -703,71 +703,71 @@

     #endregion

-    #region AbstractHeapImplementation
+    #region PriorityQueue<T>

     /// <summary>
-    /// Generic heap functionality abstraction used for <see cref="SplHeap"/> and <see cref="SplPriorityQueue"/>
+    /// Generic priority queue for PHP's <see cref="SplPriorityQueue"/> and <see cref="SplHeap"/>.
     /// </summary>
-    /// <typeparam name="T">Heap type parameter, PhpValue for a <see cref="SplHeap"/>, or KeyValuePair of PhpValues for <see cref="SplPriorityQueue"/>/typeparam>
-    public abstract class AbstractHeap<T>
+    [PhpHidden]
+    sealed class PriorityQueue<T>
     {
         /// <summary>
+        /// Comparer.
+        /// </summary>
+        readonly IComparer<T> _comparer;
+
+        /// <summary>
         /// Binary heap nodes implemented as a list
         /// </summary>
-        protected readonly List<T> _heap = new List<T>();
-
-        /// <summary>
-        /// Indicator if the heap might be corrupted (true only when bubbling up or down hasnl finished correctly)
-        /// </summary>
-        protected bool _corrupted = false;
-
-        /// <summary>
-        /// Compare elements in order to place them correctly in the heap while sifting up
-        /// </summary>
-        /// <returns>positive integer if value1 is greater than value2, 0 if they are equal, negative integer otherwise</returns>
-        protected abstract long compare(T value1, T value2);
+        readonly List<T> _list = new List<T>();
+
+        /// <summary>
+        /// Indicator if the heap might be corrupted (true only when bubbling up or down hasn't finished correctly)
+        /// </summary>
+        public bool IsCorrupted { get; private set; }
+
+        /// <summary>
+        /// Creates the instance.
+        /// </summary>
+        public PriorityQueue(IComparer<T> comparer)
+        {
+            _comparer = comparer ?? throw new ArgumentNullException();
+        }
+
+        /// <summary>
+        /// Count of items.
+        /// </summary>
+        public int Count => _list.Count;

         /// <summary>
         /// Gets the current top of the heap
         /// </summary>
         /// <returns>value on top of the heap</returns>
-        protected T Peek
-        {
-            get
-            {
-                if (_heap.Count > 0)
-                {
-                    return _heap[0];
-                }
-                else
-                {
-                    throw new RuntimeException("The heap is empty.");
-                }
-            }
-        }
+        public T Peek() => _list.Count != 0 ? _list[0] : default;

         /// <summary>
         /// Gets the current top of the heap, and removes it
         /// </summary>
         /// <returns>value on top of the heap</returns>
-        protected T Pop()
-        {
-            if (_heap.Count > 0)
-            {
-                _corrupted = true;
-
-                var top = _heap[0];
-
-                _heap[0] = _heap[LastIndex];
-                _heap.RemoveAt(LastIndex);
+        public bool TryPop(out T value)
+        {
+            if (_list.Count != 0)
+            {
+                IsCorrupted = true;
+
+                value = _list[0];
+
+                _list[0] = _list[LastIndex];
+                _list.RemoveAt(LastIndex);

                 BubbleDown();

-                return top;
-            }
-            else
-            {
-                throw new RuntimeException("The heap is empty.");
+                return true;
+            }
+            else
+            {
+                value = default;
+                return false;
             }
         }

@@ -775,11 +775,11 @@
         /// Inserts a value into a heap, and bubbles it into correct place
         /// </summary>
         /// <param name="value">node to be inserted</param>
-        protected void Insert(T value)
-        {
-            _corrupted = true;
-
-            _heap.Add(value);
+        public void Insert(T value)
+        {
+            IsCorrupted = true;
+
+            _list.Add(value);

             BubbleUp();
         }
@@ -787,28 +787,14 @@
         /// <summary>
         /// Index of last node of a heap, or -1 if empty
         /// </summary>
-        protected int LastIndex
-        {
-            get
-            {
-                int index = _heap.Count - 1;
-                if (index >= 0)
-                {
-                    return index;
-                }
-                else
-                {
-                    return -1;
-                }
-            }
-        }
+        int LastIndex => _list.Count - 1;

         /// <summary>
         /// Gets the parent node index if exists, otherwise -1
         /// </summary>
         /// <param name="childIndex">index of the child node</param>
         /// <returns>parent node index if exists, otherwise -1</returns>
-        protected int ParentIndex(int childIndex)
+        int ParentIndex(int childIndex)
         {
             if (childIndex > 0)
             {
@@ -825,10 +811,10 @@
         /// </summary>
         /// <param name="parentIndex">index of the parent node</param>
         /// <returns>left child's index, if exists, otherwise -1</returns>
-        protected int LeftChildIndex(int parentIndex)
+        int LeftChildIndex(int parentIndex)
         {
             int childIndex = (parentIndex * 2) + 1;
-            if (childIndex < _heap.Count)
+            if (childIndex < _list.Count)
             {
                 return childIndex;
             }
@@ -843,10 +829,10 @@
         /// </summary>
         /// <param name="parentIndex">index of the parent node</param>
         /// <returns>right child's index, if exists, otherwise -1</returns>
-        protected int RightChildIndex(int parentIndex)
+        int RightChildIndex(int parentIndex)
         {
             int childIndex = (parentIndex * 2) + 2;
-            if (childIndex < _heap.Count)
+            if (childIndex < _list.Count)
             {
                 return childIndex;
             }
@@ -862,35 +848,40 @@
         /// <param name="index1"></param>
         /// <param name="index2"></param>
         /// <exception cref="OutOfRangeException">Given index is out of range or invalid.</exception>
-        protected void Swap(int index1, int index2)
-        {
-            var tmp = _heap[index1];
-            _heap[index1] = _heap[index2];
-            _heap[index2] = tmp;
+        void Swap(int index1, int index2)
+        {
+            var tmp = _list[index1];
+            _list[index1] = _list[index2];
+            _list[index2] = tmp;
         }

         /// <summary>
         /// Bubble the last item of the heap up, to get it into correct position
         /// </summary>
-        protected void BubbleUp()
-        {
-            int currentIndex = LastIndex;
-            int parentIndex = ParentIndex(currentIndex);
-
-            while (parentIndex >= 0 && compare(_heap[parentIndex], _heap[currentIndex]) < 0)
-            {
-                Swap(currentIndex, parentIndex);
-                currentIndex = parentIndex;
-                parentIndex = ParentIndex(currentIndex);
-            }
-
-            _corrupted = false;
+        void BubbleUp() => BubbleUp(LastIndex);
+
+        /// <summary>
+        /// Bubble the item of the heap up, to get it into correct position
+        /// </summary>
+        void BubbleUp(int index)
+        {
+            Debug.Assert(index >= 0 && index < Count);
+            int parentIndex = ParentIndex(index);
+
+            while (parentIndex >= 0 && _comparer.Compare(_list[parentIndex], _list[index]) < 0)
+            {
+                Swap(index, parentIndex);
+                index = parentIndex;
+                parentIndex = ParentIndex(index);
+            }
+
+            IsCorrupted = false;
         }

         /// <summary>
         /// Bubble the first item of the heap down, to get it into the correct position
         /// </summary>
-        protected void BubbleDown()
+        void BubbleDown()
         {
             int currentIndex = 0;
             int leftChild = LeftChildIndex(currentIndex);
@@ -899,12 +890,12 @@
             {
                 int rightChild = RightChildIndex(currentIndex);

-                if (rightChild > 0 && compare(_heap[rightChild], _heap[leftChild]) > 0 && compare(_heap[rightChild], _heap[currentIndex]) > 0)
+                if (rightChild > 0 && _comparer.Compare(_list[rightChild], _list[leftChild]) > 0 && _comparer.Compare(_list[rightChild], _list[currentIndex]) > 0)
                 {
                     Swap(currentIndex, rightChild);
                     currentIndex = rightChild;
                 }
-                else if (compare(_heap[leftChild], _heap[currentIndex]) > 0)
+                else if (_comparer.Compare(_list[leftChild], _list[currentIndex]) > 0)
                 {
                     Swap(currentIndex, leftChild);
                     currentIndex = leftChild;
@@ -916,7 +907,24 @@

                 leftChild = LeftChildIndex(currentIndex);
             }
-            _corrupted = false;
+
+            IsCorrupted = false;
+        }
+
+        /// <summary>
+        /// Reorders the queue if <see cref="IsCorrupted"/>.
+        /// </summary>
+        public void Recover()
+        {
+            if (IsCorrupted)
+            {
+                for (int i = 0; i < _list.Count; i++)
+                {
+                    BubbleUp(i);
+                }
+
+                IsCorrupted = false;
+            }
         }
     }

@@ -928,19 +936,32 @@
     /// The SplPriorityQueue class provides the main functionalities of a prioritized queue, implemented using a max heap.
     /// </summary>
     [PhpType(PhpTypeAttribute.InheritName), PhpExtension(SplExtension.Name)]
-    public class SplPriorityQueue : AbstractHeap<KeyValuePair<PhpValue, PhpValue>>, Iterator, Countable
+    public class SplPriorityQueue : Iterator, Countable, IComparer<SplPriorityQueue.Pair>
     {
         /// <summary>
-        /// Runtime context.
-        /// </summary>
-        protected readonly Context/*!*/_ctx;
+        /// Shortcut for (PhpValue priority, PhpValue value).
+        /// </summary>
+        internal struct Pair
+        {
+            public PhpValue
+                priority,
+                value;
+        }
+
+        readonly PriorityQueue<Pair> _queue;
+
+        #region IComparer
+
+        int IComparer<Pair>.Compare(Pair x, Pair y)
+            => (int)this.compare(x.priority, y.priority);
+
+        #endregion

         /// <summary>
         /// SplPriorityQueue extraction mode
         /// </summary>
-        [PhpHidden]
         [Flags]
-        public enum SplExtractionMode
+        internal enum SplExtractionMode
         {
             ExtrData = 1,
             ExtrPriority = 2,
@@ -956,81 +977,48 @@
         /// </summary>
         private SplExtractionMode _extractionMode = SplExtractionMode.ExtrData;

-        public SplPriorityQueue(Context ctx) : base()
-        {
-            _ctx = ctx;
+        public SplPriorityQueue()
+        {
+            _queue = new PriorityQueue<Pair>(this);
         }

         public void __construct() { /* Nothing */ }

-        protected override long compare(KeyValuePair<PhpValue, PhpValue> pair1, KeyValuePair<PhpValue, PhpValue> pair2)
-        {
-            if (pair1.Key > pair2.Key)
-            {
-                return 1;
-            }
-            else if (pair2.Key > pair1.Key)
-            {
-                return -1;
-            }
-            else
-            {
-                return 0;
-            }
-        }
-        public virtual long count()
-        {
-            return _heap.Count;
-        }
-        public virtual PhpValue current()
-        {
-            return ForExtractionMode(Peek);
-        }
-        public virtual PhpValue extract()
-        {
-            return ForExtractionMode(Pop());
-        }
-        public virtual int getExtractFlags()
-        {
-            return (int)_extractionMode;
-        }
+        public virtual long compare(PhpValue priority1, PhpValue priority2) => priority1.Compare(priority2);
+
+        public virtual long count() => _queue.Count;
+
+        public virtual PhpValue current() => _queue.Count != 0 ? ForExtractionMode(_queue.Peek()) : PhpValue.Null;
+
+        public virtual PhpValue extract() => _queue.TryPop(out var x) ? ForExtractionMode(x) : PhpValue.Null;
+
+        public virtual int getExtractFlags() => (int)_extractionMode;
+
         public virtual void insert(PhpValue value, PhpValue priority)
         {
-            Insert(new KeyValuePair<PhpValue, PhpValue>(priority, value));
-        }
-        public virtual bool isCorrupted()
-        {
-            return _corrupted;
-        }
-        public virtual bool isEmpty()
-        {
-            return count() == 0;
-        }
+            _queue.Insert(new Pair { priority = priority.DeepCopy(), value = value.DeepCopy() });
+        }
+
+        public virtual bool isCorrupted() => _queue.IsCorrupted;
+
+        public virtual bool isEmpty() => _queue.Count == 0;
+
         public virtual PhpValue key()
         {
             // The key is the theoretical index of the iterater, which is always the last node for the heap
-            return count() - 1;
-        }
+            return _queue.Count - 1;
+        }
+
         public virtual void next()
         {
             // The only thing moving the iterator of a heap does is deletes the top and corrects the heap
-            Pop();
-        }
-        public virtual void recoverFromCorruption()
-        {
-            var backupList = new List<KeyValuePair<PhpValue, PhpValue>>();
-            foreach (var item in _heap)
-            {
-                backupList.Add(item);
-            }
-            foreach (var item in backupList)
-            {
-                insert(item.Value, item.Key);
-            }
-
-            _corrupted = false;
-        }
+            _queue.TryPop(out var _);
+        }
+
+        public virtual void recoverFromCorruption() => _queue.Recover();
+
         public virtual void rewind() { /* Nothing */ }
+
         public virtual void setExtractFlags(int flags)
         {
             // flags are within all possible combinations of SplExtractionMode
@@ -1043,15 +1031,17 @@
                 throw new ArgumentException("Argument value is not an iterator mode.");
             }
         }
+
         public virtual PhpValue top()
         {
             // Top of the heap is also the current position of the iterator
             return current();
         }
+
         public virtual bool valid()
         {
             // Only checks if the priorityQueue contains any nodes
-            return !isEmpty();
+            return _queue.Count != 0;
         }

         /// <summary>
@@ -1059,26 +1049,25 @@
         /// </summary>
         /// <param name="pair">Node to return</param>
         /// <returns>pair's value, priority, or both in a PhpArray accordint to <see cref="_extractionMode"/></returns>
-        private PhpValue ForExtractionMode (KeyValuePair<PhpValue, PhpValue> pair)
-        {
-            if (_extractionMode == SplExtractionMode.ExtrData)
-            {
-                return pair.Value;
-            }
-            else if (_extractionMode == SplExtractionMode.ExtrPriority)
-            {
-                return pair.Key;
-            }
-            else if (_extractionMode == SplExtractionMode.ExtrBoth)
-            {
-                var arr = new PhpArray(2);
-                arr.Add("priority", pair.Key);
-                arr.Add("data", pair.Value);
-                return arr;
-            }
-            else
-            {
-                throw new RuntimeException("SplPriorityQueue has unknown extraction mode set.");
+        private PhpValue ForExtractionMode(Pair pair)
+        {
+            switch (_extractionMode)
+            {
+                case SplExtractionMode.ExtrData:
+                    return pair.value;
+
+                case SplExtractionMode.ExtrPriority:
+                    return pair.priority;
+
+                case SplExtractionMode.ExtrBoth:
+                    return new PhpArray(2)
+                    {
+                        { "priority", pair.priority },
+                        { "data", pair.value },
+                    };
+
+                default:
+                    throw new InvalidOperationException();
             }
         }
     }
@@ -1091,89 +1080,69 @@
     /// The SplHeap class provides the main functionalities of a Heap.
     /// </summary>
     [PhpType(PhpTypeAttribute.InheritName), PhpExtension(SplExtension.Name)]
-    public abstract class SplHeap : AbstractHeap<PhpValue>, Iterator, Countable
+    public abstract class SplHeap : Iterator, Countable, IComparer<PhpValue>
     {
-        /// <summary>
-        /// Runtime context.
-        /// </summary>
-        protected readonly Context/*!*/_ctx;
-
-        protected SplHeap(Context ctx) : base()
-        {
-            _ctx = ctx;
+        readonly PriorityQueue<PhpValue> _queue;
+
+        protected SplHeap()
+        {
+            _queue = new PriorityQueue<PhpValue>(this);
+
             __construct();
         }

-        public virtual void __construct() {/* nothing */}
-        public virtual long count()
-        {
-            return _heap.Count;
-        }
+        public void __construct() {/* nothing */}
+
+        protected abstract long compare(PhpValue value1, PhpValue value2);
+
+        public virtual long count() => _queue.Count;

         /// <summary>
         /// Gets the current top of the heap
         /// </summary>
         /// <returns>value on top of the heap</returns>
-        public virtual PhpValue current()
-        {
-            return Peek;
-        }
+        public virtual PhpValue current() => _queue.Peek();

         /// <summary>
         /// Gets the current top of the heap, and removes it
         /// </summary>
         /// <returns>value on top of the heap</returns>
-        public virtual PhpValue extract()
-        {
-            return Pop();
-        }
-        public virtual void insert(PhpValue value)
-        {
-            Insert(value);
-        }
-        public virtual bool isCorrupted()
-        {
-            return _corrupted;
-        }
-        public virtual bool isEmpty()
-        {
-            return count() == 0;
-        }
+        public virtual PhpValue extract() => _queue.TryPop(out var x) ? x : PhpValue.Null;
+
+        public virtual void insert(PhpValue value) => _queue.Insert(value.DeepCopy());
+
+        public virtual bool isCorrupted() => _queue.IsCorrupted;
+
+        public virtual bool isEmpty() => _queue.Count == 0;
+
         public virtual PhpValue key()
         {
             // The key is the theoretical index of the iterater, which is always the last node for the heap
-            return count() - 1;
-        }
+            return _queue.Count - 1;
+        }
+
         public virtual void next()
         {
             // The only thing moving the iterator of a heap does is deletes the top and corrects the heap
-            Pop();
-        }
-        public virtual void recoverFromCorruption()
-        {
-            List<PhpValue> backupList = new List<PhpValue>();
-            foreach (var item in _heap)
-            {
-                backupList.Add(item);
-            }
-            foreach (var item in backupList)
-            {
-                insert(item);
-            }
-
-            _corrupted = false;
-        }
+            _queue.TryPop(out var _);
+        }
+        public virtual void recoverFromCorruption() => _queue.Recover();
+
         public virtual void rewind() { /*nothing*/ }
+
         public virtual PhpValue top()
         {
             // Top of the heap is also the current position of the iterator
-            return Peek;
-        }
+            return _queue.Peek();
+        }
+
         public virtual bool valid()
         {
             // Only checks if the heap contains any nodes
-            return !isEmpty();
-        }
+            return _queue.Count != 0;
+        }
+
+        int IComparer<PhpValue>.Compare(PhpValue x, PhpValue y) => (int)compare(x, y);
     }

     /// <summary>
@@ -1182,28 +1151,10 @@
     [PhpType(PhpTypeAttribute.InheritName), PhpExtension(SplExtension.Name)]
     public class SplMinHeap : SplHeap
     {
-        public SplMinHeap(Context ctx) : base(ctx)
-        {
-        }
-
         /// <summary>
         /// Compare elements in order to place them correctly in the heap while sifting up
         /// </summary>
-        protected override long compare(PhpValue value1, PhpValue value2)
-        {
-            if (value1 < value2)
-            {
-                return 1;
-            }
-            else if (value2 < value1)
-            {
-                return -1;
-            }
-            else
-            {
-                return 0;
-            }
-        }
+        protected override long compare(PhpValue value1, PhpValue value2) => -value1.Compare(value2);
     }

     /// <summary>
@@ -1212,27 +1163,10 @@
     [PhpType(PhpTypeAttribute.InheritName), PhpExtension(SplExtension.Name)]
     public class SplMaxHeap : SplHeap
     {
-        public SplMaxHeap(Context ctx) : base(ctx)
-        {
-        }
-
         /// <summary>
         /// Compare elements in order to place them correctly in the heap while sifting up
         /// </summary>
-        protected override long compare(PhpValue value1, PhpValue value2)
-        {
-            if(value1 > value2)
-            {
-                return 1;
-            }
-            else if (value2 > value1)
-            {
-                return -1;
-            } else
-            {
-                return 0;
-            }
-        }
+        protected override long compare(PhpValue value1, PhpValue value2) => value1.Compare(value2);
     }

     #endregion


properties accessibility within callsite fix

fixes https://github.com/peachpiecompiler/peachpie/issues/642

--- src/Peachpie.Runtime/Dynamic/CallBinder.cs
+++ src/Peachpie.Runtime/Dynamic/CallBinder.cs
@@ -104,7 +104,7 @@
                 }
                 else
                 {
-                    invocation = OverloadBinder.BindOverloadCall(_returnType, bound.TargetInstance, methods, bound.Context, bound.Arguments, bound.IsStaticSyntax, lateStaticType: bound.TargetType);
+                    invocation = OverloadBinder.BindOverloadCall(_returnType, bound.TargetInstance, methods, bound.Context, bound.Arguments, bound.IsStaticSyntax, lateStaticType: bound.TargetType, classContext: bound.ClassContext);
                 }
             }
             else


Allow setting CellPadding through the constructor for TextureFont.

--- TextureFont.cs
+++ TextureFont.cs
@@ -8,13 +8,14 @@
 {
     public class TextureFont : FontBase
     {
-        public TextureFont(string name, int cellWidth, int cellHeight, Texture2D texture)
+        public TextureFont(string name, int cellWidth, int cellHeight, Texture2D texture, int cellPadding = 0)
         {
             Name = name;
             Image = texture;
             CellWidth = cellWidth;
             CellHeight = cellHeight;
-
+            CellPadding = cellPadding;
+
             ConfigureRects();
         }
     }


CR feedback

CR feedback

--- src/Common/Core/Impl/Extensions/CharExtensions.cs
+++ src/Common/Core/Impl/Extensions/CharExtensions.cs
@@ -3,7 +3,7 @@

 namespace Microsoft.Common.Core {
     public static class CharExtensions {
-        public static char[] LineBreakChars => new char[] { '\n', '\r' };
+        public static char[] LineBreakChars { get; } = new char[] { '\n', '\r' };

         public static bool IsLineBreak(this char ch) {
             return ch == '\r' || ch == '\n';


Switched to using method group rather than lambda

--- src/Nancy.Owin/Extensions.cs
+++ src/Nancy.Owin/Extensions.cs
@@ -20,7 +20,7 @@

             if (appDisposing.HasValue)
             {
-                appDisposing.Value.Register(() => nancyOptions.Bootstrapper.Dispose());
+                appDisposing.Value.Register(nancyOptions.Bootstrapper.Dispose);
             }

             return builder.Use(typeof(NancyOwinHost), nancyOptions);


Projection rebuild is not terminated when the deadline hits but a want log messages is written

--- src/Elders.Cronus/Projections/ProjectionPlayer.cs
+++ src/Elders.Cronus/Projections/ProjectionPlayer.cs
@@ -78,9 +78,9 @@
                         }
                         if (DateTime.UtcNow >= replayUntil)
                         {
-                            string message = $"Rebuilding projection `{projectionType.Name}` stopped bacause the deadline has been reached. PROGRESS:{progressCounter} Version:{version} EventType:`{eventType}` Deadline:{replayUntil}.";
-                            log.Info(() => message);
-                            return new ReplayResult(message);
+                            string message = $"Rebuilding projection `{projectionType.Name}` takes longer than expected. PROGRESS:{progressCounter} Version:{version} EventType:`{eventType}` Deadline:{replayUntil}.";
+                            log.Warn(() => message);
+                            //return new ReplayResult(message);
                         }
                         IAggregateRootId arId = GetAggregateRootId(indexCommit.EventOrigin.AggregateRootId);
                         IEventStore eventStore = eventStoreFactory.GetEventStore(tenantResolver.Resolve(arId));


Add Control+V detection.

Add Control+V detection.

--- ML.TypingClassifier/Views/Home/Index.cshtml
+++ ML.TypingClassifier/Views/Home/Index.cshtml
@@ -97,7 +97,7 @@

     function rootOutCheaters() {
       var cs = $('#sentinel').text().length;
-      var isCheater = isComplete() && events.length < cs;
+      var isCheater = isComplete() && (events.length < cs || hasPasted());
       if(isCheater) {
         console.log('You are our newest inductee into the hall of shame.');
       }
@@ -123,6 +123,15 @@
       return text === input;
     }

+    function hasPasted() {
+      for(var i = 0; i < events.length - 1; ++i) {
+        if(events[i].e == "Control" && events[i+1].e == "v") {
+          return true;
+        }
+      }
+      return false;
+    }
+
     function clearText() {
       $('#user-input').val('');
     }
@@ -142,7 +151,7 @@
     <p oncopy="return false" id="sentinel">
       It was the best of times, it was the worst of times...
     </p>
-    <textarea id="user-input" class="input"></textarea>
+    <textarea oncontextmenu="return false;" id="user-input" class="input"></textarea>
     <button class="btn btn-primary" id="score-btn" disabled="true">Go to Results</button>
   </section>
 </main>


- now propagating leaveStreamOpen to the base constructor

--- src/Parquet/ParquetReader.cs
+++ src/Parquet/ParquetReader.cs
@@ -34,7 +34,7 @@
       /// <exception cref="ArgumentNullException">input</exception>
       /// <exception cref="ArgumentException">stream must be readable and seekable - input</exception>
       /// <exception cref="IOException">not a Parquet file (size too small)</exception>
-      public ParquetReader(Stream input, ParquetOptions parquetOptions = null, bool leaveStreamOpen = true) : this(input, true)
+      public ParquetReader(Stream input, ParquetOptions parquetOptions = null, bool leaveStreamOpen = true) : this(input, leaveStreamOpen)
       {

          if (!input.CanRead || !input.CanSeek) throw new ArgumentException("stream must be readable and seekable", nameof(input));