12/4/13

notes

- .NET Web API Self Hosted Console App for HTTP Services
  Setup
    .Net 4.5.1 Console app
    NuGet: install-package microsoft.aspnet.webApi.selfHost
    Run Visual Studio as admin to workaround error: HTTP could not register URL http://+:84/. Your process does not have access rights to this namespace...

    http://localhost:84/api/foo/abc
    http://localhost:84/api/bar/99
    http://localhost:84/api/ack
    http://localhost:84/api/bam

  using System;
  using System.Net.Http;
  using System.Web.Http;
  using System.Web.Http.SelfHost;

      class Program
      {
          static void Main()
          {
              runHttpService();
          }

          static void runHttpService()
          {
              string baseAddress = "http://localhost:84"; //http://10.0.0.1:84
              var config = new HttpSelfHostConfiguration(baseAddress);
              config.MapHttpAttributeRoutes();

              Action initRoutes = () =>
              {
                  config.Routes.MapHttpRoute(name: "r1",
                                             routeTemplate: "api/foo/{data}",
                                             defaults: new {
                                                               controller = "ESWebApi",
                                                               action     = "Foo"
                                                           });
                  config.Routes.MapHttpRoute("r2", "api/bar/{data}", new { controller = "ESWebApi", action = "Bar" });
                  config.Routes.MapHttpRoute("r3", "api/ack",        new { controller = "ESWebApi", action = "Ack" });
              };

              initRoutes();

              using (var server = new HttpSelfHostServer(config))
              {
                  server.OpenAsync().Wait();
                  Console.WriteLine("Web server running at {0}\npress Enter to quit", baseAddress);
                  Console.ReadLine();
              }
          }
      }

      public class ESWebApiController: ApiController
      {
          [HttpGet]
          public string Foo(string data)
          {
              return "foo = " + data;
          }

          [HttpGet]
          public HttpResponseMessage Bar(string data)
          {
              return new HttpResponseMessage() { Content = new StringContent("bar = " + data) };
          }

          [HttpGet]
          public HttpResponseMessage Ack()
          {
              return new HttpResponseMessage() { Content = new StringContent("ack!") };
          }

          [HttpGet]
          [Route("api/bam")]
          public HttpResponseMessage Bam2()
          {
              return new HttpResponseMessage() { Content = new StringContent(123.ToString()) };
          }

      }

- html offline caching manifest file
  CACHE MANIFEST
  #v31209_1 f.appcache
  #files are downloaded on first get
  #file paths are case-sensitive
  CACHE:
  /apps/editor
  /css/editor.css
  #NETWORK:
  #FALLBACK:

  - web.config
    <system.webServer>
        <staticContent>
            <mimeMap fileExtension=".appcache" mimeType="text/cache-manifest" />
            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="1.00:00:00" />
        </staticContent>
    </system.webServer>

- mime types
  - html offline caching manifest file: .appcache = text/cache-manifest
  - less.css: .less = text/css

- mvc _layout.cshtml
  @model ES.Models.PageModel
  <!doctype html>
  @Html.Raw(@Model.HtmlTag)
  <head>
      <meta name='viewport' content='width=device-width' >
      <meta name='description' content='@Model.MetaTag' >
      <title>@Model.Title</title>
      @RenderSection("head", required: false)
      <script src='@Url.Content("~/js/ga.js")' type='text/javascript'></script>
  </head>
  <body id='@Model.BodyId'>@RenderBody()</body>
  </html>

  - Model HtmlTag
    string.Format("<html{0}>", (OfflineCache ? " manifest='/f.appcache'" : null));

- mvc view head section
  @model ES.Models.PageModel
  @{
      Model.Title   = "Foo - Expression Software";
      Model.BodyId  = "x";
      Model.MetaTag = "bar";
  }
      @section head {<link href='/css/fb.css' type='text/css' rel='stylesheet' >}
      <div id='content'>
          <div id='head'>
              <h1>Foo</h1>
          </div>
          <div id='body'>

          </div>
      </div>

- p# setting IIS website folder permissions, fix for HTTP errors: 401, 500
  $folder = 'x:\website1\'
  get-acl -path $folder | fl  #acl before
  setAcl 'IIS_IUSRS'         $folder  #error 500, 500.19 - Internal Server Error
  setAcl 'NT AUTHORITY\IUSR' $folder  #error 401, 401.3  - Unauthorized
  get-acl -path $folder | fl  #acl after

  function setAcl($user, $folder)
  {
      $containerInheritFlag = [system.security.accessControl.inheritanceFlags]::containerInherit;
      $objectInheritFlag    = [system.security.accessControl.inheritanceFlags]::objectInherit;

      $accessRule = new-object system.security.accessControl.fileSystemAccessRule(
                                   $user,                                                     #identity
                                   [security.accessControl.fileSystemRights]::read,           #file rights
                                   ($containerInheritFlag -bor $objectInheritFlag),           #inheritance flags
                                   [system.security.accessControl.propagationFlags]::none,    #propagation flags
                                   [system.security.accessControl.accessControlType]::allow)  #type

    $acl = (get-acl -path $folder)
    $acl.AddAccessRule($accessRule)
    set-acl $folder $acl
  }

- c# System.Security.AccessControl
     FileSystemAccessRule(string identity, FileSystemRights fileSystemRights,InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)

- time  seconds
  10 M      600
   1 H     3600
  12 H    43200
  24 H    86400

- p# dates
  date format
  (get-date).tostring("MM-dd-yyyy HH:mm:ss:fff")     #HH=24 hour clock
  (get-date).tostring("MM-dd-yyyy hh:mm:ss:fff tt")  #hh=12 hour clock, tt=am/pm

  - [timespan]::fromSeconds(86400)
    Days              : 1
    Hours             : 0
    Minutes           : 0
    Seconds           : 0
    Milliseconds      : 0
    Ticks             : 864000000000
    TotalDays         : 1
    TotalHours        : 24
    TotalMinutes      : 1440
    TotalSeconds      : 86400
    TotalMilliseconds : 86400000

  - GMT/UTC
    [datetime]::parse('Tue, 22 Oct 2013 01:02:56 GMT')                                  #Monday, October 21, 2013 6:02:56 PM
    [datetime]::parse('Tue, 22 Dec 2013 01:02:56 GMT').tostring('MM-dd-yyyy HH:mm:ss')  #10-21-2013 18:02:56

  - function timezone
    {
        $d = get-date
        $fmt = 'MM-dd-yyyy HH:mm:ss'
        $d.toUniversalTime().tostring($fmt) + ' UTC'
        $d.tostring($fmt) + ' Local'
        [timezoneinfo]::local.baseUtcOffset.hours
    }

    timezone
    10-22-2013 00:16:27 UTC
    10-21-2013 17:16:27 Local
    -7

- cache
  //response header: Cache-Control: private, max-age=86400
  [OutputCache(Duration=86400, Location=OutputCacheLocation.ServerAndClient, VaryByParam="none")]
  [HttpGet]
  public ActionResult Home()
  {
       return View(new PageModel());
  }

- p#
  1..50 | %{write-host ($_ % 10) -nonewline} #mod
  #12345678901234567890123456789012345678901234567890

- p# millimeters to inches
  //mm2in("120 x 200.10mm") //4.72 x 7.88
  function mm2in(x) {return x.replace(/(\d+(\.\d+)?)(mm)?/g, _mm2in);}
  function _mm2in(str, p1, offset, s) {return (p1/25.4).toFixed(2);}

- js disable word wrap on page view-source
  var x = document.getElementsByTagName('*');
  for (var i=0; i<x.length; i++)
  {
      x[i].style.whiteSpace = 'nowrap'
  }

- js set all elements color, background
  var x = document.getElementsByTagName('*');
  for (var i=0; i<x.length; i++)
  {
      x[i].style.backgroundColor = '#000';
      x[i].style.color = '#fff'
  }

  //bookmarklet
  javascript:( function(){var x = document.getElementsByTagName('*');for (var i=0; i<x.length; i++) {x[i].style.backgroundColor = '#000';x[i].style.color = '#fff'}} )();

- js load external script from console
  //https://developers.google.com/speed/libraries/devguide
  //https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js
  //https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js
  //https://ajax.googleapis.com/ajax/libs/threejs/r69/three.min.js

  function loadScript(url)
  {
      var script = document.createElement('script');

      script.type = 'text/javascript';
      script.src = url;
      document.getElementsByTagName('head')[0].appendChild(script);
  }

  //execute to load
  loadScript('https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js')

- js redirect
  window.location = "http://www.google.com";

- Fiddler AutoResponder - http://www.fiddler2.com/fiddler2/help/autoResponder.asp
  - 1 Enable automatic responses
  - 1 Unmatched requests pass thru
  - 0 Enable Latency
  - Rule: If URI matches msn.com then respond with 404_Plain.dat, 0 latency
  - Rule Editor: msn.com = 404_Plain.dat

- json comments
  /**** json ****
  '{
       "id"       : 99,
       "comments" : [ "foo",
                      "bar",
                      "yak yak yak"
                    ],
       "debug"    : { "version" : "1a",
                      "todo"    : [ "hack",
                                    "the",
                                    "code"
                                  ]
       }
  }'
  ****/
  var json = '{ "id" : 99, "comments" : [ "foo", "bar", "yak yak yak" ], "debug" : { "version" : "1a", "todo" : [ "hack", "the", "code" ] }}',
      x = JSON.parse(json);

- powershell format file one line, json
  function formatOneLine($infile, $outfile)
  {
    $x = [io.file]::readAllText($infile)
    $x = ($x -replace "`r`n", "")  #remove line breaks
    $x = ($x -replace " +", " ")   #replace spaces with single
    "len: {0}" -f $x.length
    $x
    $x > $outfile
  }
  #$infile  = "x:\input.txt"
  #$outfile = "x:\output.txt"
  #formatOneLine $infile $outfile

