<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Computing &#8211; Henry Poon&#039;s Blog</title>
	<atom:link href="https://blog.henrypoon.com/blog/tag/computing/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.henrypoon.com</link>
	<description></description>
	<lastBuildDate>Sat, 19 Apr 2025 14:15:54 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
<site xmlns="com-wordpress:feed-additions:1">83044199</site>	<item>
		<title>Jenkins pipeline for Spring with beta and prod stages and deployment rollback</title>
		<link>https://blog.henrypoon.com/blog/2017/03/09/jenkins-pipeline-for-spring-with-beta-and-prod-stages-and-deployment-rollback/</link>
					<comments>https://blog.henrypoon.com/blog/2017/03/09/jenkins-pipeline-for-spring-with-beta-and-prod-stages-and-deployment-rollback/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Thu, 09 Mar 2017 08:04:51 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[9]]></category>
		<category><![CDATA[Apache Ant]]></category>
		<category><![CDATA[Apache Maven]]></category>
		<category><![CDATA[Build automation]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Compiling tools]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Const]]></category>
		<category><![CDATA[Continuous integration]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Digital technology]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[future]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[Hole]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java enterprise platform]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[Levant]]></category>
		<category><![CDATA[Password]]></category>
		<category><![CDATA[PATH]]></category>
		<category><![CDATA[Plug]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Rolling]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scripting languages]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[STR]]></category>
		<category><![CDATA[Thou]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[URL]]></category>
		<category><![CDATA[Variable]]></category>
		<category><![CDATA[Z]]></category>
		<category><![CDATA[Zip]]></category>
		<guid isPermaLink="false">https://blog.henrypoon.com/?p=2614</guid>

					<description><![CDATA[In the past couple of days, I&#8217;ve been experimenting a bit with the Jenkins pipeline plugin to create a code deployment pipeline with independent beta and prod stages for a Spring Boot app. I even managed to add rolling back a deployment in case a prod deployment fails! It took me a bit of time [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the past couple of days, I&#8217;ve been experimenting a bit with the <a href="https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Plugin" target="_blank" rel="noopener">Jenkins pipeline plugin</a> to create a code deployment pipeline with independent beta and prod stages for a Spring Boot app. I even managed to add rolling back a deployment in case a prod deployment fails! It took me a bit of time to Google my way through how to do everything, so I figure I just lay it all out here in case it helps other people do the same thing.</p>



<p class="wp-block-paragraph">The nice thing about all of this is that I can push a code change to git, and Jenkins can build it, run through all the tests and then deploy to production automatically.</p>



<h1 class="wp-block-heading">Layout of a pipeline script</h1>



<p class="wp-block-paragraph">Pipeline scripts are written in <a rel="noopener" href="http://www.groovy-lang.org/" target="_blank">Groovy</a>, which is a variant of Java. In general, a pipeline script is laid out like this:</p>



<pre class="wp-block-code"><code lang="python" class="language-python">node {
    def SOME_CONSTANT = "whatever"
    ...

    stage('some stage name like Build') {
        // Stuff to do as a part of this stage
    }

    stage('another stage') {
        // More stuff
    }

    ...
}</code></pre>



<p class="wp-block-paragraph">Each stage represents a stage in the pipeline (e.g. building, beta deployment, prod deployment etc.)</p>



<h1 class="wp-block-heading">Defining some constants</h1>



<p class="wp-block-paragraph">First, a list of constants can be defined that can be used throughout the pipeline so that if the pipeline script gets reused somewhere, only these constants have to be changed. I&#8217;m not aware of anything that lets me reuse a pipeline in Jenkins without copying and pasting the code somewhere else so for now I&#8217;ll have to live with copying and pasting.</p>



<p class="wp-block-paragraph">My project uses Maven so I got Jenkins to download its own copy of Maven that it can use to execute builds and have defined it as a constant. The name I&#8217;ve given it in the Jenkins Global Tool Configuration is &#8220;Maven 3.3.9&#8221; exactly. My project also uses Tomcat so there are some Tomcat specific things in there that may or may not be relevant to your use case.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">def MAVEN_HOME = tool 'Maven 3.3.9'
    def WORKSPACE = pwd()

    def PROJECT_NAME = "name-of-project"
    def WAR_PATH_RELATIVE = "App/target/${PROJECT_NAME}.war"
    def WAR_PATH_FULL = "${WORKSPACE}/${WAR_PATH_RELATIVE}"
    def TOMCAT_CTX_PATH_BETA = "Tomcat-context-path-for-the-beta-stage"
    def TOMCAT_CTX_PATH_PROD = "Tomcat-context-path-for-the-prod-stage"
    def GIT_REPO_URL = "URL-to-git-repo-ending-in-.git"</code></pre>



<h1 class="wp-block-heading">Preparation Stage</h1>



<p class="wp-block-paragraph">First, the code has to be retrieved from the repository before it gets built. Jenkins allows storing username/password pairs so that they can be referenced without having to write out the password in plaintext. Jenkins uses a &#8220;credential ID&#8221; for this.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">    stage('Preparation') {
        git branch: "master",
        credentialsId: "credentials-ID-stored-in-Jenkins-that-can-access-the-git-repo",
        url: "${GIT_REPO_URL}"
    }</code></pre>



<h1 class="wp-block-heading">Build Stage</h1>



<p class="wp-block-paragraph">Next, the code must be built and unit tested. &#8220;mvn clean install&#8221; will do just that (depending on what you want, you can always put in a different maven goal). The junit command is just there to take the resulting XML that gets generated during the build process and posts a graph of how many tests were run for each build.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">    stage('Build') {
        sh "'${MAVEN_HOME}/bin/mvn' clean install"
        junit '**/target/surefire-reports/TEST-*.xml'
    }
</code></pre>



<h1 class="wp-block-heading">Beta Stage</h1>



<p class="wp-block-paragraph">Once the build succeeds, you&#8217;ll want to deploy it to a beta environment, so integration tests can happen. The following happens at this stage:</p>



<ol class="wp-block-list"><li>Get the right credentials to get permissions to Tomcat</li><li>Call the deploy method to deploy the war file in Tomcat (more on that later)</li><li>If the deployment fails for whatever reason, print out the deployment log for debugging and fail the build</li><li>If the deployment succeeds, run the integration tests (the command to do this may differ based on use case)</li></ol>



