appendix: JSON
==================
[
    {
        "first": "Jerome",
        "middle": "Lester",
        "last": "Howard",
        "nick-name": "Curly",
        "born": 1903,
        "died": 1952,
        "quote": "nyuk-nyuk-nyuk!"
    },
    {
        "first": "Harry",
        "middle": "Moses",
        "last": "Howard",
        "nick-name": "Moe",
        "born": 1897,
        "died": 1975,
        "quote": "Why, you!"
    },
    {
        "first": "Louis",
        "last": "Feinberg",
        "nick-name": "Larry",
        "born": 1902,
        "died": 1975,
        "quote": "I'm sorry. Moe, it was an accident!"
    }
]
    
    
====================================
var myData = eval('(' + myJSONText + ')');
    
    
====================================
var json_parse = function () {

// Funkcja ta potrafi analizowa tekst w formacie JSON, zwracajc struktur
// danych JavaScriptu. Jest to prosty, rekurencyjny parser.

// Definiujemy funkcj wewntrz innej funkcji aby unikn tworzenia
// zmiennych globalnych.

     var at,     // Indeks biecego znaku
         ch,     // Biecy znak
         escapee = {
             '"':  '"',
             '\\': '\\',
             '/':  '/',
             b:    'b',
             f:    '\f',
             n:    '\n',
             r:    '\r',
             t:    '\t'
         },
         text,

         error = function (m) {

// Zgaszamy bd gdy co poszo nie tak.

             throw {
                 name:    'SyntaxError',
                 message: m,
                 at:      at,
                 text:    text
             };
         },

         next = function (c) {

// Jeli parametr c zosta przekazany, sprawdzamy czy pasuje on do biecego znaku.

             if (c && c !== ch) {
                 error("Oczekiwano '" + c + "' zamiast '" + ch + "'");
             }

// Pobieramy nastpny znak. Jeli nie ma wicej znakw,
// zwracamy pusty acuch.

             ch = text.charAt(at);
             at += 1;
             return ch;
         },

         number = function () {

// Przetwarzamy liczb.

             var number,
                 string = '';

             if (ch === '-') {
                 string = '-';
                 next('-');
             }
             while (ch >= '0' && ch <= '9') {
                 string += ch;
                 next();
             }
             if (ch === '.') {
                 string += '.';
                 while (next() && ch >= '0' && ch <= '9') {
                     string += ch;
                 }
             }
             if (ch === 'e' || ch === 'E') {
                 string += ch;
                 next();
                 if (ch === '-' || ch === '+') {
                     string += ch;
                     next();
                 }
                 while (ch >= '0' && ch <= '9') {
                     string += ch;
                     next();
                 }
             }
             number = +string;
             if (isNaN(number)) {
                 error("Niepoprawna liczba");
             } else {
                 return number;
             }
         },

         string = function () {

// Przetwarzamy acuch.

             var hex,
                 i,
                 string = '',
                 uffff;

// Przy przetwarzaniu acuchw musimy uwaa na znaki " oraz \.

             if (ch === '"') {
                 while (next()) {
                     if (ch === '"') {
                         next();
                         return string;
                     } else if (ch === '\\') {
                         next();
                         if (ch === 'u') {
                             uffff = 0;
                             for (i = 0; i < 4; i += 1) {
                                 hex = parseInt(next(), 16);
                                 if (!isFinite(hex)) {
                                     break;
                                 }
                                 uffff = uffff * 16 + hex;
                             }
                             string += String.fromCharCode(uffff);
                         } else if (typeof escapee[ch] === 'string') {
                             string += escapee[ch];
                         } else {
                             break;
                         }
                     } else {
                         string += ch;
                     }
                 }
             }
             error("Niepoprawny acuch");
         },

         white = function () {

// Pomi biae znaki.

             while (ch && ch <= ' ') {
                 next();
             }
         },

         word = function () {

// true, false, lub null.

             switch (ch) {
             case 't':
                 next('t');
                 next('r');
                 next('u');
                 next('e');
                 return true;
             case 'f':
                 next('f');
                 next('a');
                 next('l');
                 next('s');
                 next('e');
                 return false;
             case 'n':
                 next('n');
                 next('u');
                 next('l');
                 next('l');
                 return null;
             }
             error("Nieoczekiwany znak '" + ch + "'");
         },

         value,  // Tu zapiszemy funkcj value

         array = function () {

// Przetwarzamy tablic.

             var array = [];

             if (ch === '[') {
                 next('[');
                 white();
                 if (ch === ']') {
                     next(']');
                     return array;   // pusta tablica
                 }
                 while (ch) {
                     array.push(value());
                     white();
                     if (ch === ']') {
                         next(']');
                         return array;
                     }
                     next(',');
                     white();
                 }
             }
             error("Niepoprawna tablica");
         },

         object = function () {

// Przetwarzamy obiekt.

             var key,
                 object = {};

             if (ch === '{') {
                 next('{');
                 white();
                 if (ch === '}') {
                     next('}');
                     return object;   // pusty obiekt
                 }
                 while (ch) {
                     key = string();
                     white();
                     next(':');
                     object[key] = value();
                     white();
                     if (ch === '}') {
                         next('}');
                         return object;
                     }
                     next(',');
                     white();
                 }
             }
             error("Niepoprawny obiekt");
         };

     value = function () {

// Przetwarzamy warto JSON. Moe to by obiekt, tablica, acuch, liczba,
// lub sowo.

         white();
         switch (ch) {
         case '{':
             return object();
         case '[':
             return array();
         case '"':
             return string();
         case '-':
             return number();
         default:
             return ch >= '0' && ch <= '9' ? number() : word();
         }
     };

// Zwracamy funkcj json_parse. Bdzie miaa dostp do wszystkich powyszych 
// funkcji i zmiennych.

     return function (source, reviver) {
         var result;

         text = source;
         at = 0;
         ch = ' ';
         result = value();
         white();
         if (ch) {
             error("Bd skadniowy");
         }

// Jeli istnieje funkcja reviver, rekurencyjnie przetwarzamy now struktur,
// przekazujc kad par nazwa-warto do funkcji reviver w celu moliwej 
// transformacji, zaczynajc od tymczasowego obiektu, ktry przechowuje wynik 
// pod pustym kluczem. Jeli nie ma funkcji reviver, po prostu zwracamy
// wynik.

         return typeof reviver === 'function' ?
             function walk(holder, key) {
                 var k, v, value = holder[key];
                 if (value && typeof value === 'object') {
                     for (k in value) {
                         if (Object.hasOwnProperty.call(value, k)) {
                             v = walk(value, k);
                             if (v !== undefined) {
                                 value[k] = v;
                             } else {
                                 delete value[k];
                             }
                         }
                     }
                 }
                 return reviver.call(holder, key, value);
             }({'': result}, '') : result;

     };
}();
    
    
==================