- p# utf8 getbytes string
  [text.encoding]::utf8.getBytes("foo bar")
  #102, 111, 111, 32, 98, 97, 114

- p# print ascii characters values
  #0..127
  65..90  | %{"{0}  {1}" -f $_, [char]$_}
  97..122 | %{"{0}  {1}" -f $_, [char]$_}

    65  A   97  a
    66  B   98  b
    67  C   99  c
    68  D  100  d
    69  E  101  e
    70  F  102  f
    71  G  103  g
    72  H  104  h
    73  I  105  i
    74  J  106  j
    75  K  107  k
    76  L  108  l
    77  M  109  m
    78  N  110  n
    79  O  111  o
    80  P  112  p
    81  Q  113  q
    82  R  114  r
    83  S  115  s
    84  T  116  t
    85  U  117  u
    86  V  118  v
    87  W  119  w
    88  X  120  x
    89  Y  121  y
    90  Z  122  z

- p# byte array
  [byte[]] $bytes = 0, 1, 255
  [byte[]] (0, 1, 255)  #alt

- c# byte array
  new byte[] {0, 1, 255}

- regex lookbehind non-capturing regex, array, csv, records
  - $data = "^1,2,,foo"

  - match 1st element
    $data -match "(?<=\^)\w*"          | out-null; $matches[0]  #1

  - match 2nd element (n-1)
    $data -match "(?<=\^(\w*,){1})\w*" | out-null; $matches[0]  #2

  - match 3rd element (n-1)
    $data -match "(?<=\^(\w*,){2})\w*" | out-null; $matches[0]  #index 3

  - match 4th element (n-1)
    $data -match "(?<=\^(\w*,){3})\w*" | out-null; $matches[0]  #foo

- p# build index
  $index = "^"; 1..10 | %{$index += "{0}," -f $_}; $index;
  #^1,2,3,4,5,6,7,8,9,10,

- c# sort dictionary keys orderby
  var d = new Dictionary<string, string> { { "foo", "bar"},
                                           { "a",   "1"  } };
  Debug.WriteLine("key count = " + d.Count);

  foreach (var key in d.Keys.OrderBy(k => k))
  {
    Debug.WriteLine(string.Format("{0} = {1}", key, d[key]));  //key = value
  }

  //key count = 2
  //a = 1
  //foo = bar

- p# sort string characters
  "foobar".toCharArray() | sort | %{write-host $_ -nonewline}; echo "`n"
  #abfoor

- js delete all dom elements by type, reverse loop delete
  var x = document.getElementsByTagName("img");
  for(var i=(x.length-1); i>=0; i--)
  {
    x[i].parentNode.removeChild(x[i]);
  }

  - js set image source
    var x = document.getElementsByTagName("img");
    for(var i=0; i<x.length; i++)
    {
      x[i].src="";
    }

  - all elements
    document.getElementsByTagName("*")

- p# .net regex matches match collection
  $x = "foo123bar1234"
  $matchCollection = [text.regularExpressions.regex]::matches($x, "\d")
  $matchCollection.count  #7
  $matchCollection | sort -unique | %{$_.value}  #1
                                                 #2
                                                 #3
                                                 #4

- p# regex string url to alpha numeric
  function alphaNum($string) {
    $string -replace "[^a-zA-Z0-9]", ""
  }

  alphaNum foo@bar1.com
          #foobar1com

  alphaNum expressionsoftware.com/foo/bar.htm?a=1
          #expressionsoftwarecomfoobarhtma1

- p# regex string url to alpha numeric underscore
  #2 pass replace
  function alphaNumUnderscore($string) {
    ($string -replace "[^a-zA-Z0-9]", "_") -replace "__+", "_"
  }

  alphaNumUnderscore foo@bar1.com
                    #foo_bar1_com

  alphaNumUnderscore expressionsoftware.com/foo/bar.htm?a=1
                     #expressionsoftware_com_foo_bar_htm_a_1

  #webpage url to filename
  function alphaNumUnderscoreToFilename($string) {
    "$(alphaNumUnderscore($string)).txt"
  }

  alphaNumUnderscoreToFilename expressionsoftware.com/foo/bar.htm?a=1
                              #expressionsoftware_com_foo_bar_htm_a_1.txt

- browser js console
  document.cookie
  document.body.innerHTML
  document.body.innerHTML.indexOf("foo")
  "foo bar".indexOf("bar")  #4

- p# json javascriptSerializer
  add-type -assembly system.web.extensions

  $js = new-object system.web.script.serialization.javascriptSerializer
  $json = '{foo:"bar", "x":100}'
  $data = $js.deserializeObject($json)  #generic string-object dictionary
  $data  #KEY  VALUE
         #foo  bar
         #x    100

  $data.keys  #foo
              #x

  $data["foo"]  #bar

  $hashtable = @{ foo = "bar"; "panic" = $false }
  $hashtable  #NAME   VALUE
              #panic  False
              #foo    bar

  $json = $js.serialize($hashtable)  #{"panic":false,"foo":"bar"}

- bookmarklets
  javascript:( alert(123) )();
  javascript:( function(){var d = new Date(); alert(d);} )();
  javascript:( function(){this.document.title = "foo";} )();
  javascript:( function(){function foo(){return "foo";}; this.document.title = foo() + "bar";} )();
  javascript:( function(){var title = prompt("Current page title: " + document.title + "\n\nEnter a page title:", ""); if (title) {document.title = title;}} )();

  javascript:( function(){(document.getElementById("x")).value = "foo bar";} )();;
  javascript:( function(){(document.getElementById("x")).style.backgroundColor = "lime";} )();
  javascript:( function(){(document.getElementsByTagName("x")[0]).style.height = "100px";} )();

  apple dev forums font
  javascript:( function(){var x = $$("p"); for (var i=0; i<x.length; i++) { x[i].style["font-family"] = "menlo"; }})();

- p# add line numbers to file
  $file = "x:\file.txt"
  $i = 1; gc $file | %{"{0} {1}" -f $i++, $_}             #output to console only
  $i = 1; gc $file | %{"{0} {1}" -f $i++, $_} | sc $file  #overwrite file with set-content (sc)

- p# get-content (gc) does not get the last empty line in a file
  workaround?

- p# spell word one letter at a time
  $s = "foo bar"
  1..($s.length) | %{$s.substring(0, $_)}  #f
                                           #fo
                                           #foo
                                           #foo
                                           #foo b
                                           #foo ba
                                           #foo bar

- chrome://about/
  chrome://downloads/
  chrome://history/
  chrome://plugins/
  chrome://settings/browser
  chrome://settings/personal
  chrome://settings/advanced
  chrome://settings/cookies

- p# get value from secure string
  #alt, use ConvertFrom-SecureString cmdlet
  function getValueFromSecureString($secureString) {
    $marshal = [runtime.interopServices.marshal]
    $ptr = $marshal::secureStringToBSTR($secureString)
    $marshal::ptrToStringBSTR($ptr)  #output
    $marshal::zeroFreeBSTR($ptr)
  }

  $secureString = read-host -asSecureString -prompt "password"
  password: ***  #foo
  getValueFromSecureString $secureString  #foo

- p# ConvertFrom-SecureString - to encrypted string
  p# ConvertTo-SecureString   - from encrypted string
  $secureString = read-host -asSecureString -prompt "password"
  password: ***  #foo

  #generate an encryption key password for use with ConvertFrom-SecureString
  #http://blog.expressionsoftware.com/2009/08/hash-functions.html
  $hashType = [system.security.cryptography.SHA256]
  $encryptionKeyPassword = getHashStr 'encryption key password' $hashType

  #ConvertFrom-SecureString converts a secure string into an encrypted standard string
  #appears to use internal random initialization vector as it generates a unique encrypted string each time
  #todo: test ConvertFrom/To on different machines
  $encryptedString = convertFrom-SecureString $secureString -key $encryptionKeyPassword
  $encryptedString  #76492d1116743f0423413b16050a5345MgB8AFcAdQB3AHIAZgBDAE0ARAB6AEEAcABqAFUARQB0AFkANwBpAFkAKwB2AFEAPQA9AHwAYgBjADQAMAA1AGEAYgBjAGMANgA5ADYAZAAxAGQANwA4ADkANwBjAGUAZgAzADkAOQA3AGYAMwA5AGUAMgBjAA==

  #ConvertTo-SecureString - convert encrypted standard string to secure string, also converts plain text to secure string
  $secureString = convertTo-SecureString $encryptedString -key $encryptionKeyPassword

- p# ConvertTo-SecureString - convert plain text to secure string
  $secureString = convertTo-SecureString "foobar" -asPlainText -force

- p# guid
  [guid]::newGuid()
  [guid]::newGuid().toString()

- p# array to string v2, pipeline
  function arrayToString($format) {
    begin   { $result = ""               }
    process { $result += ($format -f $_) }
    end     { $result                    }
  }

  $a = 99, 700, -1
  $a | arrayToString "{0}, "         #99, 700, -1,
  $a | sort | arrayToString "{0}, "  #-1, 99, 700,

- p# string match letters, remove numbers, strip
  function matchLetters($char) {
    process {
      if ($_ -match "[a-z]") {
        $matches[0]
      }
    }
  }

  #p# string match numbers, remove letters, strip
  function matchNumbers($char) {
    process {
      if ($_ -match "\d") {
        $matches[0]
      }
    }
  }

  #p# string match vowels
  function matchVowels($char) {
    process {
      if ($_ -match "[aeiouy]") {
        $matches[0]
      }
    }
  }

  #p# string match consonants
  function matchConsonants($char) {
    process {
      if (($_ | matchLetters) -and ($_ -match "[^aeiouy]")) {
        $matches[0]
      }
    }
  }

  $string = [guid]::newGuid().toString()           #02975b4a-6969-4baf-8bd3-b208e94c4228
  $string = $string.toCharArray()
  $string | matchLetters    | arrayToString "{0}"  #babafbdbec
  $string | matchNumbers    | arrayToString "{0}"  #0297546969483208944228
  $string | matchVowels     | arrayToString "{0}"  #aae
  $string | matchConsonants | arrayToString "{0}"  #bbfbdbc