<pre class="wp-block-code"><code lang="python" class="language-python">    stage('Beta') {
        withCredentials([[$class: 'UsernamePasswordMultiBinding',
            credentialsId: 'credential-id-for-tomcat',
            usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
                // Password is available as an env variable, but will be masked 
                // if you try to print it out any which way
                def output = deploy(WAR_PATH_FULL, TOMCAT_CTX_PATH_BETA,
                        env.USERNAME, env.PASSWORD)
                if (output.contains("FAIL - Deployed application at context path " + 
                        "/${TOMCAT_CTX_PATH_BETA} but context failed to start")) {
                    echo "----- Beta deployment log -----"
                    echo output
                    echo "-------------------------------"
                    currentBuild.result = 'FAILURE'
                    error "Beta stage deployment failure"
                }
            }

        echo "Running integration tests"
        sh "'${MAVEN_HOME}/bin/mvn' -Dtest=*IT test"
        junit '**/target/surefire-reports/TEST-*.xml'
    }</code></pre>



<p class="wp-block-paragraph">The deploy method is what takes care of the actual deployment to Tomcat, which is how the Jenkins build tells Tomcat about the newly built war file. The deploy method is below (be sure to change the server IP and port). Alternatively, I could have built my project as an embedded jar file, but that has a different challenge in figuring out how to get Jenkins to tell the OS to execute the newly built jar file as a particular user.</p>



<ol class="wp-block-list"><li>Based on the Tomcat context path, decide whether a beta or production deployment is happening</li><li>Make a copy of the build war file and add .prod or .beta to the end of it so as to keep the original</li><li>Set the Spring profile to use on the newly copied war file (more on that later)</li><li>Call the curl command to do the actual deployment to Tomcat (more on that later)</li></ol>



<pre class="wp-block-code"><code lang="python" class="language-python">def deploy(warPathFull, tomcatCtxPath, username, password) {
    def envSuffix = ""
    def isBeta = tomcatCtxPath.contains("beta")
    if (isBeta) {
        envSuffix = "beta"
    } else {
        envSuffix = "prod"
    }
    sh script: "cp ${warPathFull} ${warPathFull}.${envSuffix}" 
    setSpringProfile(warPathFull, isBeta)
    def output = sh script: "curl --upload-file '${warPathFull}.${envSuffix}' " +
            "'http://${username}:${password}@localhost:8081/manager/text/deploy" + 
            "?path=/${tomcatCtxPath}&amp;update=true'", returnStdout: true
    return output
}</code></pre>



<p class="wp-block-paragraph">In the case of my project, I&#8217;m building a single war file that does not have a Spring profile (beta/prod) defined. This means that I have to manually define this before I deploy the app to Tomcat since there are some things that differ between beta and prod like database URL&#8217;s. To do this, I wrote a method that opens the war file like a zip (jar/war files are zip files) and adds a line to my application.properties to define a Spring profile.</p>



<p class="wp-block-paragraph">Admittedly, doing this zip file manipulation seems kind of hacky. Alternatively, I could have defined my build such that I had a separate beta build and a prod build to avoid modifying the zip file, but the drawback is that I&#8217;d then have to build my code twice.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">def setSpringProfile(warPathFull, isBeta) {
    def zipFileFullPath = warPathFull + "." + (isBeta ? "beta" : "prod")
    def zipIn = new File(zipFileFullPath)
    def zip = new ZipFile(zipIn)
    def zipTemp = File.createTempFile("temp_${System.nanoTime()}", 'zip')
    zipTemp.deleteOnExit()
    def zos = new ZipOutputStream(new FileOutputStream(zipTemp))
    def toModify = "WEB-INF/classes/application.properties"

    for(e in zip.entries()) {
        if(!e.name.equalsIgnoreCase(toModify)) {
            zos.putNextEntry(e)
            zos &lt;&lt; zip.getInputStream(e).bytes
        } else {
            zos.putNextEntry(new ZipEntry(toModify))
            zos &lt;&lt; zip.getInputStream(e).bytes
            zos &lt;&lt; ("\nspring.profiles.active=" + (isBeta ? "beta" : "prod")).bytes
        }
        zos.closeEntry()
    }

    zos.close()
    zipIn.delete()
    zipTemp.renameTo(zipIn)
}</code></pre>



<p class="wp-block-paragraph">A curl command to Tomcat is what actually does the deployment. To deploy a file to Tomcat, do the following below. This will deploy the war file to Tomcat and instantly run it, thus it will be accessible at the given context path.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">curl --upload-file 'path-to-war-file' http://username:password@server-address:port/manager/text/deploy?path=/tomcat-context-path&amp;update=true</code></pre>



<h1 class="wp-block-heading">Prod Stage</h1>



<p class="wp-block-paragraph">The same kind of stuff happens in the prod stage as in the beta stage with a few exceptions. The following happens at this stage:</p>



<ol class="wp-block-list"><li>Get the right credentials to get permissions to Tomcat</li><li>Call the deploy method to deploy the war file in Tomcat (except this time it is prod)</li><li>If the deployment fails for whatever reason, print out the deployment log for debugging and roll back the deployment</li><li>If the deployment succeeds, save the build files, and then the pipeline is finished. Alternatively, smoke tests can be run at this point, but I did not implement this in my project</li></ol>



<p class="wp-block-paragraph">Rollback is important because if the deployment fails, you don&#8217;t want to be stuck with a broken environment. Since build artifacts are saved on successful deployments, these same artifacts can be brought back if future deployments fail. This means they can be redeployed so that the code can be fixed before another deployment happens.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">    stage('Prod') {
        withCredentials([[$class: 'UsernamePasswordMultiBinding',
            credentialsId: 'credential-id-for-tomcat',
            usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
                // Password is available as an env variable, but will be masked 
                // if you try to print it out any which way
                def output = deploy(WAR_PATH_FULL, TOMCAT_CTX_PATH_PROD, env.USERNAME, env.PASSWORD)
                if (output.contains("FAIL - Deployed application at context path " + 
                        "/${TOMCAT_CTX_PATH_PROD} but context failed to start")) {
                    echo "Prod stage deployment failure, rolling back deployment"
                    echo "----- Prod deployment log -----"
                    echo output
                    echo "-------------------------------"
                    step([$class: 'CopyArtifact',
                            filter: "${WAR_PATH_RELATIVE}",
                            fingerprintArtifacts: true,
                            projectName: "${PROJECT_NAME}",
                            target: "${WAR_PATH_RELATIVE}.rollback"])
                    deploy(WAR_PATH_FULL + ".rollback/" + WAR_PATH_RELATIVE,
                            TOMCAT_CTX_PATH_PROD, env.USERNAME, env.PASSWORD)
                    currentBuild.result = 'FAILURE'
                    error "Prod deployment rolled back"
                } else {
                    archiveArtifacts artifacts: "${WAR_PATH_RELATIVE}*", fingerprint: true
                }
            }
    }
</code></pre>



<p class="wp-block-paragraph">At the end you get to have something like this:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="600" height="882" src="https://i0.wp.com/blog.henrypoon.com/wp-content/uploads/2017/03/JenkinsPipeline.png?resize=600%2C882&#038;ssl=1" alt="" class="wp-image-2638"/></figure>
</div>


<p class="wp-block-paragraph">That pretty much sums up the whole Jenkins pipeline that I&#8217;ve been using lately for Spring projects!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2017/03/09/jenkins-pipeline-for-spring-with-beta-and-prod-stages-and-deployment-rollback/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2614</post-id>	</item>
		<item>
		<title>Groovy/Grails unable to resolve class &#8211; even if the class is in the same package</title>
		<link>https://blog.henrypoon.com/blog/2015/01/26/groovygrails-unable-to-resolve-class-even-if-the-class-is-in-the-same-package/</link>
					<comments>https://blog.henrypoon.com/blog/2015/01/26/groovygrails-unable-to-resolve-class-even-if-the-class-is-in-the-same-package/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Tue, 27 Jan 2015 06:44:33 +0000</pubDate>
				<category><![CDATA[gaming]]></category>
		<category><![CDATA[Apache Groovy]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Cross-platform software]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Digital technology]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[Integrated development environments]]></category>
		<category><![CDATA[ise]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Java platform]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[Writing]]></category>
		<guid isPermaLink="false">https://www.henrypoon.com/blog/?p=2019</guid>

					<description><![CDATA[The Problem Every now and then I get this annoying problem in GGTS (Grails/Groovy Tool Suite &#8211; Version 3.6.2.RELEASE at the time of this writing), where the IDE just complains about how it can&#8217;t resolve a class. &#160;The weird thing is that the file that the IDE is complaining about is in the same package [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>The Problem</h1>
<p>Every now and then I get this annoying problem in GGTS (Grails/Groovy Tool Suite &#8211; Version 3.6.2.RELEASE at the time of this writing), where the IDE just complains about how it can&#8217;t resolve a class. &nbsp;The weird thing is that the file that the IDE is complaining about is in the same package as the class that I&#8217;m trying to use. &nbsp;It built before, and the source hadn&#8217;t changed &#8211; so clearly this should not be happening.</p>
<h1>The Fix</h1>
<p>Hitting the Clean button on the Eclipse side (Project -&gt; Clean) seems to make the errors go away.</p>
<p>This apparently has been a problem since June 2010 (forum post reference <a href="http://forum.spring.io/forum/spring-projects/springsource-tool-suite/83417-groovy-unable-to-resolve-class-although-same-package-again" target="_blank" rel="noopener noreferrer">here</a>), so I&#8217;m surprised that it is still an issue in the current version.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2015/01/26/groovygrails-unable-to-resolve-class-even-if-the-class-is-in-the-same-package/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2019</post-id>	</item>
		<item>
		<title>Disabling Mouse Acceleration in Ubuntu</title>
		<link>https://blog.henrypoon.com/blog/2015/01/25/disabling-mouse-acceleration-in-ubuntu/</link>
					<comments>https://blog.henrypoon.com/blog/2015/01/25/disabling-mouse-acceleration-in-ubuntu/#comments</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Sun, 25 Jan 2015 08:31:32 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[AWK]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[Computer mice]]></category>
		<category><![CDATA[Computer mouse]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Counter-Strike]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Digital technology]]></category>
		<category><![CDATA[DirectInput]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mass]]></category>
		<category><![CDATA[mouse acceleration]]></category>
		<category><![CDATA[Plan]]></category>
		<category><![CDATA[Plug]]></category>
		<category><![CDATA[Programming languages]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Sleep]]></category>
		<category><![CDATA[STR]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[Trac]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">https://www.henrypoon.com/blog/?p=1955</guid>

					<description><![CDATA[I&#8217;ve been quite accustomed to disabling mouse acceleration on my Windows machine (thanks to playing massive amounts of Counter-Strike back in the day), but now that I&#8217;ve started to use Linux a bit more, I&#8217;ve found that disabling mouse acceleration was not as easy as in Windows. Script I&#8217;ve managed to produce a script to [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I&#8217;ve been quite accustomed to disabling mouse acceleration on my Windows machine (thanks to playing massive amounts of Counter-Strike back in the day), but now that I&#8217;ve started to use Linux a bit more, I&#8217;ve found that disabling mouse acceleration was not as easy as in Windows.</p>



<h1 class="wp-block-heading">Script</h1>



<p class="wp-block-paragraph">I&#8217;ve managed to produce a script to disable mouse acceleration (works for me on Ubuntu 14.04).  However, this script needs to be run every time the computer boots because the settings don&#8217;t stay.  Here is the script:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">#wait for the desktop to settle
sleep 5

#gets the hardware id's of all mice plugged into the system
hardwareIds=$(xinput | grep -i mouse | awk '{print substr($(NF-3),4)}')

#turn off mouse acceleration
for i in $hardwareIds
do
xinput set-prop ${i} 'Device Accel Profile' -1
xinput set-prop ${i} 'Device Accel Velocity Scaling' 1
done</code></pre>



<h1 class="wp-block-heading">Explanation</h1>



<p class="wp-block-paragraph">The script works by extracting the hardware id&#8217;s of the mice that are connected to the system and then applying properties to them that disable mouse acceleration for that device.  The extraction of the mouse hardware id&#8217;s are done with this:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">#gets the hardware id's of all mice plugged into the system
hardwareIds=$(xinput | grep -i mouse | awk '{print substr($(NF-3),4)}')</code></pre>



<p class="wp-block-paragraph">Calling xinput in the Terminal will list all the connected input devices, which is grepped (case insensitively) for the word &#8220;mouse&#8221;, which gives something like this on my machine:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>⎜ ↳ Logitech G500s Laser Gaming Mouse id=14 [slave pointer (2)]<br>⎜ ↳ Logitech G500s Laser Gaming Mouse id=15 [slave pointer (2)]</p></blockquote>



<p class="wp-block-paragraph">The call to awk extracts the hardware id&nbsp;from those two lines (14, 15 in the above case) and stores them in an array that is iterated through when setting the mouse properties.</p>



<h1 class="wp-block-heading">Reference</h1>



<p class="wp-block-paragraph">This is the website that showed me how to disable mouse acceleration to begin with:&nbsp;<a href="http://ubuntuforums.org/showthread.php?t=1734400" target="_blank" rel="noopener noreferrer">http://ubuntuforums.org/showthread.php?t=1734400</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2015/01/25/disabling-mouse-acceleration-in-ubuntu/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1955</post-id>	</item>
		<item>
		<title>Resolving dd-wrt bug that prevented computers on a LAN with wired connection from talking/pinging/communicating with each other</title>
		<link>https://blog.henrypoon.com/blog/2015/01/05/resolving-dd-wrt-bug-that-prevented-computers-on-a-lan-with-wired-connection-from-talkingpingingcommunicating-with-each-other/</link>
					<comments>https://blog.henrypoon.com/blog/2015/01/05/resolving-dd-wrt-bug-that-prevented-computers-on-a-lan-with-wired-connection-from-talkingpingingcommunicating-with-each-other/#comments</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Tue, 06 Jan 2015 06:27:16 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[Computer networking]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Custom firmware]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[dd-wrt]]></category>
		<category><![CDATA[destination host unreachable]]></category>
		<category><![CDATA[Event]]></category>
		<category><![CDATA[Find]]></category>
		<category><![CDATA[Firmware]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Link]]></category>
		<category><![CDATA[Linksys routers]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[Netgear WGR614L]]></category>
		<category><![CDATA[Networking hardware]]></category>
		<category><![CDATA[Page]]></category>
		<category><![CDATA[Router]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[System software]]></category>
		<category><![CDATA[Telnet]]></category>
		<category><![CDATA[wired connection]]></category>
		<guid isPermaLink="false">http://henrypoon.mooo.com/blog/resolving-dd-wrt-bug-that-prevented-computers-on-a-lan-with-wired-connection-from-talkingpingingcommunicating-with-each-other</guid>

					<description><![CDATA[I just had a problem where the computers in my house that were all using a wired connection could not talk to each other. &#160;Computers on wired connections could not ping, and ping kept giving an error saying &#8220;destination host unreachable&#8221;. &#160;I found the solution in a very hard to find forum post on the [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I just had a problem where the computers in my house that were all using a wired connection could not talk to each other. &nbsp;Computers on wired connections could not ping, and ping kept giving an error saying &#8220;destination host unreachable&#8221;. &nbsp;I found the solution in a very hard to find forum post on the dd-wrt forums.</p>



<p class="wp-block-paragraph"><strong>This specific instance of the problem affects users of the dd-wrt firmware. &nbsp;In my case, I am using build 24461 of the firmware.</strong> &nbsp;The solution is to run the following commands on the router (either with ssh or telnet):</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">swconfig dev eth0 set enable_vlan 1
swconfig dev eth0 set apply</code></pre>



<p class="wp-block-paragraph">I&#8217;ve since put this in the startup commands that the router will execute, so these settings will stay even after a router reboot.</p>



<p class="wp-block-paragraph">For some routers, it might be eth1 instead of eth0. &nbsp;It depends on which network interface is assigned to the WAN. &nbsp;This can be check in the router page under Setup &gt; Networking.</p>



<p class="wp-block-paragraph">Link to forum post: <a href="http://www.dd-wrt.com/phpBB2/viewtopic.php?t=152738&amp;postdays=0&amp;postorder=asc&amp;start=0" target="_blank" rel="noreferrer noopener">http://www.dd-wrt.com/phpBB2/viewtopic.php?t=152738&amp;postdays=0&amp;postorder=asc&amp;start=0</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2015/01/05/resolving-dd-wrt-bug-that-prevented-computers-on-a-lan-with-wired-connection-from-talkingpingingcommunicating-with-each-other/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1928</post-id>	</item>
		<item>
		<title>Proof of the Farthest-in-Future Optimal Caching Algorithm</title>
		<link>https://blog.henrypoon.com/blog/2014/02/02/proof-of-the-farthest-in-future-optimal-caching-algorithm/</link>
					<comments>https://blog.henrypoon.com/blog/2014/02/02/proof-of-the-farthest-in-future-optimal-caching-algorithm/#comments</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Sun, 02 Feb 2014 23:19:13 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[All That]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Cache replacement policies]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Comment]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[Computer architecture]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Contents]]></category>
		<category><![CDATA[CPU cache]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Digital technology]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Event]]></category>
		<category><![CDATA[farthest-first]]></category>
		<category><![CDATA[future]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[greedy algorithms]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[optimal caching]]></category>
		<category><![CDATA[Outside]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[Thou]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[tuna]]></category>
		<category><![CDATA[Z]]></category>
		<guid isPermaLink="false">http://henrypoon.mooo.com/blog/proof-of-the-farthest-in-future-optimal-caching-algorithm</guid>

					<description><![CDATA[This topic came up in one of my lectures and I found it a little challenging to understand the proof so I thought I&#8217;d write it down as best as I could explain it so that I could understand it better and possibly help other people understand it better. &#160;Feel free to comment/ask questions/correct me, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>This topic came up in one of my lectures and I found it a little challenging to understand the proof so I thought I&#8217;d write it down as best as I could explain it so that I could understand it better and possibly help other people understand it better. &nbsp;Feel free to comment/ask questions/correct me, etc.</p>
<p>In a computer, there are various methods of storing information. &nbsp;Information can be stored in the processor cache, RAM, hard disk, etc. &nbsp;It can be faster to request information from a storage medium that is smaller. &nbsp;However, this smaller storage medium cannot fit all the possible information that can be requested. &nbsp;So the idea is to insert a portion of the data into the faster, smaller medium (the <strong>cache</strong>) and the rest into the slower, larger medium (<strong>main memory)</strong>.</p>
<p>If a request is made and the data is not available in the faster, smaller medium first, then the data will be read from the slower, larger medium &#8211; this is what is known as a <strong>cache miss</strong>.</p>
<p>Given that all the data cannot possibly live in the cache, there must be a way to minimize the amount of times that the data must be read from the main memory.</p>
<h1>Optimal Caching &#8211; Farthest-in-Future</h1>
<h2>The Algorithm</h2>
<p>The idea is that there is an algorithm that minimizes the amount of cache misses that occur for a set of requests. &nbsp;The <em>Farthest-in-Future Algorithm&nbsp;</em>evicts the item in the cache that is not requested until the farthest in the future. &nbsp;For example, given the following cache with items &#8220;a&#8221; through &#8220;f&#8221;.</p>
<table>
<tbody>
<tr>
<td>Cache Items</td>
<td>a b c d e f</td>
</tr>
<tr>
<td>Future Queries</td>
<td>g a b c e d a b b f</td>
</tr>
</tbody>
</table>
<p><span style="line-height:1.5em;">It is clear that &#8220;g&#8221; does not exist in the set of cache items and so when &#8220;g&#8221; is requested, a cache miss will result. An item will be evicted because &#8220;g&#8221; is not in the cache. &nbsp;According to the </span><em style="line-height:1.5em;">Farthest-in-Future Algorithm</em><span style="line-height:1.5em;">, element &#8220;f&#8221; will be evicted since it is the one that will be used furthest in the future.</span></p>
<h2>Definitions</h2>
<p><strong>Cache Miss</strong> &#8211; Occurs when it is necessary to bring in an item from the main memory into the cache</p>
<p><strong>Schedule</strong>&nbsp;&#8211; A list that contains, for each, request, which item is brought into the cache, and which item is evicted</p>
<p><strong>Reduced Schedule</strong> &#8211; a schedule that only brings in an item when there is a request for that item &#8211; so a non-reduced schedule would bring an item into the cache outside of a request for that item</p>
<h2>Theorem</h2>
<p>To be shown:</p>
<blockquote><p><em>Farthest-in-Future</em> is the optimal algorithm that minimizes the number of cache misses.</p></blockquote>
<p>To prove this, let&#8217;s say there is a schedule SFF&nbsp;that follows the&nbsp;<em>Farthest-in-Future Algorithm</em>&nbsp;and that there is a schedule optimal S<sup><em></sup>&nbsp;that has a minimum number of cache misses. It can be shown that it is possible to transform&nbsp;S<sup></em></sup>&nbsp;into SFF&nbsp;by performing a series of evictions without increasing the number of cache misses. &nbsp;Since&nbsp;S<sup>*</sup>&nbsp;is already optimal, and the number of cache misses did not increase, then SFF&nbsp;must be optimal.</p>
<p>To perform one transformation, the statement below can be used. &nbsp;Right now, it isn&#8217;t all that clear why this is necessary, but it should become clearer further on.</p>
<blockquote><p>Let S&nbsp;be a reduced schedule that is the same as SFF&nbsp;for the first j requests, then there is a reduced schedule S&#8217;&nbsp;that is the same as SFF&nbsp;for the first j+1 requests, and incurs no more misses than S</p></blockquote>
<h2>Proof</h2>
<p>Let&#8217;s say the cache at the start looks like this. &nbsp;S and SFF&nbsp;have the exact same contents (this is what was defined in the previous section).</p>
<table>
<tbody>
<tr>
<td>S</td>
<td>a b c d</td>
</tr>
<tr>
<td>SFF</td>
<td>a b c d</td>
</tr>
</tbody>
</table>
<p><span style="line-height:1.5em;">Given a schedule S, it can be shown that any request can be made, and the resulting schedule would be equal to the ideal algorithm and does not increase the number of cache misses. &nbsp;Essentially, we want S = S&#8217; = SFF&nbsp;after a request is made and that the number of cache misses have not increased. &nbsp;If this can be shown for all different scenarios that items are requested, then&nbsp;</span><em style="line-height:1.5em;">Farthest-in-Future</em><span style="line-height:1.5em;"> is the ideal algorithm.</span></p>
<h3>Case 1: Item Is Already in the Cache</h3>
<p>Now let&#8217;s say the next item to be requested is item &#8220;d&#8221;. &nbsp;It is clear that this item exists in both caches and no evictions are necessary. &nbsp;Since no evictions are necessary, SFF&nbsp;does not change. &nbsp;It was specified in a prior section that there is a schedule S&#8217; that equals SFF, which incurs no more misses than S.</p>
<table>
<tbody>
<tr>
<td>SFF</td>
<td>a b c d</td>
<td>Read&nbsp;d</td>
</tr>
<tr>
<td>S</td>
<td>a b c d</td>
<td>Read&nbsp;d</td>
</tr>
<tr>
<td>S&#8217;</td>
<td>a b c d</td>
<td>Read&nbsp;d</td>
</tr>
</tbody>
</table>
<p>Here, S = S&#8217; because no changes had to be made to the cache and there were no cache misses. &nbsp;After the request for item &#8220;d&#8221;, S = S&#8217;, each with zero cache misses, which is a valid outcome.</p>
<h3>Case 2: Item Is Not in the Cache, S and SFF&nbsp;Evict the Same Item</h3>
<p>Let&#8217;s say the next item to be requested is item &#8220;e&#8221;. &nbsp;Neither cache has this item, so an eviction will have to be made. &nbsp;Let&#8217;s also say SFF&nbsp;and S both choose to evict item &#8220;a&#8221; to make room for &#8220;e&#8221;. &nbsp;It was specified in a prior section that there is a schedule S&#8217; that equals SFF, which incurs no more misses than S.</p>
<table>
<tbody>
<tr>
<td>SFF</td>
<td>b c d e</td>
<td>Evict a; Read e</td>
</tr>
<tr>
<td>S</td>
<td>b c d e</td>
<td>Evict a; Read e</td>
</tr>
<tr>
<td>S&#8217;</td>
<td>b c d e</td>
<td>Evict a; Read e</td>
</tr>
</tbody>
</table>
<p>Here S = S&#8217; because S and SFF&nbsp;both evicted the same item. &nbsp;Both S and S&#8217; each have one cache miss (no increase relative to one another), which is a valid outcome.</p>
<h3>Case 3: Item Is Not in the Cache, S and SFF&nbsp;Each Evict A Different Item</h3>
<p>This is where the proof can become more confusing (as if it isn&#8217;t already). &nbsp;Let&#8217;s say the next item to be requested is &#8220;e&#8221;. &nbsp;Let&#8217;s also say that the ideal algorithm, SFF, evicts &#8220;a&#8221; and S evicts &#8220;b&#8221;.&nbsp;It was specified in a prior section that there is a schedule S&#8217; that equals SFF, which incurs no more misses than S. This means that in order to get S&#8217; = SFF, S&#8217; should evict &#8220;a&#8221; in order to match with SFF.</p>
<table>
<tbody>
<tr>
<td>SFF</td>
<td>b c d e</td>
<td>Evict a; Insert&nbsp;e</td>
</tr>
<tr>
<td>S</td>
<td>a c d e</td>
<td>Evict b; Insert&nbsp;e</td>
</tr>
<tr>
<td>S&#8217;</td>
<td>b c d e</td>
<td>Evict a; Insert&nbsp;e</td>
</tr>
</tbody>
</table>
<p>Here, S does not agree with&nbsp;S&#8217; = SFF. &nbsp;Essentially, these two schedules behave the same, so long as future requests do not request items &#8220;a&#8221; or &#8220;b&#8221;. &nbsp;This shows that there is a schedule S&#8217; that equals SFF, but it is not known whether or not S&#8217; has no more cache misses than S, since &#8220;a&#8221; or &#8220;b&#8221; can be requested in the future, which can determine whether S or S&#8217; has more cache misses. &nbsp;From this point onward, S and S&#8217; behave the same until one of the following happens:</p>
<h4>Case 3a: Item Is in SFF, But Not S; S Evicts &#8220;a&#8221;</h4>
<p>Let&#8217;s say eventually item &#8220;b&#8221; gets requested. &nbsp;In this case, S&#8217; and SFF do not need to change. &nbsp;All S has to do is evict &#8220;a&#8221; to make room for &#8220;b&#8221;. &nbsp;In this case, S has two total cache misses (from request &#8220;e&#8221; and &#8220;b&#8221;), while SFF and S&#8217; each have only one cache miss, thus fulfilling the cache miss requirement.</p>
<table>
<tbody>
<tr>
<td>SFF</td>
<td>b c d e</td>
<td>Insert&nbsp;b</td>
</tr>
<tr>
<td>S</td>
<td>b c d e</td>
<td>Evict a; Insert&nbsp;b</td>
</tr>
<tr>
<td>S&#8217;</td>
<td>b c d e</td>
<td>Insert&nbsp;b</td>
</tr>
</tbody>
</table>
<h4>Case 3b: Item Is Neither in SFF Nor S</h4>
<p>Let&#8217;s say eventually item &#8220;f&#8221; gets requested. &nbsp;S&#8217;, SFF, and S all need to make an eviction. S&#8217; and SFF can evict &#8220;b&#8221; to make room for &#8220;f&#8221;, and S can evict &#8220;a&#8221; to make room for &#8220;f&#8221;. &nbsp;In this case, each schedule as two cache misses, thus fulfilling the cache miss requirement.</p>
<table>
<tbody>
<tr>
<td>SFF</td>
<td>c d e f</td>
<td>Evict b; Insert&nbsp;f</td>
</tr>
<tr>
<td>S</td>
<td>c d e f</td>
<td>Evict a; Insert&nbsp;f</td>
</tr>
<tr>
<td>S&#8217;</td>
<td>c d e f</td>
<td>Evict b; Insert&nbsp;f</td>
</tr>
</tbody>
</table>
<h4>Case 3c: Item Is in SFF, But Not S; S Evicts Item Not Equal to &#8220;a&#8221;</h4>
<p>Let&#8217;s say eventually item &#8220;b&#8221; gets requested and S evicts an item that isn&#8217;t &#8220;a&#8221;, say &#8220;c&#8221;. &nbsp;Now, SFF and S&#8217; both already have &#8220;b&#8221; in the cache. &nbsp;In order to synchronize S and S&#8217; to make them comparable to see how many cache misses each have, S&#8217; and SFF will evict &#8220;c&#8221; to make room for &#8220;a&#8221;.</p>
<table>
<tbody>
<tr>
<td>SFF</td>
<td>a b d e</td>
<td>Evict c; Insert a</td>
</tr>
<tr>
<td>S</td>
<td>a b d e</td>
<td>Evict c; Insert&nbsp;b</td>
</tr>
<tr>
<td>S&#8217;</td>
<td>a b d e</td>
<td>Evict c; Insert&nbsp;a</td>
</tr>
</tbody>
</table>
<p>Since &#8220;a&#8221; is being brought into the cache without a request for &#8220;a&#8221;, this makes S&#8217; and SFF no longer a reduced schedule. &nbsp;However, the proof calls for S&#8217; and SFF being a reduced schedule. &nbsp;Fortunately, it is possible to transform an unreduced schedule into a reduced one. &nbsp;In this case, each schedule has two cache misses, thus fulfilling the cache miss requirement.</p>
<h4>Case 3d: Item Is Not in SFF, But in S</h4>
<p>The only item that is in S and not SFF is item &#8220;a&#8221;. &nbsp;SFF had evicted it initially at the beginning of Case 3. &nbsp;Since SFF had evicted it, it must have been the item that would be requested furthest into the future. &nbsp;Therefore, it is not possible for item &#8220;a&#8221; to be requested before other items.</p>
<p>&nbsp;</p>
<p>After going through all possible eviction decisions that the schedules can do, it was shown that for each scenario, there was indeed a schedule S&#8217; = SFF, where the cache misses incurred in S&#8217; no more than S.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2014/02/02/proof-of-the-farthest-in-future-optimal-caching-algorithm/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1799</post-id>	</item>
		<item>
		<title>Removing the annoying Windows language hotkeys “Ctrl+Space”, “Shift+Space” etc. that toggles the full-width/half-width characters on the Chinese IME</title>
		<link>https://blog.henrypoon.com/blog/2012/01/03/removing-the-annoying-windows-language-hotkeys-ctrlspace-shiftspace-etc-that-toggles-the-full-widthhalf-width-characters-on-the-chinese-ime/</link>
					<comments>https://blog.henrypoon.com/blog/2012/01/03/removing-the-annoying-windows-language-hotkeys-ctrlspace-shiftspace-etc-that-toggles-the-full-widthhalf-width-characters-on-the-chinese-ime/#comments</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Tue, 03 Jan 2012 23:04:52 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[9]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[Click]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Control Panel]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Digital technology]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Event]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Family]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Hex]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[Input method]]></category>
		<category><![CDATA[Installation]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Keyboard shortcut]]></category>
		<category><![CDATA[Language]]></category>
		<category><![CDATA[Lie]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Microsoft Office]]></category>
		<category><![CDATA[Page]]></category>
		<category><![CDATA[STR]]></category>
		<category><![CDATA[UNC]]></category>
		<category><![CDATA[User interface techniques]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows Registry]]></category>
		<category><![CDATA[Z]]></category>
		<guid isPermaLink="false">http://henrypoon.mooo.com/blog/removing-the-annoying-windows-language-hotkeys-%e2%80%9cctrlspace%e2%80%9d-%e2%80%9cshiftspace%e2%80%9d-etc-that-toggles-the-full-widthhalf-width-characters-on-the-chinese-ime</guid>

					<description><![CDATA[There is a bug in Windows that prevents switching the hotkey of some of the language bar features.  The user is unable to change any of the hotkeys in the Advanced Key Settings page.  Some of the changed hotkeys revert to what they were before when the user tries to apply the changes.  Two keys [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">There is a bug in Windows that prevents switching the hotkey of some of the language bar features.  The user is unable to change any of the hotkeys in the Advanced Key Settings page.  Some of the changed hotkeys revert to what they were before when the user tries to apply the changes.  Two keys in particular, the “Ctrl+Space” and the “Shift+Space” key combinations are the most annoying.</p>



<p class="wp-block-paragraph">These two keys toggle the full-width (double-byte), and the half-width (single-byte&#8221;) character sets when typing with the Chinese IME.&nbsp; Full-width characters look like “ｔｈｉｓ “ while half-width is what people are normally used to.&nbsp; The default key combinations are easy to press by accident in situations such as capitalizing a title.&nbsp; Therefore, it is beneficial to remove this hotkey.</p>



<h1 class="wp-block-heading">Solution</h1>



<p class="wp-block-paragraph">Because changing the key settings manually through Windows does not work, one must go through the registry.&nbsp; The following fix applies to the current user that is logged in.&nbsp; Apply the following registry keys and then restart the computer.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Windows Registry Editor Version 5.00</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys]</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000010]<br>&#8220;Virtual Key&#8221;=hex:ff,00,00,00<br>&#8220;Key Modifiers&#8221;=hex:00,c0,00,00<br>&#8220;Target IME&#8221;=hex:00,00,00,00</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000011]<br>&#8220;Virtual Key&#8221;=hex:ff,00,00,00<br>&#8220;Key Modifiers&#8221;=hex:00,c0,00,00<br>&#8220;Target IME&#8221;=hex:00,00,00,00</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000012]<br>&#8220;Virtual Key&#8221;=hex:ff,00,00,00<br>&#8220;Key Modifiers&#8221;=hex:00,c0,00,00<br>&#8220;Target IME&#8221;=hex:00,00,00,00</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000070]<br>&#8220;Virtual Key&#8221;=hex:ff,00,00,00<br>&#8220;Key Modifiers&#8221;=hex:00,c0,00,00<br>&#8220;Target IME&#8221;=hex:00,00,00,00</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000071]<br>&#8220;Virtual Key&#8221;=hex:ff,00,00,00<br>&#8220;Key Modifiers&#8221;=hex:00,c0,00,00<br>&#8220;Target IME&#8221;=hex:00,00,00,00</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000072]<br>&#8220;Virtual Key&#8221;=hex:ff,00,00,00<br>&#8220;Key Modifiers&#8221;=hex:00,c0,00,00<br>&#8220;Target IME&#8221;=hex:00,00,00,00</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000201]<br>&#8220;Virtual Key&#8221;=hex:ff,00,00,00<br>&#8220;Key Modifiers&#8221;=hex:00,c0,00,00<br>&#8220;Target IME&#8221;=hex:00,00,00,00</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000202]<br>&#8220;Virtual Key&#8221;=hex:ff,00,00,00<br>&#8220;Key Modifiers&#8221;=hex:00,c0,00,00<br>&#8220;Target IME&#8221;=hex:00,00,00,00</p><p>[HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000203]<br>&#8220;Virtual Key&#8221;=hex:ff,00,00,00<br>&#8220;Key Modifiers&#8221;=hex:00,c0,00,00<br>&#8220;Target IME&#8221;=hex:00,00,00,00</p></blockquote>



<p class="wp-block-paragraph">In the registry, one can also navigate to “HKEY_CURRENT_USERControl PanelInput MethodHot Keys” and see a list of folders with names that have eight numbers in them with leading zeroes.&nbsp; Each folder here represents a particular hotkey related to an IME.&nbsp; Clicking on one of these folders will show data for these keys.</p>



<p class="wp-block-paragraph">Setting “Key Modifiers” to “00 c0 00 00” removes the use of the Ctrl and Alt key for the hotkey.<br>Setting “Virtual Key” to “ff 00 00 00” sets the key to nothing.<br>The key “Target IME” can be left as is.</p>



<p class="wp-block-paragraph">In the case of the “Shift+Space” hotkey, “Shift” is the key modifier and “Space” is the virtual key.</p>



<p class="wp-block-paragraph">It is unclear which folder corresponds to the key that toggles the character shape, therefore this fix is a blanket approach.</p>



<h1 class="wp-block-heading">If the Above Still Fails</h1>



<p class="wp-block-paragraph">Try combining the fix with an installation of Microsoft Office IME 2010, which can be downloaded here: <a href="http://www.microsoft.com/downloads/zh-tw/details.aspx?FamilyID=60984ecd-9575-411a-bd38-2294f17c4131&amp;displaylang=zh-tw" target="_blank" rel="noreferrer noopener">http://www.microsoft.com/downloads/zh-tw/details.aspx?FamilyID=60984ecd-9575-411a-bd38-2294f17c4131&amp;displaylang=zh-tw</a>.  Despite the name, it does not require Microsoft Office to be installed. After installing, apply the registry keys and restart.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2012/01/03/removing-the-annoying-windows-language-hotkeys-ctrlspace-shiftspace-etc-that-toggles-the-full-widthhalf-width-characters-on-the-chinese-ime/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1305</post-id>	</item>
		<item>
		<title>Running non-Unicode programs with multiple languages in Windows</title>
		<link>https://blog.henrypoon.com/blog/2011/12/30/running-non-unicode-programs-with-multiple-languages-in-windows/</link>
					<comments>https://blog.henrypoon.com/blog/2011/12/30/running-non-unicode-programs-with-multiple-languages-in-windows/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Fri, 30 Dec 2011 23:32:41 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[AppLocale]]></category>
		<category><![CDATA[Arial Unicode MS]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[Character encoding]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Digital technology]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[Family]]></category>
		<category><![CDATA[Find]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[ise]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Language]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Link]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Mojibake]]></category>
		<category><![CDATA[Question mark]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[STR]]></category>
		<category><![CDATA[Struct]]></category>
		<category><![CDATA[Thou]]></category>
		<category><![CDATA[Unicode]]></category>
		<category><![CDATA[Unicode input]]></category>
		<category><![CDATA[UTF-8]]></category>
		<category><![CDATA[Variable]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows XP]]></category>
		<guid isPermaLink="false">http://henrypoon.mooo.com/blog/running-non-unicode-programs-with-multiple-languages-in-windows</guid>

					<description><![CDATA[For those who are multi-lingual, they may find a need to install programs on their computer that are localised in different languages.&#160; While it is easy to go into the Windows language options and set a particular language for non-Unicode programs, this method does not work if more than one needs to run different non-Unicode [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">For those who are multi-lingual, they may find a need to install programs on their computer that are localised in different languages.&nbsp; While it is easy to go into the Windows language options and set a particular language for non-Unicode programs, this method does not work if more than one needs to run different non-Unicode programs in different languages.&nbsp; That means, if one uses Traditional Chinese as the non-Unicode language, programs using Simplified Chinese will not display properly!</p>



<p class="wp-block-paragraph">The following solution is proposed:</p>



<h1 class="wp-block-heading">Use Microsoft AppLocale</h1>



<p class="wp-block-paragraph">Microsoft AppLocale allows running a program using a particular language without changing the Windows language setting.&nbsp; That means, one can change between multiple languages on-the-fly for each program.</p>



<p class="wp-block-paragraph">According to Microsoft:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Unicode based platforms, such as Windows XP, emulate the language environment required to run non-Unicode applications by internally converting application&#8217;s non-Unicode text data to Unicode using a system-wide variable commonly called the system local (or language for non-Unicode applications). The language of the non-Unicode applications should be of the same script or family as the one defined by the system locale. Failing to meet this condition results in display of garbage characters in the UI of the application.</p></blockquote>



<p class="wp-block-paragraph">Download link</p>



<p class="wp-block-paragraph">Once downloaded, install and run it.&nbsp; Follow the instructions and choose what program that is to be run at the wanted language.&nbsp; If the correct language was chosen, the application should show the correct characters.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2011/12/30/running-non-unicode-programs-with-multiple-languages-in-windows/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1284</post-id>	</item>
		<item>
		<title>New Laptop</title>
		<link>https://blog.henrypoon.com/blog/2011/06/20/new-laptop/</link>
					<comments>https://blog.henrypoon.com/blog/2011/06/20/new-laptop/#comments</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Mon, 20 Jun 2011 15:45:14 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[APT]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Canada]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[Classes of computers]]></category>
		<category><![CDATA[Cloud clients]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Dell]]></category>
		<category><![CDATA[Dia]]></category>
		<category><![CDATA[Drive]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Euro]]></category>
		<category><![CDATA[Europe]]></category>
		<category><![CDATA[Final]]></category>
		<category><![CDATA[Find]]></category>
		<category><![CDATA[German]]></category>
		<category><![CDATA[Germany]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[In Germany]]></category>
		<category><![CDATA[ise]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Laptop]]></category>
		<category><![CDATA[Lie]]></category>
		<category><![CDATA[Microsoft Surface]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[Netbook]]></category>
		<category><![CDATA[NVIDIA]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Over]]></category>
		<category><![CDATA[Personal computing]]></category>
		<category><![CDATA[Pho]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[rain]]></category>
		<category><![CDATA[rice]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Screws]]></category>
		<category><![CDATA[Student]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Thou]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[tuna]]></category>
		<category><![CDATA[USB]]></category>
		<category><![CDATA[USB 3.0]]></category>
		<category><![CDATA[Vancouver]]></category>
		<category><![CDATA[Week]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Wireless]]></category>
		<category><![CDATA[Z]]></category>
		<guid isPermaLink="false">http://henrypoon.mooo.com/blog/new-laptop</guid>

					<description><![CDATA[After waiting for two and a half weeks for my laptop to arrive (not to mention that I had to pay 140 euros in import taxes), it finally came! In fact, I&#8217;m happily typing this post using this laptop and I can continue to keep posting things that I never got a chance to (like [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>After waiting for two and a half weeks for my laptop to arrive (not to mention that I had to pay 140 euros in import taxes), it finally came! In fact, I&#8217;m happily typing this post using this laptop and I can continue to keep posting things that I never got a chance to (like the trips that I went on during this time). The laptop is an Asus U33JC with the following specs:</p>
<ul>
<li>Intel Core i3-370M Processor (2.4 GHz)</li>
<li>Nvidia G310M Graphics Engine with 1 GB DDR3 Dedicated VRAM and Optimus Technology</li>
<li>4 GB of DDR3 1066MHz DRAM (2 GB x 2 slots)</li>
<li>Intel Wireless 802.11 b/g/n + WiDi</li>
<li>500 GB Hard Drive (5400 RPM)</li>
<li>Windows 7 Home Premium (64 bit) Operating System (which I upgraded to Pro)</li>
<li>13.3-Inch HD (1366&#215;768) LED Display</li>
<li>HDMI Port</li>
<li>USB 3.0 port</li>
<li>Bluetooth</li>
<li>8 cell 5600 mAh battery</li>
</ul>
<p>The one thing it doesn&#8217;t have that I realized just now is that the computer doesn&#8217;t have an optical drive. I didn&#8217;t know that before. I guess I assumed that all computers except for netbooks have them. It&#8217;s not really a big deal though.Since my laptop kind of died on me <a href="http://henrypoon.wordpress.com/2011/05/28/my-laptop-is-kaput/" target="_blank" rel="noopener">earlier</a>, there weren&#8217;t many things I could do to solve the problem. I pretty much only had three options: get my laptop repaired, buy/borrow a monitor for the duration of my stay, or buy a new laptop.</p>
<p>Repairing my laptop was definitely the first thing I tried. I researched on how to fix it, but I couldn&#8217;t even get the screws out to even peek at the insides. Right now, I still think that the problem inside the computer is just a loose connection. Unfortunately, I can&#8217;t confirm that. I could let Dell fix the computer, but my warranty expired a long time ago. I also bought the computer from Canada and would have to go through lots of red tape just to get it repaired by Dell Europe.</p>
<p>The next thing I tried was to find someone who had an extra monitor I could borrow. Since all my friends in Germany are all interns or thesis students, they all had only a laptop and not an extra display. Although, I did manage to borrow one for like a week until I had to return it. I could have bought a new monitor, but then it would have been really been difficult to bring home a 20 something inch screen (if I&#8217;m buying a monitor to keep then I wouldn&#8217;t buy anything smaller). I didn&#8217;t feel like buying a cheap one and just leaving it behind when I leave Germany either.</p>
<p>In the end, I ended up buying a new laptop (with much financial assistance from my parents). I figure my old laptop is getting old anyways (2007), and for the past year and a half it had been failing to keep up with my intense computer usage habits. When I return to Vancouver, I&#8217;ll get this laptop repaired and then my parents could use it (or my brother if he decides that he needs to bring a laptop somewhere).</p>


<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2011/06/20/new-laptop/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1067</post-id>	</item>
		<item>
		<title>My Laptop is Kaputt</title>
		<link>https://blog.henrypoon.com/blog/2011/05/28/my-laptop-is-kaput/</link>
					<comments>https://blog.henrypoon.com/blog/2011/05/28/my-laptop-is-kaput/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Sat, 28 May 2011 18:12:14 +0000</pubDate>
				<category><![CDATA[europe]]></category>
		<category><![CDATA[APT]]></category>
		<category><![CDATA[Backlight]]></category>
		<category><![CDATA[Berlin]]></category>
		<category><![CDATA[Best Buy]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Canada]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Consumer electronics]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Dell]]></category>
		<category><![CDATA[Dell laptops]]></category>
		<category><![CDATA[EAR]]></category>
		<category><![CDATA[Euro]]></category>
		<category><![CDATA[Europe]]></category>
		<category><![CDATA[Final]]></category>
		<category><![CDATA[future]]></category>
		<category><![CDATA[German]]></category>
		<category><![CDATA[Germany]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IME]]></category>
		<category><![CDATA[In Germany]]></category>
		<category><![CDATA[ise]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Laptop]]></category>
		<category><![CDATA[Light]]></category>
		<category><![CDATA[Monday]]></category>
		<category><![CDATA[My Phone]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[Pho]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[Screws]]></category>
		<category><![CDATA[STR]]></category>
		<category><![CDATA[Thou]]></category>
		<category><![CDATA[Time]]></category>
		<category><![CDATA[tuna]]></category>
		<category><![CDATA[Websites]]></category>
		<guid isPermaLink="false">http://henrypoon.mooo.com/blog/my-laptop-is-kaput</guid>

					<description><![CDATA[Day 136 After almost four years of using my Inspiron 1520, its age finally caught up with it and its light literally went out.&#160; The backlight refuses to turn on now.&#160; I came back from Berlin last Monday and found my computer in this state.&#160; I left it off during that time too.&#160; During this [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Day 136</p>



<p class="wp-block-paragraph">After almost four years of using my Inspiron 1520, its age finally caught up with it and its light literally went out.&nbsp; The backlight refuses to turn on now.&nbsp; I came back from Berlin last Monday and found my computer in this state.&nbsp; I left it off during that time too.&nbsp; During this time, I had trouble doing any blogging and uploading any photos.</p>



<p class="wp-block-paragraph">Google told me that the problem lay with either a loose connection, the inverter or the lamp.&nbsp; I tried to check this out myself and open the computer case, but the screws refused to budge.&nbsp; People online somehow got theirs open, but I couldn’t.</p>



<p class="wp-block-paragraph">Unfortunately, my warranty expired so I’d have to pay to get this computer fixed.&nbsp; I looked at my options on the Dell site and the North American Dell Support refused to help me and kept referring me to the European side even though I bought my computer in Canada (I really don’t know what these guys at the call centers are doing).&nbsp; After about three calls to the support line, I finally found someone helpful and she told me that I had to change my laptop registration such that it showed a European location before I could get it fixed.&nbsp; An alternative option would have been to send the computer back to Canada to get it fixed.</p>



<p class="wp-block-paragraph">What I did instead was just buy a new laptop.&nbsp; My laptop is already super old and already can’t really keep up with my tasks anyway, so I suppose it’s time for an upgrade.&nbsp; What surprised me was that laptops in Germany (from their Best Buy/Future Shop equivalents anyway) cost so much more than in North America.&nbsp; In fact, it was cheaper for me to buy my computer in Canada and get my parents to ship it to me rather than buying it locally.&nbsp; I’m sure there are cheaper places, but I don’t exactly know how to look through all these German websites.&nbsp; Another added advantage in buying from Canada is that I’d have a computer with the US Keyboard layout rather than the German one.&nbsp; And in the future when my laptop needs repairs, it’ll be easy.</p>



<p class="wp-block-paragraph">In the meantime, I’m using a 17 inch LCD screen that I borrowed from a friend.&nbsp; This will suffice until my new computer arrives.&nbsp; No more shining a lamp at my computer screen and squinting my eyes to see the screen anymore.&nbsp; I also don’t need to be using my phone to go on the internet at home either.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img data-recalc-dims="1" decoding="async" width="1280" height="960" src="https://i0.wp.com/blog.henrypoon.com/wp-content/uploads/2011/05/IMG_2808.jpg?resize=1280%2C960&#038;ssl=1" alt="" class="wp-image-7383" srcset="https://i0.wp.com/blog.henrypoon.com/wp-content/uploads/2011/05/IMG_2808.jpg?w=1600&amp;ssl=1 1600w, https://i0.wp.com/blog.henrypoon.com/wp-content/uploads/2011/05/IMG_2808.jpg?resize=768%2C576&amp;ssl=1 768w, https://i0.wp.com/blog.henrypoon.com/wp-content/uploads/2011/05/IMG_2808.jpg?resize=1536%2C1152&amp;ssl=1 1536w, https://i0.wp.com/blog.henrypoon.com/wp-content/uploads/2011/05/IMG_2808.jpg?resize=1240%2C930&amp;ssl=1 1240w, https://i0.wp.com/blog.henrypoon.com/wp-content/uploads/2011/05/IMG_2808.jpg?resize=508%2C381&amp;ssl=1 508w" sizes="(max-width: 1280px) 100vw, 1280px" /></figure>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2011/05/28/my-laptop-is-kaput/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1047</post-id>	</item>
		<item>
		<title>Axis and Allies 1940 Battle Calculator/Simulator Updated to v1.0</title>
		<link>https://blog.henrypoon.com/blog/2010/12/29/axis-and-allies-1940-battle-calculatorsimulator-updated-to-v1-0/</link>
					<comments>https://blog.henrypoon.com/blog/2010/12/29/axis-and-allies-1940-battle-calculatorsimulator-updated-to-v1-0/#respond</comments>
		
		<dc:creator><![CDATA[hp]]></dc:creator>
		<pubDate>Thu, 30 Dec 2010 07:27:03 +0000</pubDate>
				<category><![CDATA[computer stuff]]></category>
		<category><![CDATA[9]]></category>
		<category><![CDATA[Chan]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[D]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[Geeknet]]></category>
		<category><![CDATA[It]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Lie]]></category>
		<category><![CDATA[Link]]></category>
		<category><![CDATA[Net]]></category>
		<category><![CDATA[Page]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[SourceForge]]></category>
		<category><![CDATA[Z]]></category>
		<category><![CDATA[Zip]]></category>
		<guid isPermaLink="false">http://henrypoon.mooo.com/blog/axis-and-allies-1940-battle-calculatorsimulator-updated-to-v1-0</guid>

					<description><![CDATA[No big changes really, other than the fact that there is now a button for swapping attacker and defender so that people can see how the odds changed if the roles were reversed. For more information about the program, see the original post about it. Requires Java to be installed.&#160; Link for that here. SourceForge [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">No big changes really, other than the fact that there is now a button for swapping attacker and defender so that people can see how the odds changed if the roles were reversed.</p>



<p class="wp-block-paragraph">For more information about the program, see the <a href="https://henrypoon.wordpress.com/2010/12/24/axis-and-allies-1940-battle-calculator/" target="_blank" rel="noopener noreferrer">original post</a> about it.</p>



<p class="wp-block-paragraph">Requires Java to be installed.&nbsp; Link for that <a href="https://www.java.com/en/download/manual.jsp" target="_blank" rel="noopener noreferrer">here</a>.</p>



<p class="wp-block-paragraph">SourceForge Page: <a href="http://sourceforge.net/projects/aa40battlecalc/" target="_blank" rel="noreferrer noopener">http://sourceforge.net/projects/aa40battlecalc/</a></p>



<p class="wp-block-paragraph">Download: <a href="http://sourceforge.net/projects/aa40battlecalc/files/Battle%20Calculator%20Binary/v1.0/BattleCalculator-v1.0.jar/download" target="_blank" rel="noreferrer noopener">http://sourceforge.net/projects/aa40battlecalc/files/Battle%20Calculator%20Binary/v1.0/BattleCalculator-v1.0.jar/download</a></p>



<p class="wp-block-paragraph">Source Code: <a href="http://sourceforge.net/projects/aa40battlecalc/files/Battle%20Calculator%20Source/v1.0/src-v1.0.zip/download" target="_blank" rel="noreferrer noopener">http://sourceforge.net/projects/aa40battlecalc/files/Battle%20Calculator%20Source/v1.0/src-v1.0.zip/download</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.henrypoon.com/blog/2010/12/29/axis-and-allies-1940-battle-calculatorsimulator-updated-to-v1-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">553</post-id>	</item>
	</channel>
</rss>