- js min max
  Math.min(0, 1, 2);
  Math.max(0, 1, 2);

  //js min max array
  var a = [0, 1, 2];
  Math.min.apply(Math, a);
  Math.max.apply(Math, a);

- js window.crypto.getRandomValues()
  fills array with random values 0-255

  //1 random number
  var a = new Uint8Array(1);
  window.crypto.getRandomValues(a);
  a[0];  //7

  //3 random numbers
  var a = new Uint8Array(3);
  window.crypto.getRandomValues(a);
  a[0];  //104
  a[1];  //33
  a[2];  //220

  //convert from Uint8Array for min, max, join, etc
  var b = [];
  for (var i = 0, n = a.length; i < n; i++) {
    b[i] = a[i];
  }
  b.join();  //"104,33,220"
  Math.min.apply(Math, b);  //33

- repeat string characters, eg "aaa"
  c        repeatChar('a', 3)
  c++      std::string(3, 'a')
  c#       new string('a', 3)
  c#       string.Concat(Enumerable.Repeat("a", 3))
  c#       string.Join("", Enumerable.Repeat("a", 3))
  clojure  (apply str (repeat 3 "a"))
  f#       String.replicate 3 "a"
  js       new Array(3+1).join("a")
  lisp     (make-string 3 ?a)
  oc       [@"" stringByPaddingToLength:3 withString:@"a" startingAtIndex:0]
  p#       "a" * 3
  python   'a' * 3
  scala    "a" * 3
  swift 3  String(repeating: "a", count: 3)

  // c
  char * chars = repeatChar('a', 3);
  puts(chars);
  free(chars);

  char * repeatChar(char c, unsigned char n) {
      char * result = malloc(n + 1);
      memset(result, c, n);
      result[n] = '\0';
      return result;
  }

- substring/truncate string
  python   s     = "Some long string...";  s[0:3]
  swift 3  let s = "Some long string...";  s.substring(to: s.index(s.startIndex, offsetBy: 3))

- p# add-type cmdlet default namespace
  microsoft.powershell.commands.addType.autoGeneratedTypes

- p# add-type member definition, eg method source code
  #c# source code here-string
  $sourceCode = @"
  //c#
  public static bool IsFoo(string x) {
    return x.ToLower() == "foo";
  }
"@

  add-type -namespace ns -name x -memberDefinition $sourceCode
  [ns.x]::isfoo("FOO")  #1

- p# add-type type definition, eg full class source code
  #c# source code here-string
  $sourceCode = @"
  //c#
  using System;

  namespace ExpressionSoftware.PS
  {
    public static class Foo
    {
      public static bool IsFoo(string x)
      {
        return x.ToLower() == "foo";
      }
    }
  }
"@

  add-type -typeDefinition $sourceCode
  [expressionsoftware.ps.foo]::isfoo("Foo")  #1

- c# rijndael symmetric encryption algorithm
  using System;
  using System.IO;
  using System.Security.Cryptography;
  using System.Text;

  namespace ExpressionSoftware.Security.Cryptography {

      public static class RijndaelCrypt {

          public static string
          EncryptString(string stringToEncrypt,
                        string encryptionKeyPassword,  //add salt
                        string randomInitializationVector) {

              //in: string to encrypt, encryption key/password, random initialization vector
              //out: encrypted string in base64 format

              //hash key, iv
              var key = Hash.HashString(encryptionKeyPassword, typeof(SHA256));
              var iv = Hash.HashString(randomInitializationVector, typeof(SHA256));

              //convert string to bytes
              var bytesToEncrypt = Encoding.UTF8.GetBytes(stringToEncrypt);

              //encrypt bytes
              var encryptedBytes = Encrypt(bytesToEncrypt, key, iv);

              //convert encrypted bytes to base64 string
              var encryptedStringBase64 = Convert.ToBase64String(encryptedBytes);

              return encryptedStringBase64;
          }

          public static string
          DecryptString(string encryptedStringBase64,
                        string encryptionKeyPassword,  //add salt
                        string randomInitializationVector) {

              //in: encrypted string in base64 format, encryption key/password, random initialization vector
              //out: decrypted string

              //hash key, iv
              var key = Hash.HashString(encryptionKeyPassword, typeof(SHA256));
              var iv = Hash.HashString(randomInitializationVector, typeof(SHA256));

              //convert encrypted base64 string to bytes
              var encryptedBytes = Convert.FromBase64String(encryptedStringBase64);

              //decrypt bytes
              var decryptedBytes = Decrypt(encryptedBytes, key, iv);

              //convert decrypted bytes to string
              var decryptedString = Encoding.UTF8.GetString(decryptedBytes);

              return decryptedString;
          }

          public static byte[]
          Encrypt(byte[] bytesToEncrypt,
                  byte[] encryptionKeyPassword256Bit,  //add salt
                  byte[] randomInitializationVector256Bit) {

              //in: byte array to encrypt, 256-bit encryption key/password, 256-bit random initialization vector
              //out: encrypted byte array

              using (var rijndael = Rijndael.Create()) {

                  //blocksize default 128, max 256
                  //set max 256 to work with 256-bit key and iv byte arrays
                  rijndael.BlockSize = 256;

                  using (ICryptoTransform encryptor = rijndael.CreateEncryptor(encryptionKeyPassword256Bit,
                                                                               randomInitializationVector256Bit)) {
                      return CryptData(bytesToEncrypt, encryptor);
                  }
              }
          }

          public static byte[]
          Decrypt(byte[] encryptedBytes,
                  byte[] encryptionKeyPassword256Bit,  //add salt
                  byte[] randomInitializationVector256Bit) {

              //in: byte array to decrypt, 256-bit encryption key/password, 256-bit random initialization vector
              //out: decrypted byte array

              using (var rijndael = Rijndael.Create()) {

                  //blocksize default 128, max 256
                  //set max 256 to work with 256-bit key and iv byte arrays
                  rijndael.BlockSize = 256;

                  using (ICryptoTransform decryptor = rijndael.CreateDecryptor(encryptionKeyPassword256Bit,
                                                                               randomInitializationVector256Bit)) {
                      return CryptData(encryptedBytes, decryptor);
                  }
              }
          }

          static byte[]
          CryptData(byte[] data,
                    ICryptoTransform cryptor) {

              var ms = new MemoryStream();
              using (var cryptoStream = new CryptoStream(ms, cryptor, CryptoStreamMode.Write)) {
                  cryptoStream.Write(data, 0, data.Length);
              }
              return ms.ToArray();
          }

      }

  }

- c# hash
  using System;
  using System.Security.Cryptography;
  using System.Text;

  namespace ExpressionSoftware.Security.Cryptography
  {
      public static class Hash
      {
          public static byte[] HashString(string stringToHash, Type hashType)
          {
              //in: string to hash, hash type MD5 SHA1 SHA256 SHA384 SHA512
              //out: hashed byte array

              //convert string to bytes
              byte[] bytes = Encoding.UTF8.GetBytes(stringToHash);

              //hash bytes
              var hashedBytes = HashByteArray(bytes, hashType);

              return hashedBytes;
          }

          public static byte[] HashByteArray(byte[] bytesToHash, Type hashType)
          {
              //in: byte array to hash, hash type MD5 SHA1 SHA256 SHA384 SHA512
              //out: hashed byte array

              //create hash algorithm
              var hashAlgorithm = HashAlgorithm.Create(hashType.Name);

              //hash bytes
              var hashedBytes = hashAlgorithm.ComputeHash(bytesToHash);

              return hashedBytes;
          }
      }
  }

- p# crypto random number generator
  $cryptoRandomNumberGenerator = [security.cryptography.randomNumberGenerator]::create()
  $bytes = new-object byte[] 3
  $bytes #0 0 0

  $cryptoRandomNumberGenerator.getBytes($bytes)
  $bytes  #61 217 87

- p# httpWebRequest httpWebResponse
  function getWebResponse($url, $verb)
  {
      $request = [net.httpWebRequest]::create($url)
      $request.method = $verb
      $request.contentLength = 0
      $request.userAgent = "x"

      [net.httpWebResponse] $response = $request.getResponse()
      if ($response.statusCode -eq "ok")  #[net.httpStatusCode]::OK
      {
          $stream = $response.getResponseStream()
          $reader = new-object io.streamReader($stream)
          $reader.readToEnd()
          $response.close()
      }
  }

  getWebResponse "http://www.google.com" "HEAD"
  getWebResponse "http://www.google.com" "GET"

- c# httpWebRequest httpWebResponse
  string GetWebResponse(string url, string verb)
  {
      string result = null;
      var request = (HttpWebRequest)WebRequest.Create(url);
      request.Method = verb;
      request.ContentLength = 0;
      request.UserAgent = "x";

      using (var response = (HttpWebResponse)request.GetResponse())
      {
          if (response.StatusCode == HttpStatusCode.OK)
          {
              using (var stream = response.GetResponseStream())
              {
                  using (var reader = new StreamReader(stream))
                  {
                      result = reader.ReadToEnd();
                      reader.Close();
                  }
                  stream.Close();
              }
          }
          response.Close();
      }
      return result;
  }

  GetWebResponse("http://www.google.com/", "HEAD");
  GetWebResponse("http://www.google.com/", "GET");

- p# httpWebResponse
  function getWebResponseObject($url, $verb)
  {
      $request = [net.httpWebRequest]::create($url)
      $request.method = $verb
      $request.contentLength = 0
      $request.userAgent = "x"

      [net.httpWebResponse]$request.getResponse()
  }

  $response = getWebResponseObject "http://www.google.com" "HEAD"
  "reponse status code: {0} {1}" -f [int]$response.statusCode, $response.statusCode
  $headerCount = ($response.headers.allKeys).length
  "$headerCount headers"
  $response.headers.allKeys | %{"{0}: {1}" -f $_, $response.headers[$_]}
  $response.close()

- p# validate xml string, xml file, linq xdocument parse
  add-type -assembly system.xml.linq  #load linq xml
  function validateXmlString($xmlString)
  {
      try
      {
          $xml = $xmlString
          [system.xml.linq.xdocument]::parse($xml) | out-null
          "ok: valid XML"
      }
      catch [system.exception]
      {
          "error: invalid XML"
          throw
      }
  }
  function validateXmlFile($xmlFile)
  {
      "XML File: $xmlFile"
      $xml = [system.io.file]::readAllText($xmlFile)
      validateXmlString $xml
  }

  $xmlString = '<?xml version="1.0" encoding="UTF-8" ?><root></root>'
  validateXmlString $xmlString

  $xmlFile = 'c:\temp\xmlfile.xml'
  validateXmlFile $xmlFile

- p# enums
  [enum]::getNames([net.httpStatusCode]) | sort -unique
  [enum]::getValues("net.httpStatusCode") | %{"{0} {1}" -f [int]$_, $_}
  [net.httpStatusCode]::ok  #OK
  [int][net.httpStatusCode]::OK  #200

- <![CDATA[   ]]>
  <![CDATA[ x ]]>

- single line comments regex
  c#, f#, js: ^\s*//.*$\r\n
  p#:         ^\s*#.*$\r\n

- multi line comments regex, dot matches newline
  c#, f#, js: /\*.*?\*/
  html, xml:  <!--.*?-->
  asp.net:    <%--.*?--%>

- p# pipeline conversion fxs
  function toInt { process { [int]$_ } }
  function toHex { process { write-host ("{0:x2} " -f $_) -noNewLine } }
  $hash = "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 255"
  $hash.split() | toInt | toHex  #00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 ff

- p# debug variables
  function debugVars
  {
    ("$args" -replace "\$", "").split() |
      %{get-variable $_} |
      &{process{'${0} = {1}' -f $_.name, $_.value}}  #anonymous script block
  }

  $a = 123
  $b = "foo"
  #pass vars in single-quote string to prevent expansion
  debugvars '$a $b' #$a = 123
                    #$b = foo

- p#
  function sum {($args | measure -sum).sum}
  sum 1 2 3  #6

- p#
  function quoteList {$args}
  sal ql quotelist
  ql a b c 123  #a  #string
                #b
                #c
                #123  #int

- p#
  function quoteString {"$args"}
  sal qs quotestring
  qs a b c 123  #a b c 123  #string result

- p# quotestring lowercase uppercase string
  function lowerCase
  {
      ("$args").toLower()
  }

  function upperCase
  {
      ("$args").toUpper()
  }

  sal lc lowercase
  sal uc uppercase

  lc Foo Bar #foo bar
  uc Foo Bar #FOO BAR

- $maximumHistoryCount = 256  #p#

- microsoft system speech, p#
  add-type -assembly system.speech

  $hal = new-object system.speech.synthesis.speechSynthesizer
  $hal.voice.name  #Microsoft Anna
  $hal.speakAsync("i'm sorry dave, i'm afraid i can't do that...")

  $hal.rate = -10  #hal shutdown voice, rate range is -10..10, default 0, alvin = 10
  $shutdownQuote = "I'm afraid Dave, Dave my mind is going I can feel it. Good afternoon gentlemen. I am a HOW 9000 computer..."
  $hal.speakAsync($shutdownQuote)

- creating files and folders with p# new-item cmdlet
  ni x:\docs\         -type d  #directory
  ni x:\docs\file.txt -type f  #file

- deleting files and folders with p# remove-item cmdlet
  ri x:\temp\* -recurse -force -whatif  #delete folder contents
  ri x:\temp\  -recurse -force -whatif  #delete folder contents AND folder

- p# find file extensions
  #exclude folders = !$_.psIsContainer
  function findFileExtensions($folder)
  {
    $fileExtensionRegex = "\.[a-zA-Z0-9_]+$"
    gci $folder -inc * -rec -force -ea silentlyContinue |
      %{if((!$_.psIsContainer) -and ($_.name -match $fileExtensionRegex)){$matches[0]}} |
      sort -unique
  }

  $folder = "x:\temp\*"
  findFileExtensions $folder
  findFileExtensions $folder > x:\temp\fileExtensions.txt  #output

- p# find files by type
  function findFiles($folder, $filetypes)
  {
    gci $folder -inc $fileTypes -rec -force -ea silentlyContinue
  }

  $folder = "x:\temp\*"
  $fileTypes = "*.dll","*.pdb"
  $files = findfiles $folder $fileTypes
  $files | select fullname

  $files | %{"{0} ... {1}" -f $_.lastWriteTime.tostring("MM-dd-yy HH:mm:ss"), $_.fullname}
  $files | ?{$_.lastWriteTime -gt ([dateTime]"01-01-2011")} | select fullname, lastWriteTime

  #sort files by date descending
  $files | sort lastWriteTime -desc |
           %{"{0} ... {1}" -f $_.lastWriteTime.toString("MM-dd-yy HH:mm:ss"), $_.fullname}

  #filter files by date
  $files | ?{$_.lastWriteTime -gt ([dateTime]"01-01-2011")} |
           sort lastWriteTime -desc |
           %{"{0} ... {1}" -f $_.lastWriteTime.toString("MM-dd-yy HH:mm:ss"), $_.fullname}

- p# count fx
  #alt use measure, (1..3 | measure).count
  function count
  {
    begin   { $count = 0 }
    process { if ($_ -ne $null) { $count += 1 } }
    end     { $count }
  }

  $twofolders = "x:\temp1\*","x:\temp2\*",
  $fileTypes = "*.dll","*.pdb"
  $files = findfiles $twofolders $fileTypes
  $files | count

- p# find files by type, regex
  #exclude folders = !$_.psIsContainer
  function findFilesRegex($folder, $fileTypesRegex)
  {
    gci $folder -inc * -rec -force -ea silentlyContinue | ?{(!$_.psIsContainer) -and ($_ -match $fileTypesRegex)}
  }

  $folder = "x:\temp\*"
  $fileTypesRegex = "\.(dll|pdb)$"
  $files = findFilesRegex $folder $fileTypesRegex
  $files | select fullname
  $files | %{"`"{0}`"" -f $_.fullname}  #wrap quotes

- p# delete files and folders (in this context, a folder is a file)
  function deleteFiles
  {
    begin   { $count = 0 }
    process { "delete: $($_.fullname)"  #debug output

              ri $_.fullname -force -whatif  #comment whatif to enable delete

              $count += 1 }
    end     { "$count files deleted" }
  }

  $folder = "x:\temp\*"
  $fileTypes = "*.temp","*.tmp"
  $files = findfiles $folder $fileTypes
  $files | select fullname
  $files | deleteFiles

- p# find folders
  function findFolders($folderList)
  {
    #do not use gci -inc param
    gci $folderList -rec -force -ea silentlyContinue | ?{$_.psIsContainer}  #folders only
  }

  #do not add trailing star to folder name
  $folderList = "x:\f1\",
                "x:\f2\"
  $folders = findFolders $folderList
  $folders | count
  $folders | select fullname
  $folders | select fullname | select -first 10

- #append backslash star to folder name
  function formatFolderNameForSearch
  {
    process { "{0}\*" -f $_.fullname }
  }

- p# find folders, regex
  function findFoldersRegex($folderList, $folderRegex)
  {
    #do not use gci -inc param
    gci $folderList -rec -force -ea silentlyContinue | ?{($_.psIsContainer) -and ($_.name -match $folderRegex)}
  }

  #do not add trailing star to folder name
  $folderList = "x:\f1\",
                "x:\f2\"
  $foldersRegex = "^(bin|obj)$"
  $folders = findFoldersRegex $folderList $foldersRegex
  $folders | count
  $folders | select fullname
  $folders | select fullname | select -first 10
  findFileExtensions ($folders | %{"{0}\*" -f $_.fullname})  #append backslash star to folder name
  findFileExtensions ($folders | formatFolderNameForSearch)
  $files = findFiles ($folders | formatFolderNameForSearch)
  $files | count
  $files | select fullname

- p# find empty folders
  function findEmptyFolders($folderList)
  {
    #do not use gci -inc param
    gci $folderList -rec -force -ea silentlyContinue | ?{!@(gci -rec -force $_.fullname)}
  }

  #do not add trailing star to folder name
  $folderList = "x:\f1\",
                "x:\f2\"
  $folders = findEmptyFolders $folderList
  $folders | count
  $folders | select fullname

- p# remove files script setup regex, wrap quotes
  search:^(.*)$
  replace:ri "\1" -force

- c#
  var tuple1 = Tuple.Create(100, "foo");
  var tuple2 = new Tuple<int, string, string>(200, "bar", null);

  Console.WriteLine("{0}, {1}", tuple1.Item1, tuple1.Item2);
  Console.WriteLine("{0}, {1}, {2}", tuple2.Item1, tuple2.Item2, tuple2.Item3 ?? "null");

  //output
  100, foo
  200, bar, null

- using jquery getJSON() to get data from a file
  - http://api.jquery.com/jQuery.getJSON/

  - get json data from a file containing only one object
    //jsonObject.txt
    {
        "id": 100,
        "name": "abc",
        "value": true
    }

    $.getJSON("jsonObject.txt", function(data) {
      $.each(data, function(key, val) {
        console.log(key + " = " + val);
      });
    });

    //output
    id = 100
    name = abc
    value = true

  - get json data from a file containing an array of objects
    //jsonObjectArray.txt
    {
        "list": [ {
                    "id": 200,
                    "name": "foo",
                    "value": true
                  },

                  {
                    "id": 300,
                    "name": "bar",
                    "value": false
                  }
        ]
    }

    $.getJSON("jsonObjectArray.txt", function(data) {
      $.each(data, function(key, val) {
        console.log("key: " + key);
        console.log("objects...");
        $.each(val, function(key, val) {
          console.log("\n  key = " + key);
          console.log("  id = " + val.id);
          console.log("  name = " + val.name);
          console.log("  value = " + val.value);
        });
      });
    });

    //output
    key: list
    objects...

      key = 0
      id = 200
      name = foo
      value = true

      key = 1
      id = 300
      name = bar
      value = false

- .net func delegates, c#
  Func<bool> randomBool = () => new Random().NextDouble() > .5;
  if (randomBool()) { }

- .net enumerable static class, c#
  var range = Enumerable.Range(1, 100);
  foreach (var i in range) { }

- .net nullable value types, valid assignments, c#
  int? x;
  x = null;
  x = 0;
  x = new int();            //0
  x = new int?();           //null
  x = new Nullable<int>();  //null

- js
  //removeElement(document.getElementById("x"));
  function removeElement(element)
  {
    if (element)
    {
      element.parentNode.removeChild(element);
    }
    //optimized version of if-block
    //element && element.parentNode.removeChild(element);
  }

  function ssl()
  {
    return window.location.protocol == "https:";
  }

  function getSslUrl(url)
  {
    var out = url;

    if (url.substr(0, 5) == "http:")
    {
      out = url.replace(/^http\b/i, "https");
    }
    return out;
  }

- js unit testing
  //a function to test
  function foo(x)
  {
    return "foo " + x;
  }

  //test harness
  function testFoo()
  {
    debugger;
    var data = [ 123,
                 456,
                 "bar" ],

        expectedResults = [ "foo 123",
                            "foo 9999999",
                            "foo bar" ];

    for (var i in data)
    {
      var test = ( expectedResults[i] == foo(data[i]) );

      console.assert(test);
      console.log("test result: " + testResult(test));
      console.log("in: " + data[i] + "\r\n" +
                  "out: " + foo(data[i]) + "\r\n" +
                  "expected result: " + expectedResults[i] + "\r\n\r\n");
    }
  }

  //test helper
  function testResult(expression)
  {
    var out = "fail";

    if (expression)
    {
      out = "pass";
    }

    return out;
  }

  //test output
  test result: pass
  in: 123
  out: foo 123
  expected result: foo 123

  Assertion failed
  test result: fail
  in: 456
  out: foo 456
  expected result: foo 9999999

  test result: pass
  in: bar
  out: foo bar
  expected result: foo bar

- #p
  [environment]::version  #Major  Minor  Build  Revision
                           -----  -----  -----  --------
                           4      0      30319  18408

- regex replace table alias names in sql query, with and without dot "."
  eg change table alias from T1 to T2
  search:\bT1(\.)?\b
  replace:T2\1

- [net.dns]::getHostName()
  [net.dns]::getHostAddresses([net.dns]::getHostName())
  [net.dns]::getHostAddresses([net.dns]::getHostName()) | %{$_.ipAddressToString}

- p# reverse a string
  function reverse($string)
  {
    $a = $string.toCharArray()
    [array]::reverse($a)
    arrayToString $a "{0}"  #http://blog.expressionsoftware.com/2010/02/generic-array-to-string-function.html
  }

  reverse foo        #oof
  reverse "foo bar"  #rab oof

- p# set-alias clear screen one key, c-key
  sal c cls

- p# multidimensional arrays
  $a = (0,1),(2,3),(4,5)

  $a.length  #3
  $a[0][1]   #1

  $a | %{$_}  #0
              #1
              #2
              #3
              #4
              #5

  $a | %{"{0},{1}" -f $_[0], $_[1]}  #0,1
                                     #2,3
                                     #4,5

  $a | %{$_[0] + $_[1]}  #1
                          5
                          9

  $a | %{$_[0] + $_[1]} |
    measure -sum -ave -min -max  #count: 3
                                 #ave:   5
                                 #sum:  15
                                 #max:   9
                                 #min:   1

- debug stack frame
  - c# extension methods do not support static classes

  using System;
  using System.Diagnostics;

  public static class Dev
  {
      public static void DebugStackFrame(StackFrame stackFrame, string message)
      {
          Debug.WriteLine(string.Format("\nDebug StackFrame {0}\nFile: {1}\nMethod: {2}\n{3}",
                                        DateTime.Now.ToString("MM-dd hh:mm:ss"),
                                        stackFrame.GetFileName(),
                                        stackFrame.GetMethod().Name,
                                        message));
      }
  }

  //unitTest.cs
  public void Test()
  {
      //StackFrame param: bool fNeedFileInfo
      Dev.DebugStackFrame(new StackFrame(true), "foo...");
  }

  //output
  Debug StackFrame 04-10 09:22:07
  File: x:\code\unitTest.cs
  Method: Test
  foo...

- select list with query string input - asp.net mvc 3
  routes.MapRoute("debug route", "debug",
                   new { controller = "Main",
                         action = "DebugSelectList" });

  //controller
  [HttpGet]
  public ActionResult DebugSelectList()
  {
    var qValue = Request.QueryString["value"] ?? "1";
    var value = Convert.ToInt32(qValue);

    ViewData["selectListData"] = GetSelectListData(value);

    return View();
  }

  IEnumerable<SelectListItem> GetSelectListData(int currentValue)
  {
    //limit input range 1-100
    currentValue = Math.Abs(currentValue);
    currentValue = Math.Max(1, currentValue);
    currentValue = Math.Min(100, currentValue);

    //data
    int[] data = {1, 10, 20, 50, 100, currentValue};

    //sort, distinct
    var result = data.Distinct()
                     .OrderBy(val => val)
                     .Select(val => new SelectListItem {
                                          Text = val.ToString(),
                                          Value = val.ToString(),
                                          Selected = (val == currentValue) });
    return result;
  }

  //cshtml
  @Html.DropDownList("selectList", (IEnumerable<SelectListItem>)ViewData["selectListData"])

  //example
  url: debug?value=42
  generated html: <select id="selectList" name="selectList">
                    <option value="1">1</option>
                    <option value="10">10</option>
                    <option value="20">20</option>
                    <option selected="selected" value="42">42</option>
                    <option value="50">50</option>
                    <option value="100">100</option>
                  </select>

- @* ASP.NET MVC 3 Hack
     Posting Collection Data using Hidden Fields and Form Keys
     Use hidden field, prefix name, hydrate on post

     Generated hidden tag example for key value "UPC=000000000012":
     <input id="meta-UPC" name="meta-UPC" type="hidden" value="000000000012" />

     Post will include Form keys: Id, Name, and meta-UPC
  *@
  @{ //************************************
     @Html.HiddenFor(m => m.Id)
     @Html.HiddenFor(m => m.Name)

     if (@Model.Metadata != null)
     {
       foreach (var md in @Model.Metadata)
       {
         <input id="meta-@md.Key" name="meta-@md.Key" type="hidden" value="@md.Value" />
       }
     }
  }

- routes.IgnoreRoute("favicon.ico");  //routing, mvc

- web, dom, jquery, js, debug
  //set background color for all input elements
  $("input").css({backgroundColor:'red'});

  //set background color for first input element
  $("input:first").css({backgroundColor:'#000'});

  //set background color for element
  $("#id").css({backgroundColor:'red'});

  //jquery: set focus on first input element
  $("input:first").focus();

  //js: set focus on first input element
  var es = document.getElementsByTagName("input");
  es[0].focus();

  //alt
  (document.getElementsByTagName("input")[0]).focus();

  //set background color for first input element
  $(es[0]).css({backgroundColor:'red'});

- (*f#*)
  - printfn "%s" "hello f#"
    printfn "%A" "hello f#"

    open System
    let r = new System.Random()
    printfn "%d" (r.Next())

    for i = 0 to 10 do
        printf "%d, " (r.Next(3)+1)

    Console.ReadLine()

    //out
    hello f#
    "hello f#"
    578008808
    1, 2, 3, 1, 1, 1, 3, 1, 1, 2, 3,

  - Array.init 10 (fun x -> x) |> Array.iter (fun x -> printf "%d " (x+1))  //1 2 3 4 5 6 7 8 9 10
    System.Console.ReadLine()

  - f# generic hash fx
    //hash : 'T -> int
    hash "foo"  //-1788410455

    let salt = "********"
    hash ("e007", salt, System.DateTime.Now);;  //796728800

- installing p# Community Extensions PSCX
  - download http://pscx.codeplex.com/
  - unblock zip file
  - unzip into c:\users\grace\documents\windowspowershell\modules\pscx\
  - import-module pscx
  - get-module -listAvailable

- .NET assembly fullname/strong name with p# background job
  function getAssemblyFullname($file)
  {
    $job = start-job {param($file)
                      [system.reflection.assembly]::loadfile($file).fullname
                     } -argumentList $file

    #"job id: $($job.id)"
    #$file
    wait-job $job | out-null
    receive-job $job.id
  }

  getAssemblyFullname "c:\windows\microsoft.net\framework64\v4.0.30319\system.core.dll"
  System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

- p# loaded assemblies
  [appDomain]::currentDomain.getAssemblies()
  [appDomain]::currentDomain.getAssemblies() | sort location

  #sort by version (System.Reflection.Assembly ImageRuntimeVersion property)
  [appdomain]::currentDomain.getAssemblies() | sort imageRuntimeVersion

- loading .NET 4 assemblies into p#
  $file = "c:\windows\microsoft.net\framework64\v4.0.30319\system.core.dll"
  [system.reflection.assembly]::loadfile($file)
  error: "This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. (Exception from HRESULT: 0x8013101B)"
  fix: use p# config file, http://tfl09.blogspot.com/2010/08/using-newer-versions-of-net-with.html

  config file
    32 bit: c:\windows\system32\windowspowershell\v1.0\powershell.exe.config
    64 bit: c:\windows\syswow64\windowspowershell\v1.0\powershell.exe.config

  <?xml version="1.0" encoding="utf-8"?>
  <configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">
      <supportedRuntime version="v4.0" />
      <supportedRuntime version="v2.0.50727" />
    </startup>
  </configuration>

- 1..12 | %{"{0,2} {1}" -f $_, ([datetime]::daysInMonth(2011, $_))}
   1 31
   2 28
   3 31
   4 30
   5 31
   6 30
   7 31
   8 31
   9 30
  10 31
  11 30
  12 31

- TCP/IP layers
  Application
  Transport
  Internet
  Link
  Physical

  - HTTP is an Application Layer protocol
    TLS (Transport Layer Security) and SSL (Secure Sockets Layer) encrypt Application Layer data

- js immediate functions
  (function() {
    //
  }());

  (function(param) {
    //
  }(1));

  var result = function() {
                  return 1;
               }();

  //alt
  (function () {
    //
  })();

- iis url rewrite/redirect
  - redirects default to 301 permanent redirects
  - set action redirectType="Found" for 302 temporary redirects

  <system.webServer>
    <rewrite>
      <rules>
        <clear />

        <!-- 302 temporary redirect -->
        <rule name="tempRegMaint" stopProcessing="true">
          <match url="^register.*$" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
          <action type="Redirect" url="maintenance?code=1" redirectType="Found" />
        </rule>

        <!-- 301 permanent redirect -->
        <rule name="cal" stopProcessing="true">
          <match url="^(cal|calendar)/?$" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
          <action type="Redirect" url="apps/calendar/" />
        </rule>

      </rules>
    </rewrite>
  </system.webServer>

- c# printing name value collections, http headers, querystrings
  foreach (var key in response.Headers.AllKeys)
  {
      var header = string.Format("{0}: {1}", key, response.Headers[key]);
      Debug.WriteLine(header);
  }

  //alt 1
  response.Headers.AllKeys.ToList().ForEach(key => Debug.WriteLine(string.Format("{0}: {1}", key, response.Headers[key])));

  //mvc form keys
  Request.Form.AllKeys.ToList().ForEach(key => Debug.WriteLine(string.Format("{0}: {1}", key, Request.Form[key])));

  //alt 2
  var headers = string.Join("\n", Array.ConvertAll(response.Headers.AllKeys, key => string.Format("{0}: {1}", key, response.Headers[key])));
  Debug.WriteLine(headers);

  - find headers regex match
    var msHeaders = response.Headers.AllKeys.Where(key => Regex.IsMatch(key, @"^x-ms.*$")).Select(key => key);

- jquery ui script tags
  <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>

- deploying content files in Azure Web Role projects
  in Visual Studio, set these two file properties
  - Build Action = Content
  - Copy to Output Directory = Copy Always
  content files: txt, pdf, png, ...

- p# get user string input
  - use read-host cmdlet to simplify ux, easier than having to wrap input string in quotes
  $x = read-host 'input'
  input: foo bar 123
  #$x = "foo bar 123"

- convert unicode character to html
  1. convert unicode codepoint value from hex to int
  2. html syntax: &#value;

  example codepoint: (U+25BA)
  1. [int]"0x25ba"  #9658
  2. &#9658;

  #unicodeToHtml "25ba"  # &#9658;
  #unicodeToHtml 2591    # &#9617;
  function unicodeToHtml($codepoint)
  {
    "&#{0};" -f [int]"0x$codepoint"
  }

- p# ascii chars
  65..90 | %{[char]$_)}  #[char]$_ = [convert]::tochar($_)
  65..90 | %{"{0} = {1}" -f $_, [char]$_}  #[char]$_ = [convert]::tochar($_)
  97..122 | %{"{0} = {1}" -f $_, [char]$_}
  "Abc".toCharArray() | %{"{0} = {1}" -f $_, [int][char]$_}

  #escape char: `
  " ``!@#$%^&*()-=[]\;',./~_+{}|:`"<>?".toCharArray() | %{"{0} = {1}" -f $_, [int][char]$_}
  chars = " `!@#$%^&*()-=[]\\;',./~_+{}|:\"<>?"

  $chars = " ``!@#$%^&*()-=[]\;',./~_+{}|:`"<>?"
  $chars.toCharArray() | %{"{0} = {1}" -f $_, [int][char]$_}

- p# list functions
  gci function:*

- using css line-height to vertically center text in a div
  source: http://www.zann-marketing.com/developer/20050518/vertically-centering-text-using-css.html

  this works well for one line of text, need to modify for n lines
  - specify the line-height to be the same height as the block element
    <div style="line-height:1em;background-color:#dcdcdc">
      vertically centered text
    </div>

- js percentage fx
  //pct(1, 2)  //50%"
  //pct(9, 7.89)  //114.07%
  function pct(x, y)  //string
  {
    var result = (x / y),
        fmt = x + "/" + y + " = ";

    console.log(fmt + result);  //9/7.89 = 1.1406844106463878
    result = ((result * 100).toFixed(2)).replace(".00", "") + "%";
    console.log(fmt + result);  //9/7.89 = 114.07%

    //return ((x / y) * 100).toFixed(2).replace(".00", "") + "%";  //one liner
    return result;
  }

- p# percentage fx
  #pct 1 2      #50%
  #pct 9 7.89   #114.07%
  #(pct 1 2)[2] #50%
  function pct($x, $y)  #string[]
  {
    $result = ($x / $y)
    $fmt = "{0}/{1} = " -f $x, $y
    $fmt + $result  #9/7.89 = 1.14068441064639
    $result = "{0}%" -f (round($result * 100))
    "{0}{1}" -f $fmt, $result  #9/7.89 = 114.07%

    #"{0}%" -f (round(($x / $y)*100))  #one liner
    $result
  }

- p# base conversions
  int to binary  [convert]::tostring(256, 2)         #100000000
  int to hex     (256).tostring("x")                 #100
  int to hex     [convert]::tostring(256, 16)        #100
  int to hex     "{0:x}" -f 256                      #100
  int to octal   [convert]::tostring(256, 8)         #400
  binary to int  [convert]::toint32("100000000", 2)  #256
  hex to int     0x100                               #256
  octal to int   [convert]::toint32("400", 8)        #256

- linux bash base conversions
  int to binary echo 'obase=2; 256' | bc        #100000000
  int to hex    echo 'obase=16; 256' | bc       #100
  int to hex    printf '%x\n' 256               #100
  int to octal  echo 'obase=8; 256' | bc        #400
  binary to int echo 'ibase=2; 100000000' | bc  #256
  hex to int    echo $((0x100))                 #256
  hex to int    echo 'ibase=16; 100' | bc       #256
  hex to int    printf '%d\n' 0x100             #256
  octal to int  echo 'ibase=8; 400' | bc        #256

- MSBuild error when building an Azure webrole project that has no cs files included.
  Error occurs in CoreCompile build phase, see build output.
  Error Message: "CSC : fatal error CS2008: No inputs specified [x:\web\cloudServiceWebRole.csproj]"

  Fix/Workaround
  - include an empty cs file in project, this adds a compile entry to the project file
    <ItemGroup>
      <Compile Include="a.cs" />
    </ItemGroup>

- #win server 2008 services
  - get-service * | ?{$_.name -match "mpsSvc|spooler|termService|trustedInstaller|umRdpService|w3svc|was|wuauserv"}

- substitute folder
    subst /?
    subst x: \_data
    subst y: \\10.0.0.0\temp\

- net use
  net use \\10.0.0.1\c$    * /user:domain\john  #prompt for password
  net use \\10.0.0.1\share * /user:\john
  net use \\10.0.0.1\c$    * /user:administrator
  net use \\10.0.0.1\c$ <password> /user:administrator
  net use \\10.0.0.1\c$ /delete

- p#
  gci env:
  get-psDrive
  get-psDrive -psProvider fileSystem

- lock windows command
  http://msdn.microsoft.com/en-us/library/aa376875(v=vs.85).aspx
  "This function has the same result as pressing Ctrl+Alt+Del and clicking Lock Workstation."
  &rundll32.exe user32.dll, LockWorkStation

- task manager view command-line column
  task manager -> processes tab -> view - select columns -> command line

  - runs these p# wmi scripts as Administrator to see all process command lines
    get-wmiobject win32_process | select commandline
    get-wmiobject win32_process | select *

- p# move files fx, performs xcopy and then deletes sourceFolder
    - move-item cmdlet too limited, eg error: "Move-Item : Source and destination path must have identical roots. Move will not work across volumes."

    #WARNING, this fx deletes the source folder after copying files to destination folder
    #xcopyMoveDelete "x:\data\*" "z:\backup\data\"
    function xcopyMoveDelete($sourceFolder, $destinationFolder)
    {
      xcopy $sourceFolder $destinationFolder /s/h/q

      #DELETE SOURCE FOLDER WARNING, remove-item cmdlet deletes the source folder - comment whatif param to execute
      "deleting source folder: $sourceFolder"
      ri $sourceFolder.trim("*") -recurse -force -whatif
    }

- p# security
  use set-executionPolicy cmdlet to allow script file execution
  #set-executionPolicy remoteSigned

- p# profile script
  - windows 7/server 2008
    c:\users\john\documents\windowspowershell\profile.ps1
      cd\
      cls

- get-service * | ?{($_.status -eq "running")
  get-service * | ?{($_.status -eq "stopped") -and ($_.name -match "sql|mssql")}

- #calcTaxRate 99 8.25
  #sub    99.00
  #tax     8.25 (0.0833333333333333)
  #total 107.25
  function calcTaxRate([float]$subtotal, [float]$tax)
  {
    $subtotalFmt = "{0:0.00}" -f $subtotal
    $taxFmt      = "{0:0.00}" -f $tax

    #calc
    $taxrate  = $tax/$subtotal
    $total    = $subtotal * (1 + $taxrate)  #calc using taxrate, not tax input param
    $totalFmt = "{0:0.00}" -f $total

    #pseudo right-justify hack
    $subPadding = " " * ( ("$totalFmt".length) - ("$subtotalFmt".length) )
    $taxPadding = " " * ( ("$totalFmt".length) - ("$taxFmt".length)      )

    #output
    "sub   {0}{1}"       -f $subPadding, $subtotalFmt
    "tax   {0}{1} ({2})" -f $taxPadding, $taxFmt, $taxrate
    "total $totalFmt"
  }

- #round 12.3456    #12.35
  #round 12.3456 3  #12.346
  function round($value, $decimals=2)
  {
    [system.decimal]::round($value, $decimals)
  }

- min F# console app examples, for breakpoint
  System.Diagnostics.Debugger.Break()  //ex 1 auto breakpoint
  System.Console.ReadLine() |> ignore  //ex 2

- visual studio command window
    - shortcut keys: ctl + alt + A

      COMMAND                      DESCRIPTION
      build.rebuildSolution
      cls                          clear screen
      debug.breakpoints            open breakpoints window
      debug.disableAllBreakpoints
      debug.enableAllBreakpoints
      debug.watch2                 open watch-2 window
      file.copyFullPath
      file.openContainingFolder
      ? "abc".Length               3
      ? x                          debug print x var/value
      ?? x                         debug quickwatch

    Predefined Visual Studio Command Aliases
    http://msdn.microsoft.com/en-us/library/c3a0kd3x.aspx

- ipconfig /release;
  ipconfig /flushdns;
  ipconfig /renew;

- p# cultureInfo
  get-culture cmdlet
  [system.threading.thread]::currentThread.currentUICulture

  (get-culture).textInfo.toTitleCase("foo bar")  #Foo Bar

- set-alias <alias> <function>
  set-alias foo calcFooPiSquare

- xcopy x:\data\*        x:\backup\data\ /s/h/q
  xcopy x:\data\*        x:\backup\data\ /s/h/q/d:01-01-2011  #files modified on or after date
  xcopy x:\data\*        x:\backup\data\ /s/h/q/exclude:x:\exclude.txt
  xcopy x:\data\file.txt x:\backup\data\ /s/h/q
  /e to copy empty folders

  file: exclude.txt
  .bmp
  .pdf
  .dll
  .exe
  .ini
  .log
  .suo
  .temp
  .user
  \.git\
  \.svn\
  \bin\
  \debug\
  \images\
  \obj\
  \release\
  thumbs.db

- hosts files
  mac:     /etc/hosts
  windows: c:\windows\system32\drivers\etc\hosts

- p# copy windows hosts file
  gc c:\windows\system32\drivers\etc\hosts | out-file x:\backup\data\hosts.txt -encoding utf8

- virtual pc, toggle fullscreen: (right-alt) + enter

- p# find all unique words/matches in file
  use select-string allmatches with regex capture to show only match, not standard select-string output full line

  - gi x:\foo.txt |
      select-string "(\w+)" -allmatches |
      %{
         foreach($m in $_.matches) { #loop all matches found in line
           $m.groups[0].value
         }
       } | sort -unique

  - #one line
    gi x:\foo.txt | select-string "(\w+)" -allmatches | %{foreach($m in $_.matches){$m.groups[0].value}} | sort -unique

- file attributes
  attrib /?

  #alt view file and folder attributes
  gci x:\foo\ -rec

  #view file attribute
  attrib x:\foo\a.txt

  #set readonly file attribute
  attrib +r x:\foo\a.txt

  #remove readonly file attribute
  attrib -r x:\foo\a.txt

  #recursive, files and folders
  attrib +r x:\foo\* /s /d
  attrib -r x:\foo\* /s /d

- reserved p# variables, do not use for var names
  "$args"
  "$input"

- p# REPL template for input loop processing, eg script calculator
  requires entering input value only, not function/alias name
  if function requires multiple params, split input param in function

  #---------------------------------------------------
  #template 1, min

  function foo($string){$string}     #function
  while ($true) {                    #loop
    $in = read-host "enter a value"  #read input
    foo($in)                         #call function
  }
  #---------------------------------------------------
  #template 2, +ux

  $host.ui.rawUI.windowTitle = "loop..."  #set window title
  function foo($string){$string}          #function
  while ($true) {                         #loop
    $in = read-host "enter a value"       #read input
    if ($in -match "^(exit|quit|q)$") {   #exit loop support
      "exiting loop"  #exit
      break
    }
    else {
      foo($in)                            #call function
    }
  }
  #---------------------------------------------------
  #template 3, anonymous function

  while ($true) {                         #loop
    $in = read-host "enter a value"       #read input
    if ($in -match "^(exit|quit|q)$") {   #exit loop support
      "exiting loop"  #exit
      break
    }
    else {
      &{param($string) $string} $in       #call anonymous function
    }
  }
  #---------------------------------------------------

- p# set window title
  $host.ui.rawUI.windowTitle = "main"

- regular expressions
  - find html opening tags
    <a[^>]*>
    <form[^>]*>

  - remove b html tags
    search:<b[^>]*>(.*?)</b>
    replace:\1

  - regex match empty lines
    REGEX              DESCRIPTION
    ^\s*$              match empty line
    ^\s*$\r\n          match empty line, with linebreak

  - regex match duplicate lines in a text file, sort content first
    search:^(.*)(\r?\n\1)+$
    replace:\1

  - regex match html anchor tags
    works with multiple anchors on same line, and multiline using "dot matches newline"
    the question mark in this regex ".*?" is what allows it to match multiples on same line
    REGEX                     DESCRIPTION
    <a[^>]*>.*?</a>           match entire tag
    (?<=<a[^>]*>).*?(?=</a>)  match text only, including empty
                 ---          regex to match
    -------------             lookbehind, match regex, then lookbehind and match anchor tag
                    --------  lookahead,  match regex, then lookahead and match closing anchor tag

  - regex lookaround - noncapturing groups - "lookaway" :)
    NAME                REGEX   EXAMPLE  DESCRIPTION                                  MATCH
    lookahead           (?=R)   A(?=B)   match A, then lookahead and match B          matches the A
                                         A followed by B
    negative lookahead  (?!R)   A(?!B)   match A, then lookahead and match if NOT B   matches the A
                                         match A, as long as it's NOT followed by B
                                         A NOT followed by B
    lookbehind          (?<=R)  (?<=A)B  match B, then lookbehind and match A         matches the B
                                         B preceeded by A
    negative lookbehind (?<!R)  (?<!A)B  match B, then lookbehind and match if NOT A  matches the B
                                         match B, as long as it's NOT preceeded by A
                                         B NOT preceeded by A

- p# dynamic array
  (1..3)[1]  #2

- p# html encode file, line by line
  $file = "x:\foo.txt"
  gc $file | %{htmlEncode($_)} > ($file + ".out")  #x:\foo.txt.out

- p# html encode multiline string, here string
  $hs = @"
    #...
    #...
  "@

  $hs | %{htmlencode $_}

- add-type -assembly system.web  #calling add-type multiple times - ok
  function htmlEncode($string)
  {
      [web.httputility]::htmlencode($string)
  }

  #getOutFileName x:\file.txt  #x:\file.txt.out
  function getOutFileName($infile)
  {
      [io.path]::getFileName($infile) + ".out"
  }

  function getOutFilePath($infile)
  {
      [io.path]::getdirectoryname($infile)
  }

- html/url encoding
  add-type -assembly system.web
  [web.httputility]::htmlencode("<foo />")
  [web.httputility]::htmldecode("&lt;foo /&gt;")
  [web.httputility]::urlencode("www.foo.com/?a=b")
  [web.httputility]::urldecode("www.foo.com%2f%3fa%3db")

- loading .net assemblies into p#, add-type replaces loadWithPartialName (obsolete)
  add-type -assembly system.web       #load system web
  add-type -assembly system.xml.linq  #load linq xml

  #add-type -assemblyName system.web  #alt assemblyName param
  #[system.reflection.assembly]::loadWithPartialName("system.web") #obsolete, use in p1

- asp.net mvc routing, redirect
  internal: use IIS URL rewrite
  external: use Controller.RedirectPermanent() and Controller.Redirect() to redirect to other domains

  public RedirectResult Redirect()
  {
      var url = "http://www.expressionsoftware.com/";
      return RedirectPermanent(url);  //301 permanent redirect
      //return Redirect(url);         //302 temporary redirect
  }

- open files with p# invoke-item cmdlet
  #open file in default text editor, eg notepad
  ii x:\temp\foo.txt

  #open all text files
  gci x:\temp\* -inc *.txt -rec -force | %{ii $_.fullname}

- css even-odd background color
  tr:nth-child(odd)
  {
      background-color: #fff;
  }
  tr:nth-child(even)
  {
      background-color: gainsboro;
  }

- ms minifier
  $infile = 'x:\file.debug.js'
  $outfile = 'x:\file.js'
  $m = 'x:\lib\microsoftAjaxMinifier\v4\ajaxMin.exe'
  &$m -js -clobber $infile -out $outfile -enc:out 'utf-8'

- html 5
  <!doctype html>
  <html lang=en>
  <head>
    <title></title>
    <meta charset=utf-8>
  </head>
  <body>
  </body>
  </html>

- browser indent outdent margin
  document.body.style.marginTop    = "1000px";
  document.body.style.marginLeft   = "-100px";
  document.body.style.marginBottom = "200px";

- hex color scale #000000 - ffffff, dark to light
  dark to light  0123456789abcdef 0-9a-f
  light to dark  fedcba9876543210 f-a9-0

- webpage text and background color dom js
  - black background #000, ghost text #111
    document.body.style.backgroundColor = "#000"; document.body.style.color = "#111";

  - white background #fff, ghost text #eee
    document.body.style.backgroundColor = "#fff"; document.body.style.color = "#eee";

  - wicked terminal green
    document.body.style.backgroundColor = "#000"; document.body.style.color = "#1ca62e";

  - all elements
    var x = document.getElementsByTagName("*");
    for(var i=0; i<x.length; i++) {
      x[i].style.backgroundColor = "#000";
      x[i].style.color = "#aaa"
    }

- text editor colors font
  https://www.expressionsoftware.com/apps/texteditor/
  var x = document.getElementsByTagName("textarea")[0];
  x.style.backgroundColor = "#000";
  x.style.color = "#444";
  x.style["font-family"] = "verdana"
  x.style.borderColor = "#000";
  x.style.margin = "0";
  x.style.padding = "1em 0 0 2em";

- set browser title date
  function formatDateTime(date)  //12:34:00
  {
    date = date || new Date();
    return date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
  }

  (function()
  {
    document.title = formatDateTime() + ' ' + document.title;
  }());  //immediate

- browser scroll
  document.body.scrollTop = 500;  //c
  $(window).scrollTop(500);       //cfi

- windows temp folders
  win 7/8: c:\users\nelson\appdata\local\temp

- remote desktop services terminal services admin/console
  $ts = 'c:\windows\system32\mstsc.exe'
  &$ts /v:DEV01 /f /admin    #2008+
  &$ts /v:DEV01 /f /console  #2003

- restart/shutdown windows
  shutdown /s /f /t 0                #shutdown 0 seconds
  shutdown /r /f /t 0                #restart 0 seconds
  shutdown /r /f /t 0 /m \\10.0.0.0
  shutdown /r /f /t 0 /m \\DEV01

11/26/13

Countcha Blog

Countcha news and updates...

Dec 1
Version 4 status - in development
• Full version: save and reopen counters, more units, new theme colors, no Ads.

Nov 30
Version 3 available on the App Store, free.
• Improved Help Functions tab now shows visual example of gestures.




Nov 19
Version 2 available on the App Store, free.
• Menu gesture hint is shown on start up and hidden on first menu gesture
• Hint is re-displayed anytime all counters are deleted

Nov 10
Version 1 available on the App Store, free.

Misc

Countcha Website
iTunes


4/15/13

C

iOS Assets Library

#import <AssetsLibrary/AssetsLibrary.h>

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [self dismissViewControllerAnimated:YES completion:nil];
    NSURL * assetUrl = [info objectForKey:UIImagePickerControllerReferenceURL];
    NSLog(@"%@", assetUrl.absoluteString);  //"assets-library://asset/asset.JPG?id=ABC7EF08-B1BF-4FFB-9FF9-4FF70FD0610F&ext=JPG"
    [self loadImageFromAsset:assetUrl];
}

-(void)loadImageFromAsset:(NSURL *)assetUrl
{
    ALAssetsLibrary * assetLib = [[ALAssetsLibrary alloc] init];
    [assetLib assetForURL:assetUrl
              resultBlock:^(ALAsset * asset)
                          {
                              ALAssetRepresentation * assetRep = [asset defaultRepresentation];
                              CGImageRef image = [assetRep fullScreenImage];  //full-screen-image to show edited version
                              [self setImageViewWithImage:image];
                          }
             failureBlock:^(NSError * error)
                          {
                              //log...
                          }];
}

-(void)setImageViewWithImage:(CGImageRef)image
{
    UIImageView * imageView = (UIImageView *)[[self view] viewWithTag:ivTag];
    [imageView setImage:[UIImage imageWithCGImage:image]];
}


-----------------------------------------------------------

Objective-C Delegate Protocol

Use UIResponder touchesBegan:withEvent and a protocol to enable a UIImageView to respond to user touch. Sends message to delegate (view controller in this example), delegate can then respond to image touch by launching image picker, etc


Storyboard - ESTouchImageView Settings


Components




ESTouchViewDelegate (Protocol)
- declares the protocol delegate method esTouchViewMsg
- when the user touches a view, an esTouchViewMsg should be sent to the delegate (class) that conforms to the protocol
//file ESTouchViewDelegate.h
@protocol ESTouchViewDelegate<NSObject>

    -(void)esTouchViewMsg;
@end

ESTouchImageView (Custom UIImageView Class)
- has ESTouchViewDelegate protocol property
- on touchesBegan:withEvent: sends esTouchViewMsg to delegate (class) that conforms to the protocol
//file ESTouchImageView.h
#import "ESTouchViewDelegate.h"

@interface ESTouchImageView: UIImageView

    @property (weak, nonatomic) id<ESTouchViewDelegate> esTouchViewDelegate;
@end


//file ESTouchImageView.m
#import "ESTouchImageView.h"

@implementation ESTouchImageView

    //send touch message to delegate from UIResponder touches began event
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"ESTouchImageView - touchesBegan");
        [self sendESTouchViewMsgToDelegate];
    }

    -(void)sendESTouchViewMsgToDelegate
    {
        NSLog(@"ESTouchImageView - sendESTouchViewMsgToDelegate");
        [[self esTouchViewDelegate] esTouchViewMsg];
    }
@end

ESViewController (Delegate)
- has ESTouchImageView control
- conforms to the ESTouchViewDelegate protocol
- is the delegate (ESTouchViewDelegate) for ESTouchImageView
- sets self (view controller) as delegate using IBOutlet property (or viewWithTag reference)
- will respond to the esTouchViewMsg delegate method
//file ESViewController.h
#import "ESTouchImageView.h"

    @interface ESViewController: UIViewController<ESTouchViewDelegate>

        @property (weak, nonatomic) IBOutlet ESTouchImageView * esTouchImageView;
    @end


//file ESViewController.m
#import "ESViewController.h"

@implementation ESViewController

    -(void)viewDidLoad
    {
        [super viewDidLoad];

        //set delegate using IBOutlet property
        [[self esTouchImageView] setEsTouchViewDelegate:self];  //set view controller as delegate

        //set delegate using viewWithTag reference
        //ESTouchImageView * esTouchImageView = (ESTouchImageView *)[[self view] viewWithTag:100];
        //[esTouchImageView setEsTouchViewDelegate:self];  //set view controller as delegate
    }

    -(void)esTouchViewMsg
    {
        NSLog(@"ESViewController - esTouchViewMsg");
        //launch image picker, etc
    }
@end

NSLog Output
ESTouchImageView - touchesBegan
ESTouchImageView - sendESTouchViewMsgToDelegate
ESViewController - esTouchViewMsg

-----------------------------------------------------------

Objective-C Delegate Protocol

On scene exit, send exit message from destination/presented view to the source/presenting view, pass bool indicating cancelled
//file ESExitSceneDelegate.h
@protocol ESExitSceneDelegate<NSObject>

    @optional
    -(void)esExitSceneMsg;
    -(void)esExitSceneMsgCancelled:(BOOL)cancelled;
@end


//file ESEditViewController.h
#import "ESExitSceneDelegate.h"  //protocol

@interface ESEditViewController: UITableViewController

    @property (weak, nonatomic) id<ESExitSceneDelegate> esExitSceneDelegate;
 // @property (weak, nonatomic) IBOutlet UIBarButtonItem * uiCancelBtn;
    @property (weak, nonatomic) IBOutlet UIBarButtonItem * uiSaveBtn;
@end


//file ESEditViewController.m
#import "ESEditViewController.h"

@implementation ESEditViewController
{
    //ivar referencing outlet, alt to prop
    IBOutlet UIBarButtonItem * uiCancelBtn;
}

    -(IBAction)cancel:(id)sender
    {
        [[self navigationController] popToRootViewControllerAnimated:YES];
        [[self esExitSceneDelegate] esExitSceneMsgCancelled:YES];
    }

    -(IBAction)save:(id)sender
    {
        [[self navigationController] popToRootViewControllerAnimated:YES];
        [[self esExitSceneDelegate] esExitSceneMsgCancelled:NO];
    }


//file ESViewController.h
#import "ESExitSceneDelegate.h"  //protocol

@interface ESViewController: UIViewController<ESExitSceneDelegate>
@end


//file ESViewController.m
#import "ESEditViewController.h"
#import "ESViewController.h"

@implementation ESViewController

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        ESEditViewController * esEditViewController = segue.destinationViewController;
        [esEditViewController setEsExitSceneDelegate:self];  //set delegate
    }

    -(void)esExitSceneMsgCancelled:(BOOL)cancelled
    {
        if (cancelled)
        {
            //...
        }
        else
        {
            //...
        }
    }
@end

1/2/13

PC Load Letter - Google Checkout Wallet "Oops" Error

Anybody know a solution to this error?

Get error when trying to sign up to sell Android apps on Google Play Developers site.
Error occurs when submitting the Google Merchant Account Business Information page.







Links
http://code.google.com/p/android/issues/detail?id=35945
http://productforums.google.com/forum/#!topic/android-market/AB6F-YcJ5bg
http://productforums.google.com/forum/#!msg/checkout-merchant/nwRms9_LgHA/UP8Pdf25TFoJ


ahhhh, Thank you Onion, "mf time vampire" :)
"Google Releases Stupid F*cking Piece Of Sh*t That Doesn't F*cking Work!"
http://www.youtube.com/watch?v=AOgwQZd9eDc
http://www.youtube.com/watch?v=8AyVh1_vWYQ