/*  Prototype JavaScript framework, version 1.6.0_rc0
 *  (c) 2005-2007 Sam Stephenson
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://www.prototypejs.org/
 *
 *--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.6.0_rc0',

  Browser: {
    IE:     !!(window.attachEvent && !window.opera),
    Opera:  !!window.opera,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
  },

  BrowserFeatures: {
    XPath: !!document.evaluate,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      document.createElement('div').__proto__ !==
       document.createElement('form').__proto__
  },

  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
};

if (Prototype.Browser.MobileSafari)
  Prototype.BrowserFeatures.SpecificElementExtensions = false;

/* Based on Alex Arnell's inheritance implementation. */
var Class = {
  create: function() {
    var parent = null, properties = $A(arguments);
    if (Object.isFunction(properties[0]))
      parent = properties.shift();

    function klass() {
      this.initialize.apply(this, arguments);
    }

    Object.extend(klass, Class.Methods);
    klass.superclass = parent;
    klass.subclasses = [];

    if (parent) {
      var subclass = function() { };
      subclass.prototype = parent.prototype;
      klass.prototype = new subclass;
      parent.subclasses.push(klass);
    }

    for (var i = 0; i < properties.length; i++)
      klass.addMethods(properties[i]);

    if (!klass.prototype.initialize)
      klass.prototype.initialize = Prototype.emptyFunction;

    klass.prototype.constructor = klass;

    return klass;
  }
};

Class.Methods = {
  addMethods: function(source) {
    var ancestor = this.superclass && this.superclass.prototype;

    for (var property in source) {
      var value = source[property];
      if (ancestor && Object.isFunction(value) &&
          value.argumentNames().first() == "$super") {
        var method = value, value = Object.extend((function(m) {
          return function() { return ancestor[m].apply(this, arguments) };
        })(property).wrap(method), {
          valueOf:  function() { return method },
          toString: function() { return method.toString() }
        });
      }
      this.prototype[property] = value;
    }

    return this;
  }
};

var Abstract = { };

Object.extend = function(destination, source) {
  for (var property in source)
    destination[property] = source[property];
  return destination;
};

Object.extend(Object, {
  inspect: function(object) {
    try {
      if (object === undefined) return 'undefined';
      if (object === null) return 'null';
      return object.inspect ? object.inspect() : object.toString();
    } catch (e) {
      if (e instanceof RangeError) return '...';
      throw e;
    }
  },

  toJSON: function(object) {
    var type = typeof object;
    switch (type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }

    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (Object.isElement(object)) return;

    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (value !== undefined)
        results.push(property.toJSON() + ': ' + value);
    }

    return '{' + results.join(', ') + '}';
  },

  toHTML: function(object) {
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
  },

  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },

  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },

  clone: function(object) {
    return Object.extend({ }, object);
  },

  isElement: function(object) {
    return object && object.nodeType == 1;
  },

  isArray: function(object) {
    return object && object.constructor === Array;
  },

  isFunction: function(object) {
    return typeof object == "function";
  },

  isString: function(object) {
    return typeof object == "string";
  },

  isNumber: function(object) {
    return typeof object == "number";
  },

  isUndefined: function(object) {
    return typeof object == "undefined";
  }
});

Object.extend(Function.prototype, {
  argumentNames: function() {
    var names = this.toString().match(/^[\s\(]*function\s*\((.*?)\)/)[1].split(",").invoke("strip");
    return names.length == 1 && !names[0] ? [] : names;
  },

  bind: function() {
    if (arguments.length < 2 && arguments[0] === undefined) return this;
    var __method = this, args = $A(arguments), object = args.shift();
    return function() {
      return __method.apply(object, args.concat($A(arguments)));
    }
  },

  bindAsEventListener: function() {
    var __method = this, args = $A(arguments), object = args.shift();
    return function(event) {
      return __method.apply(object, [event || window.event].concat(args));
    }
  },

  curry: function() {
    if (!arguments.length) return this;
    var __method = this, args = $A(arguments);
    return function() {
      return __method.apply(this, args.concat($A(arguments)));
    }
  },

  delay: function() {
    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
    return window.setTimeout(function() {
      return __method.apply(__method, args);
    }, timeout);
  },

  wrap: function(wrapper) {
    var __method = this;
    return function() {
      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
    }
  },

  methodize: function() {
    if (this._methodized) return this._methodized;
    var __method = this;
    return this._methodized = function() {
      return __method.apply(null, [this].concat($A(arguments)));
    };
  }
});

Function.prototype.defer = Function.prototype.delay.curry(0.01);

Date.prototype.toJSON = function() {
  return '"' + this.getUTCFullYear() + '-' +
    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
    this.getUTCDate().toPaddedString(2) + 'T' +
    this.getUTCHours().toPaddedString(2) + ':' +
    this.getUTCMinutes().toPaddedString(2) + ':' +
    this.getUTCSeconds().toPaddedString(2) + 'Z"';
};

var Try = {
  these: function() {
    var returnValue;

    for (var i = 0, length = arguments.length; i < length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) { }
    }

    return returnValue;
  }
};

RegExp.prototype.match = RegExp.prototype.test;

RegExp.escape = function(str) {
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};

/*--------------------------------------------------------------------------*/

var PeriodicalExecuter = Class.create({
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;

    this.registerCallback();
  },

  registerCallback: function() {
    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  execute: function() {
    this.callback(this);
  },

  stop: function() {
    if (!this.timer) return;
    clearInterval(this.timer);
    this.timer = null;
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.execute();
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
});
Object.extend(String, {
  interpret: function(value) {
    return value == null ? '' : String(value);
  },
  specialChar: {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '\\': '\\\\'
  }
});

Object.extend(String.prototype, {
  gsub: function(pattern, replacement) {
    var result = '', source = this, match;
    replacement = arguments.callee.prepareReplacement(replacement);

    while (source.length > 0) {
      if (match = source.match(pattern)) {
        result += source.slice(0, match.index);
        result += String.interpret(replacement(match));
        source  = source.slice(match.index + match[0].length);
      } else {
        result += source, source = '';
      }
    }
    return result;
  },

  sub: function(pattern, replacement, count) {
    replacement = this.gsub.prepareReplacement(replacement);
    count = count === undefined ? 1 : count;

    return this.gsub(pattern, function(match) {
      if (--count < 0) return match[0];
      return replacement(match);
    });
  },

  scan: function(pattern, iterator) {
    this.gsub(pattern, iterator);
    return String(this);
  },

  truncate: function(length, truncation) {
    length = length || 30;
    truncation = truncation === undefined ? '...' : truncation;
    return this.length > length ?
      this.slice(0, length - truncation.length) + truncation : String(this);
  },

  strip: function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  },

  stripTags: function() {
    return this.replace(/<\/?[^>]+>/gi, '');
  },

  stripScripts: function() {
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  },

  extractScripts: function() {
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    });
  },

  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  },

  escapeHTML: function() {
    var self = arguments.callee;
    self.text.data = this;
    return self.div.innerHTML;
  },

  unescapeHTML: function() {
    var div = new Element('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
      div.childNodes[0].nodeValue) : '';
  },

  toQueryParams: function(separator) {
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
    if (!match) return { };

    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
      if ((pair = pair.split('='))[0]) {
        var key = decodeURIComponent(pair.shift());
        var value = pair.length > 1 ? pair.join('=') : pair[0];
        if (value != undefined) value = decodeURIComponent(value);

        if (key in hash) {
          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
          hash[key].push(value);
        }
        else hash[key] = value;
      }
      return hash;
    });
  },

  toArray: function() {
    return this.split('');
  },

  succ: function() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  },

  times: function(count) {
    var result = '';
    for (var i = 0; i < count; i++) result += this;
    return result;
  },

  camelize: function() {
    var parts = this.split('-'), len = parts.length;
    if (len == 1) return parts[0];

    var camelized = this.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
  },

  capitalize: function() {
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  },

  underscore: function() {
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
  },

  dasherize: function() {
    return this.gsub(/_/,'-');
  },

  inspect: function(useDoubleQuotes) {
    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
      var character = String.specialChar[match[0]];
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  },

  toJSON: function() {
    return this.inspect(true);
  },

  unfilterJSON: function(filter) {
    return this.sub(filter || Prototype.JSONFilter, '#{1}');
  },

  isJSON: function() {
    var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
  },

  evalJSON: function(sanitize) {
    var json = this.unfilterJSON();
    try {
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
    } catch (e) { }
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
  },

  include: function(pattern) {
    return this.indexOf(pattern) > -1;
  },

  startsWith: function(pattern) {
    return this.indexOf(pattern) === 0;
  },

  endsWith: function(pattern) {
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
  },

  empty: function() {
    return this == '';
  },

  blank: function() {
    return /^\s*$/.test(this);
  },

  interpolate: function(object, pattern) {
    return new Template(this, pattern).evaluate(object);
  }
});

if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
  escapeHTML: function() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  },
  unescapeHTML: function() {
    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
  }
});

String.prototype.gsub.prepareReplacement = function(replacement) {
  if (Object.isFunction(replacement)) return replacement;
  var template = new Template(replacement);
  return function(match) { return template.evaluate(match) };
};

String.prototype.parseQuery = String.prototype.toQueryParams;

Object.extend(String.prototype.escapeHTML, {
  div:  document.createElement('div'),
  text: document.createTextNode('')
});

with (String.prototype.escapeHTML) div.appendChild(text);

var Template = Class.create({
  initialize: function(template, pattern) {
    this.template = template.toString();
    this.pattern = pattern || Template.Pattern;
  },

  evaluate: function(object) {
    if (Object.isFunction(object.toTemplateReplacements))
      object = object.toTemplateReplacements();

    return this.template.gsub(this.pattern, function(match) {
      if (object == null) return '';

      var before = match[1] || '';
      if (before == '\\') return match[2];

      var ctx = object, expr = match[3];
      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr);
      if (match == null) return '';

      while (match != null) {
        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
        ctx = ctx[comp];
        if (null == ctx || '' == match[3]) break;
        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
        match = pattern.exec(expr);
      }

      return before + String.interpret(ctx);
    }.bind(this));
  }
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;

var $break = { };

var Enumerable = {
  each: function(iterator, context) {
    var index = 0;
    iterator = iterator.bind(context);
    try {
      this._each(function(value) {
        iterator(value, index++);
      });
    } catch (e) {
      if (e != $break) throw e;
    }
    return this;
  },

  eachSlice: function(number, iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var index = -number, slices = [], array = this.toArray();
    while ((index += number) < array.length)
      slices.push(array.slice(index, index+number));
    return slices.collect(iterator, context);
  },

  all: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result = true;
    this.each(function(value, index) {
      result = result && !!iterator(value, index);
      if (!result) throw $break;
    });
    return result;
  },

  any: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result = false;
    this.each(function(value, index) {
      if (result = !!iterator(value, index))
        throw $break;
    });
    return result;
  },

  collect: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var results = [];
    this.each(function(value, index) {
      results.push(iterator(value, index));
    });
    return results;
  },

  detect: function(iterator, context) {
    iterator = iterator.bind(context);
    var result;
    this.each(function(value, index) {
      if (iterator(value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

  findAll: function(iterator, context) {
    iterator = iterator.bind(context);
    var results = [];
    this.each(function(value, index) {
      if (iterator(value, index))
        results.push(value);
    });
    return results;
  },

  grep: function(filter, iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var results = [];

    if (Object.isString(filter))
      filter = new RegExp(filter);

    this.each(function(value, index) {
      if (filter.match(value))
        results.push(iterator(value, index));
    });
    return results;
  },

  include: function(object) {
    if (Object.isFunction(this.indexOf))
      if (this.indexOf(object) != -1) return true;

    var found = false;
    this.each(function(value) {
      if (value == object) {
        found = true;
        throw $break;
      }
    });
    return found;
  },

  inGroupsOf: function(number, fillWith) {
    fillWith = fillWith === undefined ? null : fillWith;
    return this.eachSlice(number, function(slice) {
      while(slice.length < number) slice.push(fillWith);
      return slice;
    });
  },

  inject: function(memo, iterator, context) {
    iterator = iterator.bind(context);
    this.each(function(value, index) {
      memo = iterator(memo, value, index);
    });
    return memo;
  },

  invoke: function(method) {
    var args = $A(arguments).slice(1);
    return this.map(function(value) {
      return value[method].apply(value, args);
    });
  },

  max: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator(value, index);
      if (result == undefined || value >= result)
        result = value;
    });
    return result;
  },

  min: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator(value, index);
      if (result == undefined || value < result)
        result = value;
    });
    return result;
  },

  partition: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var trues = [], falses = [];
    this.each(function(value, index) {
      (iterator(value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  },

  pluck: function(property) {
    var results = [];
    this.each(function(value) {
      results.push(value[property]);
    });
    return results;
  },

  reject: function(iterator, context) {
    iterator = iterator.bind(context);
    var results = [];
    this.each(function(value, index) {
      if (!iterator(value, index))
        results.push(value);
    });
    return results;
  },

  sortBy: function(iterator, context) {
    iterator = iterator.bind(context);
    return this.map(function(value, index) {
      return {value: value, criteria: iterator(value, index)};
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }).pluck('value');
  },

  toArray: function() {
    return this.map();
  },

  zip: function() {
    var iterator = Prototype.K, args = $A(arguments);
    if (Object.isFunction(args.last()))
      iterator = args.pop();

    var collections = [this].concat(args).map($A);
    return this.map(function(value, index) {
      return iterator(collections.pluck(index));
    });
  },

  size: function() {
    return this.toArray().length;
  },

  inspect: function() {
    return '#<Enumerable:' + this.toArray().inspect() + '>';
  }
};

Object.extend(Enumerable, {
  map:     Enumerable.collect,
  find:    Enumerable.detect,
  select:  Enumerable.findAll,
  filter:  Enumerable.findAll,
  member:  Enumerable.include,
  entries: Enumerable.toArray,
  every:   Enumerable.all,
  some:    Enumerable.any
});
function $A(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) return iterable.toArray();
  else {
    var results = [];
    for (var i = 0, length = iterable.length; i < length; i++)
      results.push(iterable[i]);
    return results;
  }
}

if (Prototype.Browser.WebKit) {
  function $A(iterable) {
    if (!iterable) return [];
    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
        iterable.toArray) {
      return iterable.toArray();
    } else {
      var results = [];
      for (var i = 0, length = iterable.length; i < length; i++)
        results.push(iterable[i]);
      return results;
    }
  }
}

Array.from = $A;

Object.extend(Array.prototype, Enumerable);

if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0, length = this.length; i < length; i++)
      iterator(this[i]);
  },

  clear: function() {
    this.length = 0;
    return this;
  },

  first: function() {
    return this[0];
  },

  last: function() {
    return this[this.length - 1];
  },

  compact: function() {
    return this.select(function(value) {
      return value != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(Object.isArray(value) ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  },

  intersect: function(array) {
    return this.uniq().findAll(function(item) {
      return array.detect(function(value) { return item === value });
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  },

  toJSON: function() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (value !== undefined) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }
});

// use native browser JS 1.6 implementation if available
if (Object.isFunction(Array.prototype.forEach))
  Array.prototype._each = Array.prototype.forEach;

if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
  i || (i = 0);
  var length = this.length;
  if (i < 0) i = length + i;
  for (; i < length; i++)
    if (this[i] === item) return i;
  return -1;
};

if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
  var n = this.slice(0, i).reverse().indexOf(item);
  return (n < 0) ? n : i - n - 1;
};

Array.prototype.toArray = Array.prototype.clone;

function $w(string) {
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

if (Prototype.Browser.Opera){
  Array.prototype.concat = function() {
    var array = [];
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for (var i = 0, length = arguments.length; i < length; i++) {
      if (Object.isArray(arguments[i])) {
        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  };
}
Object.extend(Number.prototype, {
  toColorPart: function() {
    return this.toPaddedString(2, 16);
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  },

  toPaddedString: function(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  },

  toJSON: function() {
    return isFinite(this) ? this.toString() : 'null';
  }
});

$w('abs round ceil floor').each(function(method){
  Number.prototype[method] = Math[method].methodize();
});
var Hash = function(object) {
  if (object instanceof Hash) this.merge(object);
  else Object.extend(this, object || { });
};

Object.extend(Hash, {
  toQueryString: function(obj) {
    var parts = [];
    parts.add = arguments.callee.addPair;

    this.prototype._each.call(obj, function(pair) {
      if (!pair.key) return;
      var value = pair.value;

      if (value && typeof value == 'object') {
        if (Object.isArray(value)) value.each(function(value) {
          parts.add(pair.key, value);
        });
        return;
      }
      parts.add(pair.key, value);
    });

    return parts.join('&');
  },

  toJSON: function(object) {
    var results = [];
    this.prototype._each.call(object, function(pair) {
      var value = Object.toJSON(pair.value);
      if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
    });
    return '{' + results.join(', ') + '}';
  }
});

Hash.toQueryString.addPair = function(key, value, prefix) {
  key = encodeURIComponent(key);
  if (value === undefined) this.push(key);
  else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
};

Object.extend(Hash.prototype, Enumerable);
Object.extend(Hash.prototype, {
  _each: function(iterator) {
    for (var key in this) {
      var value = this[key];
      if (value && value == Hash.prototype[key]) continue;

      var pair = [key, value];
      pair.key = key;
      pair.value = value;
      iterator(pair);
    }
  },

  keys: function() {
    return this.pluck('key');
  },

  values: function() {
    return this.pluck('value');
  },

  index: function(value) {
    var match = this.detect(function(pair) {
      return pair.value === value;
    });
    return match && match.key;
  },

  merge: function(hash) {
    return $H(hash).inject(this, function(mergedHash, pair) {
      mergedHash[pair.key] = pair.value;
      return mergedHash;
    });
  },

  remove: function() {
    var result;
    for(var i = 0, length = arguments.length; i < length; i++) {
      var value = this[arguments[i]];
      if (value !== undefined){
        if (result === undefined) result = value;
        else {
          if (!Object.isArray(result)) result = [result];
          result.push(value);
        }
      }
      delete this[arguments[i]];
    }
    return result;
  },

  toQueryString: function() {
    return Hash.toQueryString(this);
  },

  inspect: function() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  },

  toJSON: function() {
    return Hash.toJSON(this);
  }
});

function $H(object) {
  if (object instanceof Hash) return object;
  return new Hash(object);
};

// Safari iterates over shadowed properties
if (function() {
  var i = 0, Test = function(value) { this.key = value };
  Test.prototype.key = 'foo';
  for (var property in new Test('bar')) i++;
  return i > 1;
}()) Hash.prototype._each = function(iterator) {
  var cache = [];
  for (var key in this) {
    var value = this[key];
    if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
    cache.push(key);
    var pair = [key, value];
    pair.key = key;
    pair.value = value;
    iterator(pair);
  }
};
ObjectRange = Class.create({
  initialize: function(start, end, exclusive) {
    this.start = start;
    this.end = end;
    this.exclusive = exclusive;
  },

  _each: function(iterator) {
    var value = this.start;
    while (this.include(value)) {
      iterator(value);
      value = value.succ();
    }
  }
});

Object.extend(ObjectRange.prototype, Enumerable);

ObjectRange.prototype.include = function(value) {
  if (value < this.start)
    return false;
  if (this.exclusive)
    return value < this.end;
  return value <= this.end;
};

var $R = function(start, end, exclusive) {
  return new ObjectRange(start, end, exclusive);
};

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
  },

  activeRequestCount: 0
};

Ajax.Responders = {
  responders: [],

  _each: function(iterator) {
    this.responders._each(iterator);
  },

  register: function(responder) {
    if (!this.include(responder))
      this.responders.push(responder);
  },

  unregister: function(responder) {
    this.responders = this.responders.without(responder);
  },

  dispatch: function(callback, request, transport, json) {
    this.each(function(responder) {
      if (Object.isFunction(responder[callback])) {
        try {
          responder[callback].apply(responder, [request, transport, json]);
        } catch (e) { }
      }
    });
  }
};

Object.extend(Ajax.Responders, Enumerable);

Ajax.Responders.register({
  onCreate:   function() { Ajax.activeRequestCount++ },
  onComplete: function() { Ajax.activeRequestCount-- }
});

Ajax.Base = Class.create({
  initialize: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      contentType:  'application/x-www-form-urlencoded',
      encoding:     'UTF-8',
      parameters:   '',
      evalJSON:     true,
      evalJS:       true
    };
    Object.extend(this.options, options || { });

    this.options.method = this.options.method.toLowerCase();
    if (Object.isString(this.options.parameters))
      this.options.parameters = this.options.parameters.toQueryParams();
  }
});

Ajax.Request = Class.create(Ajax.Base, {
  _complete: false,

  initialize: function($super, url, options) {
    $super(options);
    this.transport = Ajax.getTransport();
    this.request(url);
  },

  request: function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = Object.clone(this.options.parameters);

    if (!['get', 'post'].include(this.method)) {
      // simulate other verbs over post
      params['_method'] = this.method;
      this.method = 'post';
    }

    this.parameters = params;

    if (params = Hash.toQueryString(params)) {
      // when GET, append parameters to URL
      if (this.method == 'get')
        this.url += (this.url.include('?') ? '&' : '?') + params;
      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        params += '&_=';
    }

    try {
      var response = new Ajax.Response(this);
      if (this.options.onCreate) this.options.onCreate(response);
      Ajax.Responders.dispatch('onCreate', this, response);

      this.transport.open(this.method.toUpperCase(), this.url,
        this.options.asynchronous);

      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);

      this.transport.onreadystatechange = this.onStateChange.bind(this);
      this.setRequestHeaders();

      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
      this.transport.send(this.body);

      /* Force Firefox to handle ready state 4 for synchronous requests */
      if (!this.options.asynchronous && this.transport.overrideMimeType)
        this.onStateChange();

    }
    catch (e) {
      this.dispatchException(e);
    }
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState > 1 && !((readyState == 4) && this._complete))
      this.respondToReadyState(this.transport.readyState);
  },

  setRequestHeaders: function() {
    var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'X-Prototype-Version': Prototype.Version,
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    };

    if (this.method == 'post') {
      headers['Content-type'] = this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : '');

      /* Force "Connection: close" for older Mozilla browsers to work
       * around a bug where XMLHttpRequest sends an incorrect
       * Content-length header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
            headers['Connection'] = 'close';
    }

    // user-defined headers
    if (typeof this.options.requestHeaders == 'object') {
      var extras = this.options.requestHeaders;

      if (Object.isFunction(extras.push))
        for (var i = 0, length = extras.length; i < length; i += 2)
          headers[extras[i]] = extras[i+1];
      else
        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
    }

    for (var name in headers)
      this.transport.setRequestHeader(name, headers[name]);
  },

  success: function() {
    var status = this.getStatus();
    return !status || (status >= 200 && status < 300);
  },

  getStatus: function() {
    try {
      return this.transport.status || 0;
    } catch (e) { return 0 }
  },

  respondToReadyState: function(readyState) {
    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);

    if (state == 'Complete') {
      try {
        this._complete = true;
        (this.options['on' + response.status]
         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(response, response.headerJSON);
      } catch (e) {
        this.dispatchException(e);
      }

      var contentType = response.getHeader('Content-type');
      if (this.options.evalJS == 'force'
          || (this.options.evalJS && contentType
          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
        this.evalResponse();
    }

    try {
      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
    } catch (e) {
      this.dispatchException(e);
    }

    if (state == 'Complete') {
      // avoid memory leak in MSIE: clean up
      this.transport.onreadystatechange = Prototype.emptyFunction;
    }
  },

  getHeader: function(name) {
    try {
      return this.transport.getResponseHeader(name);
    } catch (e) { return null }
  },

  evalResponse: function() {
    try {
      return eval((this.transport.responseText || '').unfilterJSON());
    } catch (e) {
      this.dispatchException(e);
    }
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Response = Class.create({
  initialize: function(request){
    this.request = request;
    var transport  = this.transport  = request.transport,
        readyState = this.readyState = transport.readyState;

    if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
      this.status       = this.getStatus();
      this.statusText   = this.getStatusText();
      this.responseText = String.interpret(transport.responseText);
      this.headerJSON   = this.getHeaderJSON();
    }

    if(readyState == 4) {
      var xml = transport.responseXML;
      this.responseXML  = xml === undefined ? null : xml;
      this.responseJSON = this.getResponseJSON();
    }
  },

  status:      0,
  statusText: '',

  getStatus: Ajax.Request.prototype.getStatus,

  getStatusText: function() {
    try {
      return this.transport.statusText || '';
    } catch (e) { return '' }
  },

  getHeader: Ajax.Request.prototype.getHeader,

  getAllHeaders: function() {
    try {
      return this.getAllResponseHeaders();
    } catch (e) { return null }
  },

  getResponseHeader: function(name) {
    return this.transport.getResponseHeader(name);
  },

  getAllResponseHeaders: function() {
    return this.transport.getAllResponseHeaders();
  },

  getHeaderJSON: function() {
    var json = this.getHeader('X-JSON');
    try {
      return json ? json.evalJSON(this.request.options.sanitizeJSON) : null;
    } catch (e) {
      this.request.dispatchException(e);
    }
  },

  getResponseJSON: function() {
    var options = this.request.options;
    try {
      if (options.evalJSON == 'force' || (options.evalJSON &&
          (this.getHeader('Content-type') || '').include('application/json')))
        return this.transport.responseText.evalJSON(options.sanitizeJSON);
      return null;
    } catch (e) {
      this.request.dispatchException(e);
    }
  }
});

Ajax.Updater = Class.create(Ajax.Request, {
  initialize: function($super, container, url, options) {
    this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    };

    options = options || { };
    var onComplete = options.onComplete;
    options.onComplete = (function(response, param) {
      this.updateContent(response.responseText);
      if (Object.isFunction(onComplete)) onComplete(response, param);
    }).bind(this);

    $super(url, options);
  },

  updateContent: function(responseText) {
    var receiver = this.container[this.success() ? 'success' : 'failure'],
        options = this.options;

    if (!options.evalScripts) responseText = responseText.stripScripts();

    if (receiver = $(receiver)) {
      if (options.insertion) {
        if (Object.isString(options.insertion)) {
          var insertion = { }; insertion[options.insertion] = responseText;
          receiver.insert(insertion);
        }
        else options.insertion(receiver, responseText);
      }
      else receiver.update(responseText);
    }

    if (this.success()) {
      if (this.onComplete) this.onComplete.bind(this).defer();
    }
  }
});

Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
  initialize: function($super, container, url, options) {
    $super(options);
    this.onComplete = this.options.onComplete;

    this.frequency = (this.options.frequency || 2);
    this.decay = (this.options.decay || 1);

    this.updater = { };
    this.container = container;
    this.url = url;

    this.start();
  },

  start: function() {
    this.options.onComplete = this.updateComplete.bind(this);
    this.onTimerEvent();
  },

  stop: function() {
    this.updater.options.onComplete = undefined;
    clearTimeout(this.timer);
    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
  },

  updateComplete: function(response) {
    if (this.options.decay) {
      this.decay = (response.responseText == this.lastText ?
        this.decay * this.options.decay : 1);

      this.lastText = response.responseText;
    }
    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
  },

  onTimerEvent: function() {
    this.updater = new Ajax.Updater(this.container, this.url, this.options);
  }
});
function $(element) {
  if (arguments.length > 1) {
    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
      elements.push($(arguments[i]));
    return elements;
  }
  if (Object.isString(element))
    element = document.getElementById(element);
  return Element.extend(element);
}

if (Prototype.BrowserFeatures.XPath) {
  document._getElementsByXPath = function(expression, parentElement) {
    var results = [];
    var query = document.evaluate(expression, $(parentElement) || document,
      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0, length = query.snapshotLength; i < length; i++)
      results.push(Element.extend(query.snapshotItem(i)));
    return results;
  };
}

/*--------------------------------------------------------------------------*/

if (!window.Node) var Node = { };

if (!Node.ELEMENT_NODE) {
  // DOM level 2 ECMAScript Language Binding
  Object.extend(Node, {
    ELEMENT_NODE: 1,
    ATTRIBUTE_NODE: 2,
    TEXT_NODE: 3,
    CDATA_SECTION_NODE: 4,
    ENTITY_REFERENCE_NODE: 5,
    ENTITY_NODE: 6,
    PROCESSING_INSTRUCTION_NODE: 7,
    COMMENT_NODE: 8,
    DOCUMENT_NODE: 9,
    DOCUMENT_TYPE_NODE: 10,
    DOCUMENT_FRAGMENT_NODE: 11,
    NOTATION_NODE: 12
  });
}

(function() {
  var element = this.Element;
  this.Element = function(tagName, attributes) {
    attributes = attributes || { };
    tagName = tagName.toLowerCase();
    var cache = Element.cache;
    if (Prototype.Browser.IE && attributes.name) {
      tagName = '<' + tagName + ' name="' + attributes.name + '">';
      delete attributes.name;
      return Element.writeAttribute(document.createElement(tagName), attributes);
    }
    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
  };
  Object.extend(this.Element, element || { });
}).call(window);

Element.cache = { };

Element.Methods = {
  visible: function(element) {
    return $(element).style.display != 'none';
  },

  toggle: function(element) {
    element = $(element);
    Element[Element.visible(element) ? 'hide' : 'show'](element);
    return element;
  },

  hide: function(element) {
    $(element).style.display = 'none';
    return element;
  },

  show: function(element) {
    $(element).style.display = '';
    return element;
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
    return element;
  },

  update: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) return element.update().insert(content);
    content = Object.toHTML(content);
    element.innerHTML = content.stripScripts();
    content.evalScripts.bind(content).defer();
    return element;
  },

  replace: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    else if (!Object.isElement(content)) {
      content = Object.toHTML(content);
      var range = element.ownerDocument.createRange();
      range.selectNode(element);
      content.evalScripts.bind(content).defer();
      content = range.createContextualFragment(content.stripScripts());
    }
    element.parentNode.replaceChild(content, element);
    return element;
  },

  insert: function(element, insertions) {
    element = $(element);

    if (Object.isString(insertions) || Object.isNumber(insertions) ||
        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
          insertions = {bottom:insertions};

    var content, t, range;

    for (position in insertions) {
      content  = insertions[position];
      position = position.toLowerCase();
      t = Element._insertionTranslations[position];

      if (content && content.toElement) content = content.toElement();
      if (Object.isElement(content)) {
        t.insert(element, content);
        continue;
      }

      content = Object.toHTML(content);

      range = element.ownerDocument.createRange();
      t.initializeRange(element, range);
      t.insert(element, range.createContextualFragment(content.stripScripts()));

      content.evalScripts.bind(content).defer();
    }

    return element;
  },

  wrap: function(element, wrapper, attributes) {
    element = $(element);
    if (Object.isElement(wrapper))
      $(wrapper).writeAttribute(attributes || { });
    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
    else wrapper = new Element('div', wrapper);
    if (element.parentNode)
      element.parentNode.replaceChild(wrapper, element);
    wrapper.appendChild(element);
    return wrapper;
  },

  inspect: function(element) {
    element = $(element);
    var result = '<' + element.tagName.toLowerCase();
    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
      var property = pair.first(), attribute = pair.last();
      var value = (element[property] || '').toString();
      if (value) result += ' ' + attribute + '=' + value.inspect(true);
    });
    return result + '>';
  },

  recursivelyCollect: function(element, property) {
    element = $(element);
    var elements = [];
    while (element = element[property])
      if (element.nodeType == 1)
        elements.push(Element.extend(element));
    return elements;
  },

  ancestors: function(element) {
    return $(element).recursivelyCollect('parentNode');
  },

  descendants: function(element) {
    return $A($(element).getElementsByTagName('*')).each(Element.extend);
  },

  firstDescendant: function(element) {
    element = $(element).firstChild;
    while (element && element.nodeType != 1) element = element.nextSibling;
    return $(element);
  },

  immediateDescendants: function(element) {
    if (!(element = $(element).firstChild)) return [];
    while (element && element.nodeType != 1) element = element.nextSibling;
    if (element) return [element].concat($(element).nextSiblings());
    return [];
  },

  previousSiblings: function(element) {
    return $(element).recursivelyCollect('previousSibling');
  },

  nextSiblings: function(element) {
    return $(element).recursivelyCollect('nextSibling');
  },

  siblings: function(element) {
    element = $(element);
    return element.previousSiblings().reverse().concat(element.nextSiblings());
  },

  match: function(element, selector) {
    if (Object.isString(selector))
      selector = new Selector(selector);
    return selector.match($(element));
  },

  up: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(element.parentNode);
    var ancestors = element.ancestors();
    return expression ? Selector.findElement(ancestors, expression, index) :
      ancestors[index || 0];
  },

  down: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return element.firstDescendant();
    var descendants = element.descendants();
    return expression ? Selector.findElement(descendants, expression, index) :
      descendants[index || 0];
  },

  previous: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
    var previousSiblings = element.previousSiblings();
    return expression ? Selector.findElement(previousSiblings, expression, index) :
      previousSiblings[index || 0];
  },

  next: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
    var nextSiblings = element.nextSiblings();
    return expression ? Selector.findElement(nextSiblings, expression, index) :
      nextSiblings[index || 0];
  },

  select: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element, args);
  },

  adjacent: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element.parentNode, args).without(element);
  },

  identify: function(element) {
    element = $(element);
    var id = element.readAttribute('id'), self = arguments.callee;
    if (id) return id;
    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
    element.writeAttribute('id', id);
    return id;
  },

  readAttribute: function(element, name) {
    element = $(element);
    if (Prototype.Browser.IE) {
      var t = Element._attributeTranslations.read;
      if (t.values[name]) return t.values[name](element, name);
      if (t.names[name]) name = t.names[name];
      if (name.include(':')) {
        return (!element.attributes || !element.attributes[name]) ? null :
         element.attributes[name].value;
      }
    }
    return element.getAttribute(name);
  },

  writeAttribute: function(element, name, value) {
    element = $(element);
    var attributes = { }, t = Element._attributeTranslations.write;

    if (typeof name == 'object') attributes = name;
    else attributes[name] = value === undefined ? true : value;

    for (var attr in attributes) {
      var name = t.names[attr] || attr, value = attributes[attr];
      if (t.values[attr]) name = t.values[attr](element, value);
      if (value === false || value === null)
        element.removeAttribute(name);
      else if (value === true)
        element.setAttribute(name, name);
      else element.setAttribute(name, value);
    }
    return element;
  },

  getHeight: function(element) {
    return $(element).getDimensions().height;
  },

  getWidth: function(element) {
    return $(element).getDimensions().width;
  },

  classNames: function(element) {
    return new Element.ClassNames(element);
  },

  hasClassName: function(element, className) {
    if (!(element = $(element))) return;
    var elementClassName = element.className;
    return (elementClassName.length > 0 && (elementClassName == className ||
      elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))));
  },

  addClassName: function(element, className) {
    if (!(element = $(element))) return;
    if (!element.hasClassName(className))
      element.className += (element.className ? ' ' : '') + className;
    return element;
  },

  removeClassName: function(element, className) {
    if (!(element = $(element))) return;
    element.className = element.className.replace(
      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
    return element;
  },

  toggleClassName: function(element, className) {
    if (!(element = $(element))) return;
    return element[element.hasClassName(className) ?
      'removeClassName' : 'addClassName'](className);
  },

  // removes whitespace-only text node children
  cleanWhitespace: function(element) {
    element = $(element);
    var node = element.firstChild;
    while (node) {
      var nextNode = node.nextSibling;
      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
        element.removeChild(node);
      node = nextNode;
    }
    return element;
  },

  empty: function(element) {
    return $(element).innerHTML.blank();
  },

  descendantOf: function(element, ancestor) {
    element = $(element), ancestor = $(ancestor);
    while (element = element.parentNode)
      if (element == ancestor) return true;
    return false;
  },

  scrollTo: function(element) {
    element = $(element);
    var pos = element.cumulativeOffset();
    window.scrollTo(pos[0], pos[1]);
    return element;
  },

  getStyle: function(element, style) {
    element = $(element);
    style = style == 'float' ? 'cssFloat' : style.camelize();
    var value = element.style[style];
    if (!value) {
      var css = document.defaultView.getComputedStyle(element, null);
      value = css ? css[style] : null;
    }
    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
    return value == 'auto' ? null : value;
  },

  getOpacity: function(element) {
    return $(element).getStyle('opacity');
  },

  setStyle: function(element, styles) {
    element = $(element);
    var elementStyle = element.style, match;
    if (Object.isString(styles)) {
      element.style.cssText += ';' + styles;
      return styles.include('opacity') ?
        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
    }
    for (var property in styles)
      if (property == 'opacity') element.setOpacity(styles[property]);
      else
        elementStyle[(property == 'float' || property == 'cssFloat') ?
          (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
            property] = styles[property];

    return element;
  },

  setOpacity: function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;
    return element;
  },

  getDimensions: function(element) {
    element = $(element);
    var display = $(element).getStyle('display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = 'block';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      // Opera returns the offset relative to the positioning context, when an
      // element is position relative but top and left have not been defined
      if (window.opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
    return element;
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
    return element;
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return element;
    element._overflow = element.style.overflow || 'auto';
    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
      element.style.overflow = 'hidden';
    return element;
  },

  undoClipping: function(element) {
    element = $(element);
    if (!element._overflow) return element;
    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
    element._overflow = null;
    return element;
  },

  cumulativeOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  positionedOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
      if (element) {
        if (element.tagName == 'BODY') break;
        var p = Element.getStyle(element, 'position');
        if (p == 'relative' || p == 'absolute') break;
      }
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  absolutize: function(element) {
    element = $(element);
    if (element.getStyle('position') == 'absolute') return;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    var offsets = element.positionedOffset();
    var top     = offsets[1];
    var left    = offsets[0];
    var width   = element.clientWidth;
    var height  = element.clientHeight;

    element._originalLeft   = left - parseFloat(element.style.left  || 0);
    element._originalTop    = top  - parseFloat(element.style.top || 0);
    element._originalWidth  = element.style.width;
    element._originalHeight = element.style.height;

    element.style.position = 'absolute';
    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.width  = width + 'px';
    element.style.height = height + 'px';
    return element;
  },

  relativize: function(element) {
    element = $(element);
    if (element.getStyle('position') == 'relative') return;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    element.style.position = 'relative';
    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.height = element._originalHeight;
    element.style.width  = element._originalWidth;
    return element;
  },

  cumulativeScrollOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
      element = element.parentNode;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  getOffsetParent: function(element) {
    if (element.offsetParent) return $(element.offsetParent);
    if (element == document.body) return $(element);

    while ((element = element.parentNode) && element != document.body)
      if (Element.getStyle(element, 'position') != 'static')
        return $(element);

    return $(document.body);
  },

  viewportOffset: function(forElement) {
    var valueT = 0, valueL = 0;

    var element = forElement;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;

      // Safari fix
      if (element.offsetParent == document.body &&
        Element.getStyle(element, 'position') == 'absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
        valueT -= element.scrollTop  || 0;
        valueL -= element.scrollLeft || 0;
      }
    } while (element = element.parentNode);

    return Element._returnOffset(valueL, valueT);
  },

  clonePosition: function(element, source) {
    var options = Object.extend({
      setLeft:    true,
      setTop:     true,
      setWidth:   true,
      setHeight:  true,
      offsetTop:  0,
      offsetLeft: 0
    }, arguments[2] || { });

    // find page position of source
    source = $(source);
    var p = source.viewportOffset();

    // find coordinate system to use
    element = $(element);
    var delta = [0, 0];
    var parent = null;
    // delta [0,0] will do fine with position: fixed elements,
    // position:absolute needs offsetParent deltas
    if (Element.getStyle(element, 'position') == 'absolute') {
      parent = element.getOffsetParent();
      delta = parent.viewportOffset();
    }

    // correct by body offsets (fixes Safari)
    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    // set position
    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
    return element;
  }
};

Element.Methods.identify.counter = 1;

Object.extend(Element.Methods, {
  getElementsBySelector: Element.Methods.select,
  childElements: Element.Methods.immediateDescendants
});

Element._attributeTranslations = {
  write: {
    names: {
      className: 'class',
      htmlFor:   'for'
    },
    values: { }
  }
};


if (!document.createRange || Prototype.Browser.Opera) {
  Element.Methods.insert = function(element, insertions) {
    element = $(element);

    if (Object.isString(insertions) || Object.isNumber(insertions) ||
        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
          insertions = { bottom: insertions };

    var t = Element._insertionTranslations, content, position, pos, tagName;

    for (position in insertions) {
      content  = insertions[position];
      position = position.toLowerCase();
      pos      = t[position];

      if (content && content.toElement) content = content.toElement();
      if (Object.isElement(content)) {
        pos.insert(element, content);
        continue;
      }

      content = Object.toHTML(content);
      tagName = ((position == 'before' || position == 'after')
        ? element.parentNode : element).tagName.toUpperCase();

      if (t.tags[tagName]) {
        var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
        if (position == 'top' || position == 'after') fragments.reverse();
        fragments.each(pos.insert.curry(element));
      }
      else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());

      content.evalScripts.bind(content).defer();
    }

    return element;
  };
}

if (Prototype.Browser.Opera) {
  Element.Methods._getStyle = Element.Methods.getStyle;
  Element.Methods.getStyle = function(element, style) {
    switch(style) {
      case 'left':
      case 'top':
      case 'right':
      case 'bottom':
        if (Element._getStyle(element, 'position') == 'static') return null;
      default: return Element._getStyle(element, style);
    }
  };
  Element.Methods._readAttribute = Element.Methods.readAttribute;
  Element.Methods.readAttribute = function(element, attribute) {
    if (attribute == 'title') return element.title;
    return Element._readAttribute(element, attribute);
  };
}

else if (Prototype.Browser.IE) {
  $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
    Element.Methods[method] = Element.Methods[method].wrap(
      function(proceed, element) {
        element = $(element);
        var position = element.getStyle('position');
        if (position != 'static') return proceed(element);
        element.setStyle({ position: 'relative' });
        var value = proceed(element);
        element.setStyle({ position: position });
        return value;
      }
    );
  });

  Element.Methods.getStyle = function(element, style) {
    element = $(element);
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
    var value = element.style[style];
    if (!value && element.currentStyle) value = element.currentStyle[style];

    if (style == 'opacity') {
      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if (value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }

    if (value == 'auto') {
      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
        return element['offset' + style.capitalize()] + 'px';
      return null;
    }
    return value;
  };

  Element.Methods.setOpacity = function(element, value) {
    function stripAlpha(filter){
      return filter.replace(/alpha\([^\)]*\)/gi,'');
    }
    element = $(element);
    if (!element.currentStyle.hasLayout) element.style.zoom = 1;
    var filter = element.getStyle('filter'), style = element.style;
    if (value == 1 || value === '') {
      (filter = stripAlpha(filter)) ?
        style.filter = filter : style.removeAttribute('filter');
      return element;
    } else if (value < 0.00001) value = 0;
    style.filter = stripAlpha(filter) +
      'alpha(opacity=' + (value * 100) + ')';
    return element;
  };

  Element._attributeTranslations = {
    read: {
      names: {
        'class': 'className',
        'for':   'htmlFor'
      },
      values: {
        _getAttr: function(element, attribute) {
          return element.getAttribute(attribute, 2);
        },
        _getAttrNode: function(element, attribute) {
          var node = element.getAttributeNode(attribute);
          return node ? node.value : "";
        },
        _getEv: function(element, attribute) {
          var attribute = element.getAttribute(attribute);
          return attribute ? attribute.toString().slice(23, -2) : null;
        },
        _flag: function(element, attribute) {
          return $(element).hasAttribute(attribute) ? attribute : null;
        },
        style: function(element) {
          return element.style.cssText.toLowerCase();
        },
        title: function(element) {
          return element.title;
        }
      }
    }
  };

  Element._attributeTranslations.write = {
    names: Object.clone(Element._attributeTranslations.read.names),
    values: {
      checked: function(element, value) {
        element.checked = !!value;
      },

      style: function(element, value) {
        element.style.cssText = value ? value : '';
      }
    }
  };

  Element._attributeTranslations.has = {};

  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
      'encType maxLength readOnly longDesc').each(function(attr) {
    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
  });

  (function(v) {
    Object.extend(v, {
      href:        v._getAttr,
      src:         v._getAttr,
      type:        v._getAttr,
      action:      v._getAttrNode,
      disabled:    v._flag,
      checked:     v._flag,
      readonly:    v._flag,
      multiple:    v._flag,
      onload:      v._getEv,
      onunload:    v._getEv,
      onclick:     v._getEv,
      ondblclick:  v._getEv,
      onmousedown: v._getEv,
      onmouseup:   v._getEv,
      onmouseover: v._getEv,
      onmousemove: v._getEv,
      onmouseout:  v._getEv,
      onfocus:     v._getEv,
      onblur:      v._getEv,
      onkeypress:  v._getEv,
      onkeydown:   v._getEv,
      onkeyup:     v._getEv,
      onsubmit:    v._getEv,
      onreset:     v._getEv,
      onselect:    v._getEv,
      onchange:    v._getEv
    });
  })(Element._attributeTranslations.read.values);
}

else if (Prototype.Browser.Gecko) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :
      (value === '') ? '' : (value < 0.00001) ? 0 : value;
    return element;
  };
}

else if (Prototype.Browser.WebKit) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;

    if (value == 1)
      if(element.tagName == 'IMG' && element.width) {
        element.width++; element.width--;
      } else try {
        var n = document.createTextNode(' ');
        element.appendChild(n);
        element.removeChild(n);
      } catch (e) { }

    return element;
  };

  // Safari returns margins on body which is incorrect if the child is absolutely
  // positioned.  For performance reasons, redefine Position.cumulativeOffset for
  // KHTML/WebKit only.
  Element.Methods.cumulativeOffset = function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      if (element.offsetParent == document.body)
        if (Element.getStyle(element, 'position') == 'absolute') break;

      element = element.offsetParent;
    } while (element);

    return Element._returnOffset(valueL, valueT);
  };
}

if (Prototype.Browser.IE || Prototype.Browser.Opera) {
  // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
  Element.Methods.update = function(element, content) {
    element = $(element);

    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) return element.update().insert(content);

    content = Object.toHTML(content);
    var tagName = element.tagName.toUpperCase();

    if (tagName in Element._insertionTranslations.tags) {
      $A(element.childNodes).each(function(node) { element.removeChild(node) });
      Element._getContentFromAnonymousElement(tagName, content.stripScripts())
        .each(function(node) { element.appendChild(node) });
    }
    else element.innerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

if (document.createElement('div').outerHTML) {
  Element.Methods.replace = function(element, content) {
    element = $(element);

    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) {
      element.parentNode.replaceChild(content, element);
      return element;
    }

    content = Object.toHTML(content);
    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();

    if (Element._insertionTranslations.tags[tagName]) {
      var nextSibling = element.next();
      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
      parent.removeChild(element);
      if (nextSibling)
        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
      else
        fragments.each(function(node) { parent.appendChild(node) });
    }
    else element.outerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

Element._returnOffset = function(l, t) {
  var result = [l, t];
  result.left = l;
  result.top = t;
  return result;
};

Element._getContentFromAnonymousElement = function(tagName, html) {
  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
  div.innerHTML = t[0] + html + t[1];
  t[2].times(function() { div = div.firstChild });
  return $A(div.childNodes);
};

Element._insertionTranslations = {
  before: {
    adjacency: 'beforeBegin',
    insert: function(element, node) {
      element.parentNode.insertBefore(node, element);
    },
    initializeRange: function(element, range) {
      range.setStartBefore(element);
    }
  },
  top: {
    adjacency: 'afterBegin',
    insert: function(element, node) {
      element.insertBefore(node, element.firstChild);
    },
    initializeRange: function(element, range) {
      range.selectNodeContents(element);
      range.collapse(true);
    }
  },
  bottom: {
    adjacency: 'beforeEnd',
    insert: function(element, node) {
      element.appendChild(node);
    }
  },
  after: {
    adjacency: 'afterEnd',
    insert: function(element, node) {
      element.parentNode.insertBefore(node, element.nextSibling);
    },
    initializeRange: function(element, range) {
      range.setStartAfter(element);
    }
  },
  tags: {
    TABLE:  ['<table>',                '</table>',                   1],
    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
    SELECT: ['<select>',               '</select>',                  1]
  }
};

(function() {
  this.bottom.initializeRange = this.top.initializeRange;
  Object.extend(this.tags, {
    THEAD: this.tags.TBODY,
    TFOOT: this.tags.TBODY,
    TH:    this.tags.TD
  });
}).call(Element._insertionTranslations);

Element.Methods.Simulated = {
  hasAttribute: function(element, attribute) {
    attribute = Element._attributeTranslations.has[attribute] || attribute;
    var node = $(element).getAttributeNode(attribute);
    return node && node.specified;
  }
};

Element.Methods.ByTag = { };

Object.extend(Element, Element.Methods);

if (!Prototype.BrowserFeatures.ElementExtensions &&
    document.createElement('div').__proto__) {
  window.HTMLElement = { };
  window.HTMLElement.prototype = document.createElement('div').__proto__;
  Prototype.BrowserFeatures.ElementExtensions = true;
}

Element.extend = (function() {
  if (Prototype.BrowserFeatures.SpecificElementExtensions)
    return Prototype.K;

  var Methods = { }, ByTag = Element.Methods.ByTag;

  var extend = Object.extend(function(element) {
    if (!element || element._extendedByPrototype ||
        element.nodeType != 1 || element == window) return element;

    var methods = Object.clone(Methods),
      tagName = element.tagName, property, value;

    // extend methods for specific tags
    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);

    for (property in methods) {
      value = methods[property];
      if (Object.isFunction(value) && !(property in element))
        element[property] = value.methodize();
    }

    element._extendedByPrototype = Prototype.emptyFunction;
    return element;

  }, {
    refresh: function() {
      // extend methods for all tags (Safari doesn't need this)
      if (!Prototype.BrowserFeatures.ElementExtensions) {
        Object.extend(Methods, Element.Methods);
        Object.extend(Methods, Element.Methods.Simulated);
      }
    }
  });

  extend.refresh();
  return extend;
})();

Element.hasAttribute = function(element, attribute) {
  if (element.hasAttribute) return element.hasAttribute(attribute);
  return Element.Methods.Simulated.hasAttribute(element, attribute);
};

Element.addMethods = function(methods) {
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

  if (!methods) {
    Object.extend(Form, Form.Methods);
    Object.extend(Form.Element, Form.Element.Methods);
    Object.extend(Element.Methods.ByTag, {
      "FORM":     Object.clone(Form.Methods),
      "INPUT":    Object.clone(Form.Element.Methods),
      "SELECT":   Object.clone(Form.Element.Methods),
      "TEXTAREA": Object.clone(Form.Element.Methods)
    });
  }

  if (arguments.length == 2) {
    var tagName = methods;
    methods = arguments[1];
  }

  if (!tagName) Object.extend(Element.Methods, methods || { });
  else {
    if (Object.isArray(tagName)) tagName.each(extend);
    else extend(tagName);
  }

  function extend(tagName) {
    tagName = tagName.toUpperCase();
    if (!Element.Methods.ByTag[tagName])
      Element.Methods.ByTag[tagName] = { };
    Object.extend(Element.Methods.ByTag[tagName], methods);
  }

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    for (var property in methods) {
      var value = methods[property];
      if (!Object.isFunction(value)) continue;
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = value.methodize();
    }
  }

  function findDOMClass(tagName) {
    var klass;
    var trans = {
      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
      "FrameSet", "IFRAME": "IFrame"
    };
    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName.capitalize() + 'Element';
    if (window[klass]) return window[klass];

    window[klass] = { };
    window[klass].prototype = document.createElement(tagName).__proto__;
    return window[klass];
  }

  if (F.ElementExtensions) {
    copy(Element.Methods, HTMLElement.prototype);
    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
  }

  if (F.SpecificElementExtensions) {
    for (var tag in Element.Methods.ByTag) {
      var klass = findDOMClass(tag);
      if (Object.isUndefined(klass)) continue;
      copy(T[tag], klass.prototype);
    }
  }

  Object.extend(Element, Element.Methods);
  delete Element.ByTag;

  if (Element.extend.refresh) Element.extend.refresh();
  Element.cache = { };
};

document.viewport = {
  getDimensions: function() {
    var dimensions = { };
    $w('width height').each(function(d) {
      var D = d.capitalize();
      dimensions[d] = self['inner' + D] ||
       (document.documentElement['client' + D] || document.body['client' + D]);
    });
    return dimensions;
  },

  getWidth: function() {
    return this.getDimensions().width;
  },

  getHeight: function() {
    return this.getDimensions().height;
  },

  getScrollOffsets: function() {
    return Element._returnOffset(
      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
  }
};
/* Portions of the Selector class are derived from Jack Slocumâ€™s DomQuery,
 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
 * license.  Please see http://www.yui-ext.com/ for more information. */

var Selector = Class.create({
  initialize: function(expression) {
    this.expression = expression.strip();
    this.compileMatcher();
  },

  compileMatcher: function() {
    // Selectors with namespaced attributes can't use the XPath version
    if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
      return this.compileXPathMatcher();

    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
        c = Selector.criteria, le, p, m;

    if (Selector._cache[e]) {
      this.matcher = Selector._cache[e];
      return;
    }

    this.matcher = ["this.matcher = function(root) {",
                    "var r = root, h = Selector.handlers, c = false, n;"];

    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
    	      new Template(c[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.matcher.push("return h.unique(n);\n}");
    eval(this.matcher.join('\n'));
    Selector._cache[this.expression] = this.matcher;
  },

  compileXPathMatcher: function() {
    var e = this.expression, ps = Selector.patterns,
        x = Selector.xpath, le, m;

    if (Selector._cache[e]) {
      this.xpath = Selector._cache[e]; return;
    }

    this.matcher = ['.//*'];
    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        if (m = e.match(ps[i])) {
          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
            new Template(x[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.xpath = this.matcher.join('');
    Selector._cache[this.expression] = this.xpath;
  },

  findElements: function(root) {
    root = root || document;
    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
    return this.matcher(root);
  },

  match: function(element) {
    this.tokens = [];

    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
    var le, p, m;

    while (e && le !== e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          // use the Selector.assertions methods unless the selector
          // is too complex.
          if (as[i]) {
            this.tokens.push([i, Object.clone(m)]);
            e = e.replace(m[0], '');
          } else {
            // reluctantly do a document-wide search
            // and look for a match in the array
            return this.findElements(document).include(element);
          }
        }
      }
    }

    var match = true, name, matches;
    for (var i = 0, token; token = this.tokens[i]; i++) {
      name = token[0], matches = token[1];
      if (!Selector.assertions[name](element, matches)) {
        match = false; break;
      }
    }

    return match;
  },

  toString: function() {
    return this.expression;
  },

  inspect: function() {
    return "#<Selector:" + this.expression.inspect() + ">";
  }
});

Object.extend(Selector, {
  _cache: { },

  xpath: {
    descendant:   "//*",
    child:        "/*",
    adjacent:     "/following-sibling::*[1]",
    laterSibling: '/following-sibling::*',
    tagName:      function(m) {
      if (m[1] == '*') return '';
      return "[local-name()='" + m[1].toLowerCase() +
             "' or local-name()='" + m[1].toUpperCase() + "']";
    },
    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
    id:           "[@id='#{1}']",
    attrPresence: "[@#{1}]",
    attr: function(m) {
      m[3] = m[5] || m[6];
      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
    },
    pseudo: function(m) {
      var h = Selector.xpath.pseudos[m[1]];
      if (!h) return '';
      if (Object.isFunction(h)) return h(m);
      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
    },
    operators: {
      '=':  "[@#{1}='#{3}']",
      '!=': "[@#{1}!='#{3}']",
      '^=': "[starts-with(@#{1}, '#{3}')]",
      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
      '*=': "[contains(@#{1}, '#{3}')]",
      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
    },
    pseudos: {
      'first-child': '[not(preceding-sibling::*)]',
      'last-child':  '[not(following-sibling::*)]',
      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
      'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
      'checked':     "[@checked]",
      'disabled':    "[@disabled]",
      'enabled':     "[not(@disabled)]",
      'not': function(m) {
        var e = m[6], p = Selector.patterns,
            x = Selector.xpath, le, m, v;

        var exclusion = [];
        while (e && le != e && (/\S/).test(e)) {
          le = e;
          for (var i in p) {
            if (m = e.match(p[i])) {
              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
              e = e.replace(m[0], '');
              break;
            }
          }
        }
        return "[not(" + exclusion.join(" and ") + ")]";
      },
      'nth-child':      function(m) {
        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
      },
      'nth-last-child': function(m) {
        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
      },
      'nth-of-type':    function(m) {
        return Selector.xpath.pseudos.nth("position() ", m);
      },
      'nth-last-of-type': function(m) {
        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
      },
      'first-of-type':  function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
      },
      'last-of-type':   function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
      },
      'only-of-type':   function(m) {
        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
      },
      nth: function(fragment, m) {
        var mm, formula = m[6], predicate;
        if (formula == 'even') formula = '2n+0';
        if (formula == 'odd')  formula = '2n+1';
        if (mm = formula.match(/^(\d+)$/)) // digit only
          return '[' + fragment + "= " + mm[1] + ']';
        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
          if (mm[1] == "-") mm[1] = -1;
          var a = mm[1] ? Number(mm[1]) : 1;
          var b = mm[2] ? Number(mm[2]) : 0;
          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
          "((#{fragment} - #{b}) div #{a} >= 0)]";
          return new Template(predicate).evaluate({
            fragment: fragment, a: a, b: b });
        }
      }
    }
  },

  criteria: {
    tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
    className:    'n = h.className(n, r, "#{1}", c); c = false;',
    id:           'n = h.id(n, r, "#{1}", c);        c = false;',
    attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
    attr: function(m) {
      m[3] = (m[5] || m[6]);
      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
    },
    pseudo: function(m) {
      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
    },
    descendant:   'c = "descendant";',
    child:        'c = "child";',
    adjacent:     'c = "adjacent";',
    laterSibling: 'c = "laterSibling";'
  },

  patterns: {
    // combinators must be listed first
    // (and descendant needs to be last combinator)
    laterSibling: /^\s*~\s*/,
    child:        /^\s*>\s*/,
    adjacent:     /^\s*\+\s*/,
    descendant:   /^\s/,

    // selectors follow
    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
    id:           /^#([\w\-\*]+)(\b|$)/,
    className:    /^\.([\w\-\*]+)(\b|$)/,
    pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/,
    attrPresence: /^\[([\w]+)\]/,
    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
  },

  // for Selector.match and Element#match
  assertions: {
    tagName: function(element, matches) {
      return matches[1].toUpperCase() == element.tagName.toUpperCase();
    },

    className: function(element, matches) {
      return Element.hasClassName(element, matches[1]);
    },

    id: function(element, matches) {
      return element.id === matches[1];
    },

    attrPresence: function(element, matches) {
      return Element.hasAttribute(element, matches[1]);
    },

    attr: function(element, matches) {
      var nodeValue = Element.readAttribute(element, matches[1]);
      return Selector.operators[matches[2]](nodeValue, matches[3]);
    }
  },

  handlers: {
    // UTILITY FUNCTIONS
    // joins two collections
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        a.push(node);
      return a;
    },

    // marks an array of nodes for counting
    mark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._counted = true;
      return nodes;
    },

    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._counted = undefined;
      return nodes;
    },

    // mark each child node with its position (for nth calls)
    // "ofType" flag indicates whether we're indexing for nth-of-type
    // rather than nth-child
    index: function(parentNode, reverse, ofType) {
      parentNode._counted = true;
      if (reverse) {
        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
          var node = nodes[i];
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
        }
      } else {
        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
      }
    },

    // filters out duplicates and extends all nodes
    unique: function(nodes) {
      if (nodes.length == 0) return nodes;
      var results = [], n;
      for (var i = 0, l = nodes.length; i < l; i++)
        if (!(n = nodes[i])._counted) {
          n._counted = true;
          results.push(Element.extend(n));
        }
      return Selector.handlers.unmark(results);
    },

    // COMBINATOR FUNCTIONS
    descendant: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, node.getElementsByTagName('*'));
      return results;
    },

    child: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
      }
      return results;
    },

    adjacent: function(nodes) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        var next = this.nextElementSibling(node);
        if (next) results.push(next);
      }
      return results;
    },

    laterSibling: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, Element.nextSiblings(node));
      return results;
    },

    nextElementSibling: function(node) {
      while (node = node.nextSibling)
	      if (node.nodeType == 1) return node;
      return null;
    },

    previousElementSibling: function(node) {
      while (node = node.previousSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    // TOKEN FUNCTIONS
    tagName: function(nodes, root, tagName, combinator) {
      tagName = tagName.toUpperCase();
      var results = [], h = Selector.handlers;
      if (nodes) {
        if (combinator) {
          // fastlane for ordinary descendant combinators
          if (combinator == "descendant") {
            for (var i = 0, node; node = nodes[i]; i++)
              h.concat(results, node.getElementsByTagName(tagName));
            return results;
          } else nodes = this[combinator](nodes);
          if (tagName == "*") return nodes;
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.tagName.toUpperCase() == tagName) results.push(node);
        return results;
      } else return root.getElementsByTagName(tagName);
    },

    id: function(nodes, root, id, combinator) {
      var targetNode = $(id), h = Selector.handlers;
      if (!targetNode) return [];
      if (!nodes && root == document) return [targetNode];
      if (nodes) {
        if (combinator) {
          if (combinator == 'child') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (targetNode.parentNode == node) return [targetNode];
          } else if (combinator == 'descendant') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Element.descendantOf(targetNode, node)) return [targetNode];
          } else if (combinator == 'adjacent') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Selector.handlers.previousElementSibling(targetNode) == node)
                return [targetNode];
          } else nodes = h[combinator](nodes);
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node == targetNode) return [targetNode];
        return [];
      }
      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
    },

    className: function(nodes, root, className, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      return Selector.handlers.byClassName(nodes, root, className);
    },

    byClassName: function(nodes, root, className) {
      if (!nodes) nodes = Selector.handlers.descendant([root]);
      var needle = ' ' + className + ' ';
      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
        nodeClassName = node.className;
        if (nodeClassName.length == 0) continue;
        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
          results.push(node);
      }
      return results;
    },

    attrPresence: function(nodes, root, attr) {
      var results = [];
      for (var i = 0, node; node = nodes[i]; i++)
        if (Element.hasAttribute(node, attr)) results.push(node);
      return results;
    },

    attr: function(nodes, root, attr, value, operator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      var handler = Selector.operators[operator], results = [];
      for (var i = 0, node; node = nodes[i]; i++) {
        var nodeValue = Element.readAttribute(node, attr);
        if (nodeValue === null) continue;
        if (handler(nodeValue, value)) results.push(node);
      }
      return results;
    },

    pseudo: function(nodes, name, value, root, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      if (!nodes) nodes = root.getElementsByTagName("*");
      return Selector.pseudos[name](nodes, value, root);
    }
  },

  pseudos: {
    'first-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.previousElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'last-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.nextElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'only-child': function(nodes, value, root) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
          results.push(node);
      return results;
    },
    'nth-child':        function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root);
    },
    'nth-last-child':   function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true);
    },
    'nth-of-type':      function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, false, true);
    },
    'nth-last-of-type': function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true, true);
    },
    'first-of-type':    function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, false, true);
    },
    'last-of-type':     function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, true, true);
    },
    'only-of-type':     function(nodes, formula, root) {
      var p = Selector.pseudos;
      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
    },

    // handles the an+b logic
    getIndices: function(a, b, total) {
      if (a == 0) return b > 0 ? [b] : [];
      return $R(1, total).inject([], function(memo, i) {
        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
        return memo;
      });
    },

    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
    nth: function(nodes, formula, root, reverse, ofType) {
      if (nodes.length == 0) return [];
      if (formula == 'even') formula = '2n+0';
      if (formula == 'odd')  formula = '2n+1';
      var h = Selector.handlers, results = [], indexed = [], m;
      h.mark(nodes);
      for (var i = 0, node; node = nodes[i]; i++) {
        if (!node.parentNode._counted) {
          h.index(node.parentNode, reverse, ofType);
          indexed.push(node.parentNode);
        }
      }
      if (formula.match(/^\d+$/)) { // just a number
        formula = Number(formula);
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.nodeIndex == formula) results.push(node);
      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
        if (m[1] == "-") m[1] = -1;
        var a = m[1] ? Number(m[1]) : 1;
        var b = m[2] ? Number(m[2]) : 0;
        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
          for (var j = 0; j < l; j++)
            if (node.nodeIndex == indices[j]) results.push(node);
        }
      }
      h.unmark(nodes);
      h.unmark(indexed);
      return results;
    },

    'empty': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        // IE treats comments as element nodes
        if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
        results.push(node);
      }
      return results;
    },

    'not': function(nodes, selector, root) {
      var h = Selector.handlers, selectorType, m;
      var exclusions = new Selector(selector).findElements(root);
      h.mark(exclusions);
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node._counted) results.push(node);
      h.unmark(exclusions);
      return results;
    },

    'enabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node.disabled) results.push(node);
      return results;
    },

    'disabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.disabled) results.push(node);
      return results;
    },

    'checked': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.checked) results.push(node);
      return results;
    }
  },

  operators: {
    '=':  function(nv, v) { return nv == v; },
    '!=': function(nv, v) { return nv != v; },
    '^=': function(nv, v) { return nv.startsWith(v); },
    '$=': function(nv, v) { return nv.endsWith(v); },
    '*=': function(nv, v) { return nv.include(v); },
    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
    '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
  },

  matchElements: function(elements, expression) {
    var matches = new Selector(expression).findElements(), h = Selector.handlers;
    h.mark(matches);
    for (var i = 0, results = [], element; element = elements[i]; i++)
      if (element._counted) results.push(element);
    h.unmark(matches);
    return results;
  },

  findElement: function(elements, expression, index) {
    if (Object.isNumber(expression)) {
      index = expression; expression = false;
    }
    return Selector.matchElements(elements, expression || '*')[index || 0];
  },

  findChildElements: function(element, expressions) {
    var exprs = expressions.join(','), expressions = [];
    exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
      expressions.push(m[1].strip());
    });
    var results = [], h = Selector.handlers;
    for (var i = 0, l = expressions.length, selector; i < l; i++) {
      selector = new Selector(expressions[i].strip());
      h.concat(results, selector.findElements(element));
    }
    return (l > 1) ? h.unique(results) : results;
  }
});

function $$() {
  return Selector.findChildElements(document, $A(arguments));
}
var Form = {
  reset: function(form) {
    $(form).reset();
    return form;
  },

  serializeElements: function(elements, options) {
    if (typeof options != 'object') options = { hash: !!options };
    else if (options.hash === undefined) options.hash = true;
    var key, value, submitted = false, submit = options.submit;

    var data = elements.inject({ }, function(result, element) {
      if (!element.disabled && element.name) {
        key = element.name; value = $(element).getValue();
        if (value != null && (element.type != 'submit' || (!submitted &&
            submit !== false && (!submit || key == submit) && (submitted = true)))) {
          if (key in result) {
            // a key is already present; construct an array of values
            if (!Object.isArray(result[key])) result[key] = [result[key]];
            result[key].push(value);
          }
          else result[key] = value;
        }
      }
      return result;
    });

    return options.hash ? data : Hash.toQueryString(data);
  }
};

Form.Methods = {
  serialize: function(form, options) {
    return Form.serializeElements(Form.getElements(form), options);
  },

  getElements: function(form) {
    return $A($(form).getElementsByTagName('*')).inject([],
      function(elements, child) {
        if (Form.Element.Serializers[child.tagName.toLowerCase()])
          elements.push(Element.extend(child));
        return elements;
      }
    );
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name) return $A(inputs).map(Element.extend);

    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) || (name && input.name != name))
        continue;
      matchingInputs.push(Element.extend(input));
    }

    return matchingInputs;
  },

  disable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('disable');
    return form;
  },

  enable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('enable');
    return form;
  },

  findFirstElement: function(form) {
    var elements = $(form).getElements().findAll(function(element) {
      return 'hidden' != element.type && !element.disabled;
    });
    var firstByIndex = elements.findAll(function(element) {
      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
    }).sortBy(function(element) { return element.tabIndex }).first();

    return firstByIndex ? firstByIndex : elements.find(function(element) {
      return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    form.findFirstElement().activate();
    return form;
  },

  request: function(form, options) {
    form = $(form), options = Object.clone(options || { });

    var params = options.parameters, action = form.readAttribute('action') || '';
    if (action.blank()) action = window.location.href;
    options.parameters = form.serialize(true);

    if (params) {
      if (Object.isString(params)) params = params.toQueryParams();
      Object.extend(options.parameters, params);
    }

    if (form.hasAttribute('method') && !options.method)
      options.method = form.method;

    return new Ajax.Request(action, options);
  }
};

/*--------------------------------------------------------------------------*/

Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
};

Form.Element.Methods = {
  serialize: function(element) {
    element = $(element);
    if (!element.disabled && element.name) {
      var value = element.getValue();
      if (value != undefined) {
        var pair = { };
        pair[element.name] = value;
        return Hash.toQueryString(pair);
      }
    }
    return '';
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    return Form.Element.Serializers[method](element);
  },

  setValue: function(element, value) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    Form.Element.Serializers[method](element, value);
    return element;
  },

  clear: function(element) {
    $(element).value = '';
    return element;
  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    try {
      element.focus();
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
          !['button', 'reset', 'submit'].include(element.type)))
        element.select();
    } catch (e) { }
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.blur();
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.disabled = false;
    return element;
  }
};

/*--------------------------------------------------------------------------*/

var Field = Form.Element;
var $F = Form.Element.Methods.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
  input: function(element, value) {
    switch (element.type.toLowerCase()) {
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element, value);
      default:
        return Form.Element.Serializers.textarea(element, value);
    }
  },

  inputSelector: function(element, value) {
    if (value === undefined) return element.checked ? element.value : null;
    else element.checked = !!value;
  },

  textarea: function(element, value) {
    if (value === undefined) return element.value;
    else element.value = value;
  },

  select: function(element, index) {
    if (index === undefined)
      return this[element.type == 'select-one' ?
        'selectOne' : 'selectMany'](element);
    else {
      var opt, value, single = !Object.isArray(index);
      for (var i = 0, length = element.length; i < length; i++) {
        opt = element.options[i];
        value = this.optionValue(opt);
        if (single) {
          if (value == index) {
            opt.selected = true;
            return;
          }
        }
        else opt.selected = index.include(value);
      }
    }
  },

  selectOne: function(element) {
    var index = element.selectedIndex;
    return index >= 0 ? this.optionValue(element.options[index]) : null;
  },

  selectMany: function(element) {
    var values, length = element.length;
    if (!length) return null;

    for (var i = 0, values = []; i < length; i++) {
      var opt = element.options[i];
      if (opt.selected) values.push(this.optionValue(opt));
    }
    return values;
  },

  optionValue: function(opt) {
    // extend element because hasAttribute may not be native
    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
  }
};

/*--------------------------------------------------------------------------*/

Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
  initialize: function($super, element, frequency, callback) {
    $super(callback, frequency);
    this.element   = $(element);
    this.lastValue = this.getValue();
  },

  execute: function() {
    var value = this.getValue();
    if (Object.isString(this.lastValue) && Object.isString(value) ?
        this.lastValue != value : String(this.lastValue) != String(value)) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  }
});

Form.Element.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});

/*--------------------------------------------------------------------------*/

Abstract.EventObserver = Class.create({
  initialize: function(element, callback) {
    this.element  = $(element);
    this.callback = callback;

    this.lastValue = this.getValue();
    if (this.element.tagName.toLowerCase() == 'form')
      this.registerFormCallbacks();
    else
      this.registerCallback(this.element);
  },

  onElementEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  },

  registerFormCallbacks: function() {
    Form.getElements(this.element).each(this.registerCallback, this);
  },

  registerCallback: function(element) {
    if (element.type) {
      switch (element.type.toLowerCase()) {
        case 'checkbox':
        case 'radio':
          Event.observe(element, 'click', this.onElementEvent.bind(this));
          break;
        default:
          Event.observe(element, 'change', this.onElementEvent.bind(this));
          break;
      }
    }
  }
});

Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});
if (!window.Event) var Event = { };

Object.extend(Event, {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,
  KEY_HOME:     36,
  KEY_END:      35,
  KEY_PAGEUP:   33,
  KEY_PAGEDOWN: 34,
  KEY_INSERT:   45,

  cache: { },

  relatedTarget: function(event) {
    var element;
    switch(event.type) {
      case 'mouseover': element = event.fromElement; break;
      case 'mouseout':  element = event.toElement;   break;
      default: return null;
    }
    return Element.extend(element);
  }
});

Event.Methods = {
  element: function(event) {
    var node = event.target;
    return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
  },

  findElement: function(event, expression) {
    var element = Event.element(event);
    return element.match(expression) ? element : element.up(expression);
  },

  isLeftClick: function(event) {
    return (((event.which) && (event.which == 1)) ||
            ((event.button) && (event.button == 1)));
  },

  pointer: function(event) {
    return {
      x: event.pageX || (event.clientX +
        (document.documentElement.scrollLeft || document.body.scrollLeft)),
      y: event.pageY || (event.clientY +
        (document.documentElement.scrollTop || document.body.scrollTop))
    };
  },

  pointerX: function(event) { return Event.pointer(event).x },
  pointerY: function(event) { return Event.pointer(event).y },

  stop: function(event) {
    event.preventDefault();
    event.stopPropagation();
  }
};

Event.extend = (function() {
  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
    m[name] = Event.Methods[name].methodize();
    return m;
  });

  if (Prototype.Browser.IE) {
    Object.extend(methods, {
      stopPropagation: function() { this.cancelBubble = true },
      preventDefault:  function() { this.returnValue = false },
      inspect: function() { return "[object Event]" }
    });

    return function(event) {
      if (!event) return false;
      if (event._extendedByPrototype) return event;

      event._extendedByPrototype = Prototype.emptyFunction;
      var pointer = Event.pointer(event);
      Object.extend(event, {
        target: event.srcElement,
        relatedTarget: Event.relatedTarget(event),
        pageX:  pointer.x,
        pageY:  pointer.y
      });
      return Object.extend(event, methods);
    };

  } else {
    Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
    Object.extend(Event.prototype, methods);
    return Prototype.K;
  }
})();

Object.extend(Event, (function() {
  var cache = Event.cache;

  function getEventID(element) {
    if (element._eventID) return element._eventID;
    arguments.callee.id = arguments.callee.id || 1;
    return element._eventID = ++arguments.callee.id;
  }

  function getDOMEventName(eventName) {
    if (eventName && eventName.match(/:/)) return "dataavailable";
    return { keypress: "keydown" }[eventName] || eventName;
  }

  function getCacheForID(id) {
    return cache[id] = cache[id] || { };
  }

  function getWrappersForEventName(id, eventName) {
    var c = getCacheForID(id);
    return c[eventName] = c[eventName] || [];
  }

  function createWrapper(element, eventName, handler) {
    var id = getEventID(element);
    var c = getWrappersForEventName(id, eventName);
    if (c.pluck("handler").include(handler)) return false;

    var wrapper = function(event) {
      if (event.eventName && event.eventName != eventName)
        return false;

      Event.extend(event);
      handler.call(element, event)
    };

    wrapper.handler = handler;
    c.push(wrapper);
    return wrapper;
  }

  function findWrapper(id, eventName, handler) {
    var c = getWrappersForEventName(id, eventName);
    return c.find(function(wrapper) { return wrapper.handler == handler });
  }

  function destroyWrapper(id, eventName, handler) {
    var c = getCacheForID(id);
    if (!c[eventName]) return false;
    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
  }

  function destroyCache() {
    for (var id in cache)
      for (var eventName in cache[id])
        cache[id][eventName] = null;
  }

  if (window.attachEvent) {
    window.attachEvent("onunload", destroyCache);
  }

  return {
    observe: function(element, eventName, handler) {
      element = $(element);
      var name = getDOMEventName(eventName);

      var wrapper = createWrapper(element, eventName, handler);
      if (!wrapper) return element;

      if (element.addEventListener) {
        element.addEventListener(name, wrapper, false);
      } else {
        element.attachEvent("on" + name, wrapper);
      }

      return element;
    },

    stopObserving: function(element, eventName, handler) {
      element = $(element);
      var id = getEventID(element), name = getDOMEventName(eventName);

      if (!handler && eventName) {
        getWrappersForEventName(id, eventName).each(function(wrapper) {
          element.stopObserving(eventName, wrapper.handler);
        });
        return element;

      } else if (!eventName) {
        Object.keys(getCacheForID(id)).each(function(eventName) {
          element.stopObserving(eventName);
        });
        return element;
      }

      var wrapper = findWrapper(id, eventName, handler);
      if (!wrapper) return element;

      if (element.removeEventListener) {
        element.removeEventListener(name, wrapper, false);
      } else {
        element.detachEvent("on" + name, wrapper);
      }

      destroyWrapper(id, eventName, handler);

      return element;
    },

    fire: function(element, eventName, memo) {
      element = $(element);
      if (element == document && document.createEvent && !element.dispatchEvent)
        element = document.documentElement;

      if (document.createEvent) {
        var event = document.createEvent("HTMLEvents");
        event.initEvent("dataavailable", true, true);
      } else {
        var event = document.createEventObject();
        event.eventType = "ondataavailable";
      }

      event.eventName = eventName;
      event.memo = memo || { };

      if (document.createEvent) {
        element.dispatchEvent(event);
      } else {
        element.fireEvent(event.eventType, event);
      }

      return event;
    }
  };
})());

Object.extend(Event, Event.Methods);

Element.addMethods({
  fire:          Event.fire,
  observe:       Event.observe,
  stopObserving: Event.stopObserving
});

Object.extend(document, {
  fire:          Element.Methods.fire.methodize(),
  observe:       Element.Methods.observe.methodize(),
  stopObserving: Element.Methods.stopObserving.methodize()
});

(function() {
  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
     Matthias Miller, Dean Edwards and John Resig. */

  var timer, fired = false;

  function fireContentLoadedEvent() {
    if (fired) return;
    if (timer) window.clearInterval(timer);
    document.fire("dom:loaded");
    fired = true;
  }

  if (document.addEventListener) {
    if (Prototype.Browser.WebKit) {
      timer = window.setInterval(function() {
        if (/loaded|complete/.test(document.readyState))
          fireContentLoadedEvent();
      }, 0);

      Event.observe(window, "load", fireContentLoadedEvent);

    } else {
      document.addEventListener("DOMContentLoaded",
        fireContentLoadedEvent, false);
    }

  } else {
    document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
    $("__onDOMContentLoaded").onreadystatechange = function() {
      if (this.readyState == "complete") {
        this.onreadystatechange = null;
        fireContentLoadedEvent();
      }
    };
  }
})();
/*------------------------------- DEPRECATED -------------------------------*/

var Toggle = { display: Element.toggle };

Element.Methods.childOf = Element.Methods.descendantOf;

var Insertion = {
  Before: function(element, content) {
    return Element.insert(element, {before:content});
  },

  Top: function(element, content) {
    return Element.insert(element, {top:content});
  },

  Bottom: function(element, content) {
    return Element.insert(element, {bottom:content});
  },

  After: function(element, content) {
    return Element.insert(element, {after:content});
  }
};

var $continue = new Error('"throw $continue" is deprecated, use "return" instead');

// This should be moved to script.aculo.us; notice the deprecated methods
// further below, that map to the newer Element methods.
var Position = {
  // set to true if needed, warning: firefox performance problems
  // NOT neeeded for page scrolling, only if draggable contained in
  // scrollable elements
  includeScrollOffsets: false,

  // must be called before calling withinIncludingScrolloffset, every time the
  // page is scrolled
  prepare: function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  },

  // caches x/y coordinate pair to use with overlap
  within: function(element, x, y) {
    if (this.includeScrollOffsets)
      return this.withinIncludingScrolloffsets(element, x, y);
    this.xcomp = x;
    this.ycomp = y;
    this.offset = Element.cumulativeOffset(element);

    return (y >= this.offset[1] &&
            y <  this.offset[1] + element.offsetHeight &&
            x >= this.offset[0] &&
            x <  this.offset[0] + element.offsetWidth);
  },

  withinIncludingScrolloffsets: function(element, x, y) {
    var offsetcache = Element.cumulativeScrollOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;
    this.ycomp = y + offsetcache[1] - this.deltaY;
    this.offset = Element.cumulativeOffset(element);

    return (this.ycomp >= this.offset[1] &&
            this.ycomp <  this.offset[1] + element.offsetHeight &&
            this.xcomp >= this.offset[0] &&
            this.xcomp <  this.offset[0] + element.offsetWidth);
  },

  // within must be called directly before
  overlap: function(mode, element) {
    if (!mode) return 0;
    if (mode == 'vertical')
      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
        element.offsetHeight;
    if (mode == 'horizontal')
      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
        element.offsetWidth;
  },

  // Deprecation layer -- use newer Element methods now (1.5.2).

  cumulativeOffset: Element.Methods.cumulativeOffset,

  positionedOffset: Element.Methods.positionedOffset,

  absolutize: function(element) {
    Position.prepare();
    return Element.absolutize(element);
  },

  relativize: function(element) {
    Position.prepare();
    return Element.relativize(element);
  },

  realOffset: Element.Methods.cumulativeScrollOffset,

  offsetParent: Element.Methods.getOffsetParent,

  page: Element.Methods.viewportOffset,

  clone: function(source, target, options) {
    options = options || { };
    return Element.clonePosition(target, source, options);
  }
};

/*--------------------------------------------------------------------------*/

if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
  function iter(name) {
    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
  }

  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
  function(element, className) {
    className = className.toString().strip();
    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
  } : function(element, className) {
    className = className.toString().strip();
    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
    if (!classNames && !className) return elements;

    var nodes = $(element).getElementsByTagName('*');
    className = ' ' + className + ' ';

    for (var i = 0, child, cn; child = nodes[i]; i++) {
      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
          (classNames && classNames.all(function(name) {
            return !name.toString().blank() && cn.include(' ' + name + ' ');
          }))))
        elements.push(Element.extend(child));
    }
    return elements;
  };

  return function(className, parentElement) {
    return $(parentElement || document.body).getElementsByClassName(className);
  };
}(Element.Methods);

/*--------------------------------------------------------------------------*/

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
  initialize: function(element) {
    this.element = $(element);
  },

  _each: function(iterator) {
    this.element.className.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
  },

  set: function(className) {
    this.element.className = className;
  },

  add: function(classNameToAdd) {
    if (this.include(classNameToAdd)) return;
    this.set($A(this).concat(classNameToAdd).join(' '));
  },

  remove: function(classNameToRemove) {
    if (!this.include(classNameToRemove)) return;
    this.set($A(this).without(classNameToRemove).join(' '));
  },

  toString: function() {
    return $A(this).join(' ');
  }
};

Object.extend(Element.ClassNames.prototype, Enumerable);

/*--------------------------------------------------------------------------*/

Element.addMethods();// script.aculo.us effects.js v1.8.0_pre1, Fri Oct 12 21:34:51 +0200 2007

// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
//  Justin Palmer (http://encytemedia.com/)
//  Mark Pilgrim (http://diveintomark.org/)
//  Martin Bialasinki
// 
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ 

// converts rgb() and #xxx to #xxxxxx format,  
// returns self (or first argument) if not convertable  
String.prototype.parseColor = function() {  
  var color = '#';
  if (this.slice(0,4) == 'rgb(') {  
    var cols = this.slice(4,this.length-1).split(',');  
    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);  
  } else {  
    if (this.slice(0,1) == '#') {  
      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();  
      if (this.length==7) color = this.toLowerCase();  
    }  
  }  
  return (color.length==7 ? color : (arguments[0] || this));  
};

/*--------------------------------------------------------------------------*/

Element.collectTextNodes = function(element) {  
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue : 
      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
  }).flatten().join('');
};

Element.collectTextNodesIgnoreClass = function(element, className) {  
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue : 
      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 
        Element.collectTextNodesIgnoreClass(node, className) : ''));
  }).flatten().join('');
};

Element.setContentZoom = function(element, percent) {
  element = $(element);  
  element.setStyle({fontSize: (percent/100) + 'em'});   
  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
  return element;
};

Element.getInlineOpacity = function(element){
  return $(element).style.opacity || '';
};

Element.forceRerendering = function(element) {
  try {
    element = $(element);
    var n = document.createTextNode(' ');
    element.appendChild(n);
    element.removeChild(n);
  } catch(e) { }
};

/*--------------------------------------------------------------------------*/

var Effect = {
  _elementDoesNotExistError: {
    name: 'ElementDoesNotExistError',
    message: 'The specified DOM element does not exist, but is required for this effect to operate'
  },
  Transitions: {
    linear: Prototype.K,
    sinoidal: function(pos) {
      return (-Math.cos(pos*Math.PI)/2) + 0.5;
    },
    reverse: function(pos) {
      return 1-pos;
    },
    flicker: function(pos) {
      var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
      return pos > 1 ? 1 : pos;
    },
    wobble: function(pos) {
      return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
    },
    pulse: function(pos, pulses) { 
      pulses = pulses || 5; 
      return (
        ((pos % (1/pulses)) * pulses).round() == 0 ? 
              ((pos * pulses * 2) - (pos * pulses * 2).floor()) : 
          1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
        );
    },
    spring: function(pos) { 
      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); 
    },
    none: function(pos) {
      return 0;
    },
    full: function(pos) {
      return 1;
    }
  },
  DefaultOptions: {
    duration:   1.0,   // seconds
    fps:        100,   // 100= assume 66fps max.
    sync:       false, // true for combining
    from:       0.0,
    to:         1.0,
    delay:      0.0,
    queue:      'parallel'
  },
  tagifyText: function(element) {
    var tagifyStyle = 'position:relative';
    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
    
    element = $(element);
    $A(element.childNodes).each( function(child) {
      if (child.nodeType==3) {
        child.nodeValue.toArray().each( function(character) {
          element.insertBefore(
            new Element('span', {style: tagifyStyle}).update(
              character == ' ' ? String.fromCharCode(160) : character), 
              child);
        });
        Element.remove(child);
      }
    });
  },
  multiple: function(element, effect) {
    var elements;
    if (((typeof element == 'object') || 
        Object.isFunction(element)) && 
       (element.length))
      elements = element;
    else
      elements = $(element).childNodes;
      
    var options = Object.extend({
      speed: 0.1,
      delay: 0.0
    }, arguments[2] || { });
    var masterDelay = options.delay;

    $A(elements).each( function(element, index) {
      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
    });
  },
  PAIRS: {
    'slide':  ['SlideDown','SlideUp'],
    'blind':  ['BlindDown','BlindUp'],
    'appear': ['Appear','Fade']
  },
  toggle: function(element, effect) {
    element = $(element);
    effect = (effect || 'appear').toLowerCase();
    var options = Object.extend({
      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
    }, arguments[2] || { });
    Effect[element.visible() ? 
      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
  }
};

Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;

/* ------------- core effects ------------- */

Effect.ScopedQueue = Class.create(Enumerable, {
  initialize: function() {
    this.effects  = [];
    this.interval = null;    
  },
  _each: function(iterator) {
    this.effects._each(iterator);
  },
  add: function(effect) {
    var timestamp = new Date().getTime();
    
    var position = Object.isString(effect.options.queue) ? 
      effect.options.queue : effect.options.queue.position;
    
    switch(position) {
      case 'front':
        // move unstarted effects after this effect  
        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
            e.startOn  += effect.finishOn;
            e.finishOn += effect.finishOn;
          });
        break;
      case 'with-last':
        timestamp = this.effects.pluck('startOn').max() || timestamp;
        break;
      case 'end':
        // start effect after last queued effect has finished
        timestamp = this.effects.pluck('finishOn').max() || timestamp;
        break;
    }
    
    effect.startOn  += timestamp;
    effect.finishOn += timestamp;

    if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
      this.effects.push(effect);
    
    if (!this.interval)
      this.interval = setInterval(this.loop.bind(this), 15);
  },
  remove: function(effect) {
    this.effects = this.effects.reject(function(e) { return e==effect });
    if (this.effects.length == 0) {
      clearInterval(this.interval);
      this.interval = null;
    }
  },
  loop: function() {
    var timePos = new Date().getTime();
    for(var i=0, len=this.effects.length;i<len;i++) 
      this.effects[i] && this.effects[i].loop(timePos);
  }
});

Effect.Queues = {
  instances: $H(),
  get: function(queueName) {
    if (!Object.isString(queueName)) return queueName;
    
    if (!this.instances[queueName])
      this.instances[queueName] = new Effect.ScopedQueue();
      
    return this.instances[queueName];
  }
};
Effect.Queue = Effect.Queues.get('global');

Effect.Base = Class.create();
Effect.Base.prototype = {
  position: null,
  start: function(options) {
    function codeForEvent(options,eventName){
      return (
        (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
        (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
      );
    }
    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
    this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
    this.currentFrame = 0;
    this.state        = 'idle';
    this.startOn      = this.options.delay*1000;
    this.finishOn     = this.startOn+(this.options.duration*1000);
    this.fromToDelta  = this.options.to-this.options.from;
    this.totalTime    = this.finishOn-this.startOn;
    this.totalFrames  = this.options.fps*this.options.duration;
    
    eval('this.render = function(pos){ '+
      'if (this.state=="idle"){this.state="running";'+
      codeForEvent(this.options,'beforeSetup')+
      (this.setup ? 'this.setup();':'')+ 
      codeForEvent(this.options,'afterSetup')+
      '};if (this.state=="running"){'+
      'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
      'this.position=pos;'+
      codeForEvent(this.options,'beforeUpdate')+
      (this.update ? 'this.update(pos);':'')+
      codeForEvent(this.options,'afterUpdate')+
      '}}');
    
    this.event('beforeStart');
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ? 
        'global' : this.options.queue.scope).add(this);
  },
  loop: function(timePos) {
    if (timePos >= this.startOn) {
      if (timePos >= this.finishOn) {
        this.render(1.0);
        this.cancel();
        this.event('beforeFinish');
        if (this.finish) this.finish(); 
        this.event('afterFinish');
        return;  
      }
      var pos   = (timePos - this.startOn) / this.totalTime,
          frame = (pos * this.totalFrames).round();
      if (frame > this.currentFrame) {
        this.render(pos);
        this.currentFrame = frame;
      }
    }
  },
  cancel: function() {
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ? 
        'global' : this.options.queue.scope).remove(this);
    this.state = 'finished';
  },
  event: function(eventName) {
    if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
    if (this.options[eventName]) this.options[eventName](this);
  },
  inspect: function() {
    var data = $H();
    for(property in this)
      if (!Object.isFunction(this[property])) data[property] = this[property];
    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
  }
};

Effect.Parallel = Class.create(Effect.Base, {
  initialize: function(effects) {
    this.effects = effects || [];
    this.start(arguments[1]);
  },
  update: function(position) {
    this.effects.invoke('render', position);
  },
  finish: function(position) {
    this.effects.each( function(effect) {
      effect.render(1.0);
      effect.cancel();
      effect.event('beforeFinish');
      if (effect.finish) effect.finish(position);
      effect.event('afterFinish');
    });
  }
});

Effect.Tween = Class.create(Effect.Base, {
  initialize: function(object, from, to) {
    object = Object.isString(object) ? $(object) : object;
    var args = $A(arguments), method = args.last(), 
      options = args.length == 5 ? args[3] : null;
    this.method = Object.isFunction(method) ? method.bind(object) :
      Object.isFunction(object[method]) ? object[method].bind(object) : 
      function(value) { object[method] = value };
    this.start(Object.extend({ from: from, to: to }, options || { }));
  },
  update: function(position) {
    this.method(position);
  }
});

Effect.Event = Class.create(Effect.Base, {
  initialize: function() {
    this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
  },
  update: Prototype.emptyFunction
});

Effect.Opacity = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    // make this work on IE on elements without 'layout'
    if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
      this.element.setStyle({zoom: 1});
    var options = Object.extend({
      from: this.element.getOpacity() || 0.0,
      to:   1.0
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(position) {
    this.element.setOpacity(position);
  }
});

Effect.Move = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'relative'
    }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    this.element.makePositioned();
    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
    if (this.options.mode == 'absolute') {
      this.options.x = this.options.x - this.originalLeft;
      this.options.y = this.options.y - this.originalTop;
    }
  },
  update: function(position) {
    this.element.setStyle({
      left: (this.options.x  * position + this.originalLeft).round() + 'px',
      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
    });
  }
});

// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
  return new Effect.Move(element, 
    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};

Effect.Scale = Class.create(Effect.Base, {
  initialize: function(element, percent) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      scaleX: true,
      scaleY: true,
      scaleContent: true,
      scaleFromCenter: false,
      scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
      scaleFrom: 100.0,
      scaleTo:   percent
    }, arguments[2] || { });
    this.start(options);
  },
  setup: function() {
    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
    this.elementPositioning = this.element.getStyle('position');
    
    this.originalStyle = { };
    ['top','left','width','height','fontSize'].each( function(k) {
      this.originalStyle[k] = this.element.style[k];
    }.bind(this));
      
    this.originalTop  = this.element.offsetTop;
    this.originalLeft = this.element.offsetLeft;
    
    var fontSize = this.element.getStyle('font-size') || '100%';
    ['em','px','%','pt'].each( function(fontSizeType) {
      if (fontSize.indexOf(fontSizeType)>0) {
        this.fontSize     = parseFloat(fontSize);
        this.fontSizeType = fontSizeType;
      }
    }.bind(this));
    
    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
    
    this.dims = null;
    if (this.options.scaleMode=='box')
      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
    if (/^content/.test(this.options.scaleMode))
      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
    if (!this.dims)
      this.dims = [this.options.scaleMode.originalHeight,
                   this.options.scaleMode.originalWidth];
  },
  update: function(position) {
    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
    if (this.options.scaleContent && this.fontSize)
      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
  },
  finish: function(position) {
    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
  },
  setDimensions: function(height, width) {
    var d = { };
    if (this.options.scaleX) d.width = width.round() + 'px';
    if (this.options.scaleY) d.height = height.round() + 'px';
    if (this.options.scaleFromCenter) {
      var topd  = (height - this.dims[0])/2;
      var leftd = (width  - this.dims[1])/2;
      if (this.elementPositioning == 'absolute') {
        if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
        if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
      } else {
        if (this.options.scaleY) d.top = -topd + 'px';
        if (this.options.scaleX) d.left = -leftd + 'px';
      }
    }
    this.element.setStyle(d);
  }
});

Effect.Highlight = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    // Prevent executing on elements not in the layout flow
    if (this.element.getStyle('display')=='none') { this.cancel(); return; }
    // Disable background image during the effect
    this.oldStyle = { };
    if (!this.options.keepBackgroundImage) {
      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
      this.element.setStyle({backgroundImage: 'none'});
    }
    if (!this.options.endcolor)
      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
    if (!this.options.restorecolor)
      this.options.restorecolor = this.element.getStyle('background-color');
    // init color calculations
    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
  },
  update: function(position) {
    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
      return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
  },
  finish: function() {
    this.element.setStyle(Object.extend(this.oldStyle, {
      backgroundColor: this.options.restorecolor
    }));
  }
});

Effect.ScrollTo = function(element) {
  var options = arguments[1] || { },
    scrollOffsets = document.viewport.getScrollOffsets(),
    elementOffsets = $(element).cumulativeOffset(),
    max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();  

  if (options.offset) elementOffsets[1] += options.offset;

  return new Effect.Tween(null,
    scrollOffsets.top,
    elementOffsets[1] > max ? max : elementOffsets[1],
    options,
    function(p){ scrollTo(scrollOffsets.left, p.round()) }
  );
};

/* ------------- combination effects ------------- */

Effect.Fade = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  var options = Object.extend({
    from: element.getOpacity() || 1.0,
    to:   0.0,
    afterFinishInternal: function(effect) { 
      if (effect.options.to!=0) return;
      effect.element.hide().setStyle({opacity: oldOpacity}); 
    }
  }, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Appear = function(element) {
  element = $(element);
  var options = Object.extend({
  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
  to:   1.0,
  // force Safari to render floated elements properly
  afterFinishInternal: function(effect) {
    effect.element.forceRerendering();
  },
  beforeSetup: function(effect) {
    effect.element.setOpacity(effect.options.from).show(); 
  }}, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Puff = function(element) {
  element = $(element);
  var oldStyle = { 
    opacity: element.getInlineOpacity(), 
    position: element.getStyle('position'),
    top:  element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height
  };
  return new Effect.Parallel(
   [ new Effect.Scale(element, 200, 
      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
     Object.extend({ duration: 1.0, 
      beforeSetupInternal: function(effect) {
        Position.absolutize(effect.effects[0].element)
      },
      afterFinishInternal: function(effect) {
         effect.effects[0].element.hide().setStyle(oldStyle); }
     }, arguments[1] || { })
   );
};

Effect.BlindUp = function(element) {
  element = $(element);
  element.makeClipping();
  return new Effect.Scale(element, 0,
    Object.extend({ scaleContent: false, 
      scaleX: false, 
      restoreAfterFinish: true,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping();
      } 
    }, arguments[1] || { })
  );
};

Effect.BlindDown = function(element) {
  element = $(element);
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({ 
    scaleContent: false, 
    scaleX: false,
    scaleFrom: 0,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
    },  
    afterFinishInternal: function(effect) {
      effect.element.undoClipping();
    }
  }, arguments[1] || { }));
};

Effect.SwitchOff = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  return new Effect.Appear(element, Object.extend({
    duration: 0.4,
    from: 0,
    transition: Effect.Transitions.flicker,
    afterFinishInternal: function(effect) {
      new Effect.Scale(effect.element, 1, { 
        duration: 0.3, scaleFromCenter: true,
        scaleX: false, scaleContent: false, restoreAfterFinish: true,
        beforeSetup: function(effect) { 
          effect.element.makePositioned().makeClipping();
        },
        afterFinishInternal: function(effect) {
          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
        }
      })
    }
  }, arguments[1] || { }));
};

Effect.DropOut = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left'),
    opacity: element.getInlineOpacity() };
  return new Effect.Parallel(
    [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 
      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
    Object.extend(
      { duration: 0.5,
        beforeSetup: function(effect) {
          effect.effects[0].element.makePositioned(); 
        },
        afterFinishInternal: function(effect) {
          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
        } 
      }, arguments[1] || { }));
};

Effect.Shake = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left') };
    return new Effect.Move(element, 
      { x:  20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
        effect.element.undoPositioned().setStyle(oldStyle);
  }}) }}) }}) }}) }}) }});
};

Effect.SlideDown = function(element) {
  element = $(element).cleanWhitespace();
  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({ 
    scaleContent: false, 
    scaleX: false, 
    scaleFrom: window.opera ? 0 : 1,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
    },
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' }); 
    },
    afterFinishInternal: function(effect) {
      effect.element.undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
    }, arguments[1] || { })
  );
};

Effect.SlideUp = function(element) {
  element = $(element).cleanWhitespace();
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, window.opera ? 0 : 1,
   Object.extend({ scaleContent: false, 
    scaleX: false, 
    scaleMode: 'box',
    scaleFrom: 100,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().show();
    },  
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' });
    },
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
    }
   }, arguments[1] || { })
  );
};

// Bug in opera makes the TD containing this element expand for a instance after finish 
Effect.Squish = function(element) {
  return new Effect.Scale(element, window.opera ? 1 : 0, { 
    restoreAfterFinish: true,
    beforeSetup: function(effect) {
      effect.element.makeClipping(); 
    },  
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping(); 
    }
  });
};

Effect.Grow = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.full
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();    
  var initialMoveX, initialMoveY;
  var moveX, moveY;
  
  switch (options.direction) {
    case 'top-left':
      initialMoveX = initialMoveY = moveX = moveY = 0; 
      break;
    case 'top-right':
      initialMoveX = dims.width;
      initialMoveY = moveY = 0;
      moveX = -dims.width;
      break;
    case 'bottom-left':
      initialMoveX = moveX = 0;
      initialMoveY = dims.height;
      moveY = -dims.height;
      break;
    case 'bottom-right':
      initialMoveX = dims.width;
      initialMoveY = dims.height;
      moveX = -dims.width;
      moveY = -dims.height;
      break;
    case 'center':
      initialMoveX = dims.width / 2;
      initialMoveY = dims.height / 2;
      moveX = -dims.width / 2;
      moveY = -dims.height / 2;
      break;
  }
  
  return new Effect.Move(element, {
    x: initialMoveX,
    y: initialMoveY,
    duration: 0.01, 
    beforeSetup: function(effect) {
      effect.element.hide().makeClipping().makePositioned();
    },
    afterFinishInternal: function(effect) {
      new Effect.Parallel(
        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
          new Effect.Scale(effect.element, 100, {
            scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 
            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
        ], Object.extend({
             beforeSetup: function(effect) {
               effect.effects[0].element.setStyle({height: '0px'}).show(); 
             },
             afterFinishInternal: function(effect) {
               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 
             }
           }, options)
      )
    }
  });
};

Effect.Shrink = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.none
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();
  var moveX, moveY;
  
  switch (options.direction) {
    case 'top-left':
      moveX = moveY = 0;
      break;
    case 'top-right':
      moveX = dims.width;
      moveY = 0;
      break;
    case 'bottom-left':
      moveX = 0;
      moveY = dims.height;
      break;
    case 'bottom-right':
      moveX = dims.width;
      moveY = dims.height;
      break;
    case 'center':  
      moveX = dims.width / 2;
      moveY = dims.height / 2;
      break;
  }
  
  return new Effect.Parallel(
    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
    ], Object.extend({            
         beforeStartInternal: function(effect) {
           effect.effects[0].element.makePositioned().makeClipping(); 
         },
         afterFinishInternal: function(effect) {
           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
       }, options)
  );
};

Effect.Pulsate = function(element) {
  element = $(element);
  var options    = arguments[1] || { };
  var oldOpacity = element.getInlineOpacity();
  var transition = options.transition || Effect.Transitions.sinoidal;
  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
  reverser.bind(transition);
  return new Effect.Opacity(element, 
    Object.extend(Object.extend({  duration: 2.0, from: 0,
      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
    }, options), {transition: reverser}));
};

Effect.Fold = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height };
  element.makeClipping();
  return new Effect.Scale(element, 5, Object.extend({   
    scaleContent: false,
    scaleX: false,
    afterFinishInternal: function(effect) {
    new Effect.Scale(element, 1, { 
      scaleContent: false, 
      scaleY: false,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping().setStyle(oldStyle);
      } });
  }}, arguments[1] || { }));
};

Effect.Morph = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      style: { }
    }, arguments[1] || { });
    
    if (!Object.isString(options.style)) this.style = $H(options.style);
    else {
      if (options.style.include(':'))
        this.style = options.style.parseStyle();
      else {
        this.element.addClassName(options.style);
        this.style = $H(this.element.getStyles());
        this.element.removeClassName(options.style);
        var css = this.element.getStyles();
        this.style = this.style.reject(function(style) {
          return style.value == css[style.key];
        });
        options.afterFinishInternal = function(effect) {
          effect.element.addClassName(effect.options.style);
          effect.transforms.each(function(transform) {
            effect.element.style[transform.style] = '';
          });
        }
      }
    }
    this.start(options);
  },
  
  setup: function(){
    function parseColor(color){
      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
      color = color.parseColor();
      return $R(0,2).map(function(i){
        return parseInt( color.slice(i*2+1,i*2+3), 16 ) 
      });
    }
    this.transforms = this.style.map(function(pair){
      var property = pair[0], value = pair[1], unit = null;

      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
        value = value.parseColor();
        unit  = 'color';
      } else if (property == 'opacity') {
        value = parseFloat(value);
        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
          this.element.setStyle({zoom: 1});
      } else if (Element.CSS_LENGTH.test(value)) {
          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
          value = parseFloat(components[1]);
          unit = (components.length == 3) ? components[2] : null;
      }

      var originalValue = this.element.getStyle(property);
      return { 
        style: property.camelize(), 
        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 
        targetValue: unit=='color' ? parseColor(value) : value,
        unit: unit
      };
    }.bind(this)).reject(function(transform){
      return (
        (transform.originalValue == transform.targetValue) ||
        (
          transform.unit != 'color' &&
          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
        )
      )
    });
  },
  update: function(position) {
    var style = { }, transform, i = this.transforms.length;
    while(i--)
      style[(transform = this.transforms[i]).style] = 
        transform.unit=='color' ? '#'+
          (Math.round(transform.originalValue[0]+
            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
          (Math.round(transform.originalValue[1]+
            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
          (Math.round(transform.originalValue[2]+
            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
        (transform.originalValue +
          (transform.targetValue - transform.originalValue) * position).toFixed(3) + 
            (transform.unit === null ? '' : transform.unit);
    this.element.setStyle(style, true);
  }
});

Effect.Transform = Class.create({
  initialize: function(tracks){
    this.tracks  = [];
    this.options = arguments[1] || { };
    this.addTracks(tracks);
  },
  addTracks: function(tracks){
    tracks.each(function(track){
      var data = $H(track).values().first();
      this.tracks.push($H({
        ids:     $H(track).keys().first(),
        effect:  Effect.Morph,
        options: { style: data }
      }));
    }.bind(this));
    return this;
  },
  play: function(){
    return new Effect.Parallel(
      this.tracks.map(function(track){
        var elements = [$(track.ids) || $$(track.ids)].flatten();
        return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
      }).flatten(),
      this.options
    );
  }
});

Element.CSS_PROPERTIES = $w(
  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 
  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
  'fontSize fontWeight height left letterSpacing lineHeight ' +
  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
  'right textIndent top width wordSpacing zIndex');
  
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;

String.__parseStyleElement = document.createElement('div');
String.prototype.parseStyle = function(){
  var style, styleRules = $H();
  if (Prototype.Browser.WebKit)
    style = new Element('div',{style:this}).style;
  else {
    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
    style = String.__parseStyleElement.childNodes[0].style;
  }
  
  Element.CSS_PROPERTIES.each(function(property){
    if (style[property]) styleRules[property] = style[property]; 
  });
  
  if (Prototype.Browser.IE && this.include('opacity'))
    styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];

  return styleRules;
};

if (document.defaultView && document.defaultView.getComputedStyle) {
  Element.getStyles = function(element) {
    var css = document.defaultView.getComputedStyle($(element), null);
    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
      styles[property] = css[property];
      return styles;
    });
  };
} else {
  Element.getStyles = function(element) {
    element = $(element);
    var css = element.currentStyle, styles;
    styles = Element.CSS_PROPERTIES.inject({ }, function(hash, property) {
      hash[property] = css[property];
      return hash;
    });
    if (!styles.opacity) styles.opacity = element.getOpacity();
    return styles;
  };
};

Effect.Methods = {
  morph: function(element, style) {
    element = $(element);
    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
    return element;
  },
  visualEffect: function(element, effect, options) {
    element = $(element)
    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
    new Effect[klass](element, options);
    return element;
  },
  highlight: function(element, options) {
    element = $(element);
    new Effect.Highlight(element, options);
    return element;
  }
};

$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
  'pulsate shake puff squish switchOff dropOut').each(
  function(effect) { 
    Effect.Methods[effect] = function(element, options){
      element = $(element);
      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
      return element;
    }
  }
);

$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( 
  function(f) { Effect.Methods[f] = Element[f]; }
);

Element.addMethods(Effect.Methods);// script.aculo.us controls.js v1.8.0_pre1, Fri Oct 12 21:34:51 +0200 2007

// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//           (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
//           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
// Contributors:
//  Richard Livsey
//  Rahul Bhargava
//  Rob Wills
// 
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/

// Autocompleter.Base handles all the autocompletion functionality 
// that's independent of the data source for autocompletion. This
// includes drawing the autocompletion menu, observing keyboard
// and mouse events, and similar.
//
// Specific autocompleters need to provide, at the very least, 
// a getUpdatedChoices function that will be invoked every time
// the text inside the monitored textbox changes. This method 
// should get the text for which to provide autocompletion by
// invoking this.getToken(), NOT by directly accessing
// this.element.value. This is to allow incremental tokenized
// autocompletion. Specific auto-completion logic (AJAX, etc)
// belongs in getUpdatedChoices.
//
// Tokenized incremental autocompletion is enabled automatically
// when an autocompleter is instantiated with the 'tokens' option
// in the options parameter, e.g.:
// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
// will incrementally autocomplete with a comma as the token.
// Additionally, ',' in the above example can be replaced with
// a token array, e.g. { tokens: [',', '\n'] } which
// enables autocompletion on multiple tokens. This is most 
// useful when one of the tokens is \n (a newline), as it 
// allows smart autocompletion after linebreaks.
//
// vim:expandtab ts=8 sw=2

if(typeof Effect == 'undefined')
  throw("controls.js requires including script.aculo.us' effects.js library");

var Autocompleter = { }
Autocompleter.Base = function() { };
Autocompleter.Base.prototype = {
  baseInitialize: function(element, update, options) {
    element          = $(element)
    this.element     = element; 
    this.update      = $(update);  
    this.hasFocus    = false; 
    this.changed     = false; 
    this.active      = false; 
    this.index       = 0;     
    this.entryCount  = 0;
    this.oldElementValue = this.element.value;

    if(this.setOptions)
      this.setOptions(options);
    else
      this.options = options || { };

    this.options.paramName    = this.options.paramName || this.element.name;
    this.options.tokens       = this.options.tokens || [];
    this.options.frequency    = this.options.frequency || 0.4;
    this.options.minChars     = this.options.minChars || 1;
    this.options.onShow       = this.options.onShow || 
      function(element, update){ 
        if(!update.style.position || update.style.position=='absolute') {
          update.style.position = 'absolute';
          Position.clone(element, update, {
            setHeight: false, 
            offsetTop: element.offsetHeight
          });
        }
        Effect.Appear(update,{duration:0.15});
      };
    this.options.onHide = this.options.onHide || 
      function(element, update){ new Effect.Fade(update,{duration:0.15}) };

    if(typeof(this.options.tokens) == 'string') 
      this.options.tokens = new Array(this.options.tokens);
    // Force carriage returns as token delimiters anyway
    if (!this.options.tokens.include('\n'))
      this.options.tokens.push('\n');

    this.observer = null;
    
    this.element.setAttribute('autocomplete','off');

    Element.hide(this.update);

    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
    Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this));
  },

  show: function() {
    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
    if(!this.iefix && 
      (Prototype.Browser.IE) &&
      (Element.getStyle(this.update, 'position')=='absolute')) {
      new Insertion.After(this.update, 
       '<iframe id="' + this.update.id + '_iefix" '+
       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
      this.iefix = $(this.update.id+'_iefix');
    }
    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
  },
  
  fixIEOverlapping: function() {
    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
    this.iefix.style.zIndex = 1;
    this.update.style.zIndex = 2;
    Element.show(this.iefix);
  },

  hide: function() {
    this.stopIndicator();
    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
    if(this.iefix) Element.hide(this.iefix);
  },

  startIndicator: function() {
    if(this.options.indicator) Element.show(this.options.indicator);
  },

  stopIndicator: function() {
    if(this.options.indicator) Element.hide(this.options.indicator);
  },

  onKeyPress: function(event) {
    if(this.active)
      switch(event.keyCode) {
       case Event.KEY_TAB:
       case Event.KEY_RETURN:
         this.selectEntry();
         Event.stop(event);
       case Event.KEY_ESC:
         this.hide();
         this.active = false;
         Event.stop(event);
         return;
       case Event.KEY_LEFT:
       case Event.KEY_RIGHT:
         return;
       case Event.KEY_UP:
         this.markPrevious();
         this.render();
         if(Prototype.Browser.WebKit) Event.stop(event);
         return;
       case Event.KEY_DOWN:
         this.markNext();
         this.render();
         if(Prototype.Browser.WebKit) Event.stop(event);
         return;
      }
     else 
       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 
         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;

    this.changed = true;
    this.hasFocus = true;

    if(this.observer) clearTimeout(this.observer);
      this.observer = 
        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
  },

  activate: function() {
    this.changed = false;
    this.hasFocus = true;
    this.getUpdatedChoices();
  },

  onHover: function(event) {
    var element = Event.findElement(event, 'LI');
    if(this.index != element.autocompleteIndex) 
    {
        this.index = element.autocompleteIndex;
        this.render();
    }
    Event.stop(event);
  },
  
  onClick: function(event) {
    var element = Event.findElement(event, 'LI');
    this.index = element.autocompleteIndex;
    this.selectEntry();
    this.hide();
  },
  
  onBlur: function(event) {
    // needed to make click events working
    setTimeout(this.hide.bind(this), 250);
    this.hasFocus = false;
    this.active = false;     
  }, 
  
  render: function() {
    if(this.entryCount > 0) {
      for (var i = 0; i < this.entryCount; i++)
        this.index==i ? 
          Element.addClassName(this.getEntry(i),"selected") : 
          Element.removeClassName(this.getEntry(i),"selected");
      if(this.hasFocus) { 
        this.show();
        this.active = true;
      }
    } else {
      this.active = false;
      this.hide();
    }
  },
  
  markPrevious: function() {
    if(this.index > 0) this.index--
      else this.index = this.entryCount-1;
    this.getEntry(this.index).scrollIntoView(true);
  },
  
  markNext: function() {
    if(this.index < this.entryCount-1) this.index++
      else this.index = 0;
    this.getEntry(this.index).scrollIntoView(false);
  },
  
  getEntry: function(index) {
    return this.update.firstChild.childNodes[index];
  },
  
  getCurrentEntry: function() {
    return this.getEntry(this.index);
  },
  
  selectEntry: function() {
    this.active = false;
    this.updateElement(this.getCurrentEntry());
  },

  updateElement: function(selectedElement) {
    if (this.options.updateElement) {
      this.options.updateElement(selectedElement);
      return;
    }
    var value = '';
    if (this.options.select) {
      var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
    } else
      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
    
    var bounds = this.getTokenBounds();
    if (bounds[0] != -1) {
      var newValue = this.element.value.substr(0, bounds[0]);
      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
      if (whitespace)
        newValue += whitespace[0];
      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
    } else {
      this.element.value = value;
    }
    this.oldElementValue = this.element.value;
    this.element.focus();
    
    if (this.options.afterUpdateElement)
      this.options.afterUpdateElement(this.element, selectedElement);
  },

  updateChoices: function(choices) {
    if(!this.changed && this.hasFocus) {
      this.update.innerHTML = choices;
      Element.cleanWhitespace(this.update);
      Element.cleanWhitespace(this.update.down());

      if(this.update.firstChild && this.update.down().childNodes) {
        this.entryCount = 
          this.update.down().childNodes.length;
        for (var i = 0; i < this.entryCount; i++) {
          var entry = this.getEntry(i);
          entry.autocompleteIndex = i;
          this.addObservers(entry);
        }
      } else { 
        this.entryCount = 0;
      }

      this.stopIndicator();
      this.index = 0;
      
      if(this.entryCount==1 && this.options.autoSelect) {
        this.selectEntry();
        this.hide();
      } else {
        this.render();
      }
    }
  },

  addObservers: function(element) {
    Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
    Event.observe(element, "click", this.onClick.bindAsEventListener(this));
  },

  onObserverEvent: function() {
    this.changed = false;   
    this.tokenBounds = null;
    if(this.getToken().length>=this.options.minChars) {
      this.getUpdatedChoices();
    } else {
      this.active = false;
      this.hide();
    }
    this.oldElementValue = this.element.value;
  },

  getToken: function() {
    var bounds = this.getTokenBounds();
    return this.element.value.substring(bounds[0], bounds[1]).strip();
  },

  getTokenBounds: function() {
    if (null != this.tokenBounds) return this.tokenBounds;
    var value = this.element.value;
    if (value.strip().empty()) return [-1, 0];
    var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
    var offset = (diff == this.oldElementValue.length ? 1 : 0);
    var prevTokenPos = -1, nextTokenPos = value.length;
    var tp;
    for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
      tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
      if (tp > prevTokenPos) prevTokenPos = tp;
      tp = value.indexOf(this.options.tokens[index], diff + offset);
      if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
    }
    return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
  }
}

Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
  var boundary = Math.min(newS.length, oldS.length);
  for (var index = 0; index < boundary; ++index)
    if (newS[index] != oldS[index])
      return index;
  return boundary;
};

Ajax.Autocompleter = Class.create();
Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
  initialize: function(element, update, url, options) {
    this.baseInitialize(element, update, options);
    this.options.asynchronous  = true;
    this.options.onComplete    = this.onComplete.bind(this);
    this.options.defaultParams = this.options.parameters || null;
    this.url                   = url;
  },

  getUpdatedChoices: function() {
    this.startIndicator();
    
    var entry = encodeURIComponent(this.options.paramName) + '=' + 
      encodeURIComponent(this.getToken());

    this.options.parameters = this.options.callback ?
      this.options.callback(this.element, entry) : entry;

    if(this.options.defaultParams) 
      this.options.parameters += '&' + this.options.defaultParams;
    
    new Ajax.Request(this.url, this.options);
  },

  onComplete: function(request) {
    this.updateChoices(request.responseText);
  }

});

// The local array autocompleter. Used when you'd prefer to
// inject an array of autocompletion options into the page, rather
// than sending out Ajax queries, which can be quite slow sometimes.
//
// The constructor takes four parameters. The first two are, as usual,
// the id of the monitored textbox, and id of the autocompletion menu.
// The third is the array you want to autocomplete from, and the fourth
// is the options block.
//
// Extra local autocompletion options:
// - choices - How many autocompletion choices to offer
//
// - partialSearch - If false, the autocompleter will match entered
//                    text only at the beginning of strings in the 
//                    autocomplete array. Defaults to true, which will
//                    match text at the beginning of any *word* in the
//                    strings in the autocomplete array. If you want to
//                    search anywhere in the string, additionally set
//                    the option fullSearch to true (default: off).
//
// - fullSsearch - Search anywhere in autocomplete array strings.
//
// - partialChars - How many characters to enter before triggering
//                   a partial match (unlike minChars, which defines
//                   how many characters are required to do any match
//                   at all). Defaults to 2.
//
// - ignoreCase - Whether to ignore case when autocompleting.
//                 Defaults to true.
//
// It's possible to pass in a custom function as the 'selector' 
// option, if you prefer to write your own autocompletion logic.
// In that case, the other options above will not apply unless
// you support them.

Autocompleter.Local = Class.create();
Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
  initialize: function(element, update, array, options) {
    this.baseInitialize(element, update, options);
    this.options.array = array;
  },

  getUpdatedChoices: function() {
    this.updateChoices(this.options.selector(this));
  },

  setOptions: function(options) {
    this.options = Object.extend({
      choices: 10,
      partialSearch: true,
      partialChars: 2,
      ignoreCase: true,
      fullSearch: false,
      selector: function(instance) {
        var ret       = []; // Beginning matches
        var partial   = []; // Inside matches
        var entry     = instance.getToken();
        var count     = 0;

        for (var i = 0; i < instance.options.array.length &&  
          ret.length < instance.options.choices ; i++) { 

          var elem = instance.options.array[i];
          var foundPos = instance.options.ignoreCase ? 
            elem.toLowerCase().indexOf(entry.toLowerCase()) : 
            elem.indexOf(entry);

          while (foundPos != -1) {
            if (foundPos == 0 && elem.length != entry.length) { 
              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 
                elem.substr(entry.length) + "</li>");
              break;
            } else if (entry.length >= instance.options.partialChars && 
              instance.options.partialSearch && foundPos != -1) {
              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
                  elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
                  foundPos + entry.length) + "</li>");
                break;
              }
            }

            foundPos = instance.options.ignoreCase ? 
              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
              elem.indexOf(entry, foundPos + 1);

          }
        }
        if (partial.length)
          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
        return "<ul>" + ret.join('') + "</ul>";
      }
    }, options || { });
  }
});

// AJAX in-place editor and collection editor
// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).

// Use this if you notice weird scrolling problems on some browsers,
// the DOM might be a bit confused when this gets called so do this
// waits 1 ms (with setTimeout) until it does the activation
Field.scrollFreeActivate = function(field) {
  setTimeout(function() {
    Field.activate(field);
  }, 1);
}

Ajax.InPlaceEditor = Class.create();
Object.extend(Ajax.InPlaceEditor, {
  DefaultOptions: {
    ajaxOptions: { },
    autoRows: 3,                                // Use when multi-line w/ rows == 1
    cancelControl: 'link',                      // 'link'|'button'|false
    cancelText: 'cancel',
    clickToEditText: 'Click to edit',
    externalControl: null,                      // id|elt
    externalControlOnly: false,
    fieldPostCreation: 'activate',              // 'activate'|'focus'|false
    formClassName: 'inplaceeditor-form',
    formId: null,                               // id|elt
    highlightColor: '#ffff99',
    highlightEndColor: '#ffffff',
    hoverClassName: '',
    htmlResponse: true,
    loadingClassName: 'inplaceeditor-loading',
    loadingText: 'Loading...',
    okControl: 'button',                        // 'link'|'button'|false
    okText: 'ok',
    paramName: 'value',
    rows: 1,                                    // If 1 and multi-line, uses autoRows
    savingClassName: 'inplaceeditor-saving',
    savingText: 'Saving...',
    size: 0,
    stripLoadedTextTags: false,
    submitOnBlur: false,
    textAfterControls: '',
    textBeforeControls: '',
    textBetweenControls: ''
  },
  DefaultCallbacks: {
    callback: function(form) {
      return Form.serialize(form);
    },
    onComplete: function(transport, element) {
      // For backward compatibility, this one is bound to the IPE, and passes
      // the element directly.  It was too often customized, so we don't break it.
      new Effect.Highlight(element, {
        startcolor: this.options.highlightColor, keepBackgroundImage: true });
    },
    onEnterEditMode: null,
    onEnterHover: function(ipe) {
      ipe.element.style.backgroundColor = ipe.options.highlightColor;
      if (ipe._effect)
        ipe._effect.cancel();
    },
    onFailure: function(transport, ipe) {
      alert('Error communication with the server: ' + transport.responseText.stripTags());
    },
    onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
    onLeaveEditMode: null,
    onLeaveHover: function(ipe) {
      ipe._effect = new Effect.Highlight(ipe.element, {
        startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
        restorecolor: ipe._originalBackground, keepBackgroundImage: true
      });
    }
  },
  Listeners: {
    click: 'enterEditMode',
    keydown: 'checkForEscapeOrReturn',
    mouseover: 'enterHover',
    mouseout: 'leaveHover'
  }
});
Ajax.InPlaceEditor.prototype = {
  initialize: function(element, url, options) {
    this.url = url;
    this.element = element = $(element);
    this.prepareOptions();
    this._controls = { };
    arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
    Object.extend(this.options, options || { });
    if (!this.options.formId && this.element.id) {
      this.options.formId = this.element.id + '-inplaceeditor';
      if ($(this.options.formId))
        this.options.formId = '';
    }
    if (this.options.externalControl)
      this.options.externalControl = $(this.options.externalControl);
    if (!this.options.externalControl)
      this.options.externalControlOnly = false;
    this._originalBackground = this.element.getStyle('background-color') || 'transparent';
    this.element.title = this.options.clickToEditText;
    this._boundCancelHandler = this.handleFormCancellation.bind(this);
    this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
    this._boundFailureHandler = this.handleAJAXFailure.bind(this);
    this._boundSubmitHandler = this.handleFormSubmission.bind(this);
    this._boundWrapperHandler = this.wrapUp.bind(this);
    this.registerListeners();
  },
  checkForEscapeOrReturn: function(e) {
    if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
    if (Event.KEY_ESC == e.keyCode)
      this.handleFormCancellation(e);
    else if (Event.KEY_RETURN == e.keyCode)
      this.handleFormSubmission(e);
  },
  createControl: function(mode, handler, extraClasses) {
    var control = this.options[mode + 'Control'];
    var text = this.options[mode + 'Text'];
    if ('button' == control) {
      var btn = document.createElement('input');
      btn.type = 'submit';
      btn.value = text;
      btn.className = 'editor_' + mode + '_button';
      if ('cancel' == mode)
        btn.onclick = this._boundCancelHandler;
      this._form.appendChild(btn);
      this._controls[mode] = btn;
    } else if ('link' == control) {
      var link = document.createElement('a');
      link.href = '#';
      link.appendChild(document.createTextNode(text));
      link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
      link.className = 'editor_' + mode + '_link';
      if (extraClasses)
        link.className += ' ' + extraClasses;
      this._form.appendChild(link);
      this._controls[mode] = link;
    }
  },
  createEditField: function() {
    var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
    var fld;
    if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
      fld = document.createElement('input');
      fld.type = 'text';
      var size = this.options.size || this.options.cols || 0;
      if (0 < size) fld.size = size;
    } else {
      fld = document.createElement('textarea');
      fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
      fld.cols = this.options.cols || 40;
    }
    fld.name = this.options.paramName;
    fld.value = text; // No HTML breaks conversion anymore
    fld.className = 'editor_field';
    if (this.options.submitOnBlur)
      fld.onblur = this._boundSubmitHandler;
    this._controls.editor = fld;
    if (this.options.loadTextURL)
      this.loadExternalText();
    this._form.appendChild(this._controls.editor);
  },
  createForm: function() {
    var ipe = this;
    function addText(mode, condition) {
      var text = ipe.options['text' + mode + 'Controls'];
      if (!text || condition === false) return;
      ipe._form.appendChild(document.createTextNode(text));
    };
    this._form = $(document.createElement('form'));
    this._form.id = this.options.formId;
    this._form.addClassName(this.options.formClassName);
    this._form.onsubmit = this._boundSubmitHandler;
    this.createEditField();
    if ('textarea' == this._controls.editor.tagName.toLowerCase())
      this._form.appendChild(document.createElement('br'));
    if (this.options.onFormCustomization)
      this.options.onFormCustomization(this, this._form);
    addText('Before', this.options.okControl || this.options.cancelControl);
    this.createControl('ok', this._boundSubmitHandler);
    addText('Between', this.options.okControl && this.options.cancelControl);
    this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
    addText('After', this.options.okControl || this.options.cancelControl);
  },
  destroy: function() {
    if (this._oldInnerHTML)
      this.element.innerHTML = this._oldInnerHTML;
    this.leaveEditMode();
    this.unregisterListeners();
  },
  enterEditMode: function(e) {
    if (this._saving || this._editing) return;
    this._editing = true;
    this.triggerCallback('onEnterEditMode');
    if (this.options.externalControl)
      this.options.externalControl.hide();
    this.element.hide();
    this.createForm();
    this.element.parentNode.insertBefore(this._form, this.element);
    if (!this.options.loadTextURL)
      this.postProcessEditField();
    if (e) Event.stop(e);
  },
  enterHover: function(e) {
    if (this.options.hoverClassName)
      this.element.addClassName(this.options.hoverClassName);
    if (this._saving) return;
    this.triggerCallback('onEnterHover');
  },
  getText: function() {
    return this.element.innerHTML;
  },
  handleAJAXFailure: function(transport) {
    this.triggerCallback('onFailure', transport);
    if (this._oldInnerHTML) {
      this.element.innerHTML = this._oldInnerHTML;
      this._oldInnerHTML = null;
    }
  },
  handleFormCancellation: function(e) {
    this.wrapUp();
    if (e) Event.stop(e);
  },
  handleFormSubmission: function(e) {
    var form = this._form;
    var value = $F(this._controls.editor);
    this.prepareSubmission();
    var params = this.options.callback(form, value);
    params = (params ? params + '&' : '?') + 'editorId=' + this.element.id;
    if (this.options.htmlResponse) {
      var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
      Object.extend(options, {
        parameters: params,
        onComplete: this._boundWrapperHandler,
        onFailure: this._boundFailureHandler
      });
      new Ajax.Updater({ success: this.element }, this.url, options);
    } else {
      var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
      Object.extend(options, {
        parameters: params,
        onComplete: this._boundWrapperHandler,
        onFailure: this._boundFailureHandler
      });
      new Ajax.Request(this.url, options);
    }
    if (e) Event.stop(e);
  },
  leaveEditMode: function() {
    this.element.removeClassName(this.options.savingClassName);
    this.removeForm();
    this.leaveHover();
    this.element.style.backgroundColor = this._originalBackground;
    this.element.show();
    if (this.options.externalControl)
      this.options.externalControl.show();
    this._saving = false;
    this._editing = false;
    this._oldInnerHTML = null;
    this.triggerCallback('onLeaveEditMode');
  },
  leaveHover: function(e) {
    if (this.options.hoverClassName)
      this.element.removeClassName(this.options.hoverClassName);
    if (this._saving) return;
    this.triggerCallback('onLeaveHover');
  },
  loadExternalText: function() {
    this._form.addClassName(this.options.loadingClassName);
    this._controls.editor.disabled = true;
    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
    Object.extend(options, {
      parameters: 'editorId=' + encodeURIComponent(this.element.id),
      onComplete: Prototype.emptyFunction,
      onSuccess: function(transport) {
        this._form.removeClassName(this.options.loadingClassName);
        var text = transport.responseText;
        if (this.options.stripLoadedTextTags)
          text = text.stripTags();
        this._controls.editor.value = text;
        this._controls.editor.disabled = false;
        this.postProcessEditField();
      }.bind(this),
      onFailure: this._boundFailureHandler
    });
    new Ajax.Request(this.options.loadTextURL, options);
  },
  postProcessEditField: function() {
    var fpc = this.options.fieldPostCreation;
    if (fpc)
      $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
  },
  prepareOptions: function() {
    this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
    Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
    [this._extraDefaultOptions].flatten().compact().each(function(defs) {
      Object.extend(this.options, defs);
    }.bind(this));
  },
  prepareSubmission: function() {
    this._saving = true;
    this.removeForm();
    this.leaveHover();
    this.showSaving();
  },
  registerListeners: function() {
    this._listeners = { };
    var listener;
    $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
      listener = this[pair.value].bind(this);
      this._listeners[pair.key] = listener;
      if (!this.options.externalControlOnly)
        this.element.observe(pair.key, listener);
      if (this.options.externalControl)
        this.options.externalControl.observe(pair.key, listener);
    }.bind(this));
  },
  removeForm: function() {
    if (!this._form) return;
    this._form.remove();
    this._form = null;
    this._controls = { };
  },
  showSaving: function() {
    this._oldInnerHTML = this.element.innerHTML;
    this.element.innerHTML = this.options.savingText;
    this.element.addClassName(this.options.savingClassName);
    this.element.style.backgroundColor = this._originalBackground;
    this.element.show();
  },
  triggerCallback: function(cbName, arg) {
    if ('function' == typeof this.options[cbName]) {
      this.options[cbName](this, arg);
    }
  },
  unregisterListeners: function() {
    $H(this._listeners).each(function(pair) {
      if (!this.options.externalControlOnly)
        this.element.stopObserving(pair.key, pair.value);
      if (this.options.externalControl)
        this.options.externalControl.stopObserving(pair.key, pair.value);
    }.bind(this));
  },
  wrapUp: function(transport) {
    this.leaveEditMode();
    // Can't use triggerCallback due to backward compatibility: requires
    // binding + direct element
    this._boundComplete(transport, this.element);
  }
};
Object.extend(Ajax.InPlaceEditor.prototype, {
  dispose: Ajax.InPlaceEditor.prototype.destroy
});


Ajax.InPlaceCollectionEditor = Class.create();
Ajax.InPlaceCollectionEditor.DefaultOptions = {
  loadingCollectionText: 'Loading options...'
};
Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
  initialize: function(element, url, options) {
    this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
    Ajax.InPlaceEditor.prototype.initialize.call(this, element, url, options);
  },

  createEditField: function() {
    var list = document.createElement('select');
    list.name = this.options.paramName;
    list.size = 1;
    this._controls.editor = list;
    this._collection = this.options.collection || [];
    if (this.options.loadCollectionURL)
      this.loadCollection();
    else
      this.checkForExternalText();
    this._form.appendChild(this._controls.editor);
  },

  loadCollection: function() {
    this._form.addClassName(this.options.loadingClassName);
    this.showLoadingText(this.options.loadingCollectionText);
    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
    Object.extend(options, {
      parameters: 'editorId=' + encodeURIComponent(this.element.id),
      onComplete: Prototype.emptyFunction,
      onSuccess: function(transport) {
        var js = transport.responseText.strip();
        if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
          throw 'Server returned an invalid collection representation.';
        this._collection = eval(js);
        this.checkForExternalText();
      }.bind(this),
      onFailure: this.onFailure
    });
    new Ajax.Request(this.options.loadCollectionURL, options);
  },

  showLoadingText: function(text) {
    this._controls.editor.disabled = true;
    var tempOption = this._controls.editor.firstChild;
    if (!tempOption) {
      tempOption = document.createElement('option');
      tempOption.value = '';
      this._controls.editor.appendChild(tempOption);
      tempOption.selected = true;
    }
    tempOption.update((text || '').stripScripts().stripTags());
  },

  checkForExternalText: function() {
    this._text = this.getText();
    if (this.options.loadTextURL)
      this.loadExternalText();
    else
      this.buildOptionList();
  },

  loadExternalText: function() {
    this.showLoadingText(this.options.loadingText);
    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
    Object.extend(options, {
      parameters: 'editorId=' + encodeURIComponent(this.element.id),
      onComplete: Prototype.emptyFunction,
      onSuccess: function(transport) {
        this._text = transport.responseText.strip();
        this.buildOptionList();
      }.bind(this),
      onFailure: this.onFailure
    });
    new Ajax.Request(this.options.loadTextURL, options);
  },

  buildOptionList: function() {
    this._form.removeClassName(this.options.loadingClassName);
    this._collection = this._collection.map(function(entry) {
      return 2 === entry.length ? entry : [entry, entry].flatten();
    });
    var marker = ('value' in this.options) ? this.options.value : this._text;
    var textFound = this._collection.any(function(entry) {
      return entry[0] == marker;
    }.bind(this));
    this._controls.editor.update('');
    var option;
    this._collection.each(function(entry, index) {
      option = document.createElement('option');
      option.value = entry[0];
      option.selected = textFound ? entry[0] == marker : 0 == index;
      option.appendChild(document.createTextNode(entry[1]));
      this._controls.editor.appendChild(option);
    }.bind(this));
    this._controls.editor.disabled = false;
    Field.scrollFreeActivate(this._controls.editor);
  }
});

//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
//**** This only  exists for a while,  in order to  let ****
//**** users adapt to  the new API.  Read up on the new ****
//**** API and convert your code to it ASAP!            ****

Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
  if (!options) return;
  function fallback(name, expr) {
    if (name in options || expr === undefined) return;
    options[name] = expr;
  };
  fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
    options.cancelLink == options.cancelButton == false ? false : undefined)));
  fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
    options.okLink == options.okButton == false ? false : undefined)));
  fallback('highlightColor', options.highlightcolor);
  fallback('highlightEndColor', options.highlightendcolor);
};


// Delayed observer, like Form.Element.Observer, 
// but waits for delay after last key input
// Ideal for live-search fields

Form.Element.DelayedObserver = Class.create();
Form.Element.DelayedObserver.prototype = {
  initialize: function(element, delay, callback) {
    this.delay     = delay || 0.5;
    this.element   = $(element);
    this.callback  = callback;
    this.timer     = null;
    this.lastValue = $F(this.element); 
    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
  },
  delayedListener: function(event) {
    if(this.lastValue == $F(this.element)) return;
    if(this.timer) clearTimeout(this.timer);
    this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
    this.lastValue = $F(this.element);
  },
  onTimerEvent: function() {
    this.timer = null;
    this.callback(this.element, $F(this.element));
  }
};



function lturfly_zanox_ad(zanox_tracking_function, zanox_tracking_param) {

document.write('<style type="text/css">');
document.write('* {');
document.write('	font-family: Arial, Verdana, sans-serif;');
document.write('	font-weight: normal;');
document.write('	font-size: 11px;');
document.write('	font-style: normal;');
document.write('    margin: 0;');
document.write('    padding: 0;');
document.write('}');
document.write('div.page_autocompletition { background: #FFFFFF; display:inline; white-space:nowrap; }');
document.write('div.page_autocompletition ul { border: 1px solid #CC0066; margin: 0; padding: 0; width: 100%; list-style-type: none;  min-width:100px}');
document.write('div.page_autocompletition ul li { margin: 0; padding: 3px; }');
document.write('div.page_autocompletition ul li.selected { background-color: #EDEDED; }');
document.write('div.page_autocompletition ul strong { color: #CC0066; margin: 0; padding: 0; }');
document.write('div#searchBannerBig {');
document.write('    text-align:left;');
document.write('    width: 468px;');
document.write('	height: 90px;');
document.write('	background-color: #cc0066;');
document.write('	background: url("http://www.lturfly.com/lturfly/img/lturfly_468_60.gif") no-repeat top left;');
document.write('	padding: 7px 0px 0px 100px;');
document.write('}');
document.write('.inTip {');
document.write('    text-align:left;');
document.write('    font-size: 9px;');
document.write('    margin-top:0px;');
document.write('}');
document.write('.searchH {');
document.write('    color: #cc0066;');
document.write('    font-weight:bold;');
document.write('    font-size: 11px;');
document.write('    margin-top:3px;');
document.write('}');
document.write('.searchH2 {');
document.write('    color: #cc0066;');
document.write('    font-size: 11px;');
document.write('    margin-top:3px;');
document.write('}');
document.write('.felem {');
document.write('    border-width:1px;');
document.write('    border-color:#A5ACB2;');
document.write('    border-style:solid;');
document.write('}');
document.write('.al { text-align:left; }');
document.write('.ar { text-align:right; }');
document.write('</style>');
document.write('<form name="lfsearch" method="get" action="'+ zanox_tracking_function +'" target="_blank">');
document.write('<input type="hidden" name="'+ zanox_tracking_param +'"  value="http://www.lturfly.com/lturfly/index.ltml?fly_submit=search&step=search&service_class=Y&lstep=&fly_search_submit=fly_search_submit_x&depflex=0&retflex=0&childs=0&infants=0">');
document.write('<div id="searchBannerBig">');
document.write('    <map name="searchNow">');
document.write('        <area shape="rect" coords="0,0,95,25" href="" onclick="document.forms[\'lfsearch\'].submit();return false;" alt="Fl&uuml;ge suchen">');
document.write('    </map>');
document.write('    <p class="inTip">(Flughafen, Ort,City-Code, 3 Letter-Code)</p>');
document.write('    <table cellpadding="0" cellspacing="0" border="0" width="355">');
document.write('        <tr height="20">');
document.write('            <td width="32" class="al">');
document.write('                <span class="searchH">Von</span>');
document.write('            </td>');
document.write('            <td width="113" class="al">');
document.write('                <input type="text" autocomplete="off" style="width:104px;" class="felem" name="lf_origin" id="lf_origin" value="">');
document.write('                <div id="origin_autocompletition" style="display:none;width:auto !important;" class="page_autocompletition"></div>');
document.write('                <scr'+'ipt type="text/javascript">');
document.write('                    new Autocompleter.Local("lf_origin", "origin_autocompletition", [\'Lanzarote, Spanien - Lanzarote Airport (ACE)\',\'St. Gallen-Altenrhein (ACH)\',\'Malaga, Spanien - Malaga Arpt (AGP)\',\'Amsterdam, Niederlande - Schiphol Arpt (AMS)\',\'Barcelona, Spanien - Barcelona (BCN)\',\'Berlin, Deutschland (BER)\',\'Bremen, Deutschland - Bremen Airport (BRE)\',\'Bern, Schweiz - Belp Airport (BRN)\',\'Brüssel, Belgien - National Arpt (BRU)\',\'Basel, Schweiz - EuroAirport Basel-Mulhouse-Freiburg (BSL)\',\'Bratislava/Pressburg, Slovakei - Ivanka Arpt (BTS)\',\'Budapest, Ungarn - Budapest (BUD)\',\'Paris, Frankreich - Paris (CDG)\',\'Köln / Bonn, Deutschland - Köln / Bonn (CGN)\',\'Brüssel, Belgien - Brussels South Charleroi Airport (CRL)\',\'Dresden, Deutschland - Dresden (DRS)\',\'Dortmund, Deutschland - Dortmund (DTM)\',\'Düsseldorf, Deutschland - Düsseldorf (DUS)\',\'Eindhoven, Niederlande - Welschap Arpt (EIN)\',\'Erfurt, Deutschland - Erfurt (ERF)\',\'Friedrichshafen, Deutschland - Friedrichshafen Löwenthal (FDH)\',\'Karlsruhe / Baden-Baden, Deutschland (FKB)\',\'Memmingen, Deutschland - Flughafen Allgäu (FMM)\',\'Münster, Deutschland - Münster / Osnabrück (FMO)\',\'Frankfurt / Main, Deutschland - Frankfurt Main (FRA)\',\'Fuerteventura, Spanien - Fuerteventura Arpt (FUE)\',\'Graz, Österreich - Thalerhof Arpt (GRZ)\',\'Genf, Schweiz - Geneva Arpt (GVA)\',\'Hannover, Deutschland - Hannover (HAJ)\',\'Hamburg, Deutschland - Hamburg (HAM)\',\'Helgoland, Deutschland - Flugplatz Helgoland-Düne (HGL)\',\'Juist, Deutschland - Flugplatz Juist (JUI)\',\'Innsbruck, Österreich - Kranebitten Airport (INN)\',\'Klagenfurt, Österreich - Klagenfurt Arpt (KLU)\',\'Leipzig, Deutschland - Leipzig (LEJ)\',\'Ljubljana, Slowenien - Brnik Airport (LJU)\',\'Linz, Österreich - Hoersching Arpt (LNZ)\',\'Las Palmas, Spanien - Aeropuerto De Gran Canaria (LPA)\',\'Lugano, Schweiz - Agno Airport (LUG)\',\'Luxemburg, Luxemburg - Findel Arpt (LUX)\',\'Lyon, Frankreich - Satolas Airport (LYS)\',\'Mannheim, Deutschland - Mannheim (MHG)\',\'Basel / Mulhouse, Frankreich - Euroairport Basel-Mulhouse-Freiburg(MLH)\',\'München, Deutschland - München (Franz Josef Strauss) (MUC)\',\'Nizza, Frankreich - Nizza (NCE)\',\'Nürnberg, Deutschland - Nürnberg (NUE)\',\'Weeze, Deutschland - Airport Weeze (NRN)\',\'Paderborn, Deutschland - Paderborn (PAD)\',\'Mallorca, Spanien - Palma de Mallorca (PMI)\',\'Posen / Poznan, Polen - Lawica Arpt (POZ)\',\'Prag, Tschechien - Prag-Ruzyne (PRG)\',\'Rostock, Deutschland - Laage Arpt (RLG)\',\'Saarbrücken, Deutschland - Ensheim Arpt (SCN)\',\'Salzburg, Österreich - Salzburg Arpt (SZG)\',\'Stuttgart, Deutschland - Stuttgart (STR)\',\'Strassburg, Frankreich - Enzheim Arpt (SXB)\',\'Berlin, Deutschland - Berlin-Schönefeld (SXF)\',\'Stetin / Szczecin, Polen - Goleniow Arpt (SZZ)\',\'Teneriffa, Spanien - Tenerife Norte Los Rodeos Arpt (TFN)\',\'Teneriffa, Spanien - Reina Sofia Arpt (TFS)\',\'Berlin, Deutschland - Berlin-Tegel (TXL)\',\'Westerland / Sylt, Deutschland - Westerland / Sylt (GWT)\',\'Wien, Österreich - Wien (VIE)\',\'Wroclaw / Breslau, Polen - Strachowice (WRO)\',\'Zürich, Schweiz - Zürich (ZRH)\',\'Zweibrücken, Deutschland - Zweibrücken (ZQW)\'], {choices:15, frequency:0.1, fullSearch:true, partialChars:0, ignoreCase:true, partialSearch:true})');
document.write('                </scr'+'ipt>');
document.write('            </td>');
document.write('            <td width="42" class="al">');
document.write('                <span class="searchH">Hin</span>');
document.write('            </td>');
document.write('            <td width="73" class="al">');
document.write('                <input style="width:63px;" type="text" class="felem" id="departure_date" name="departure_date" value="05.08.2010">');
document.write('            </td>');
document.write('            <td width="95" class="al">');
document.write('                <span class="searchH">Erw.</span>');
document.write('                <select name="adults" style="width:42px;" class="felem">');
document.write('                    <option value="1" selected="selected">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option>');
document.write('                </select>');
document.write('            </td>');
document.write('        </tr>');
document.write('        <tr height="20">');
document.write('            <td width="32">');
document.write('                <span class="searchH">Nach</span>');
document.write('            </td>');
document.write('            <td width="113" class="al">');
document.write('                <input type="text" autocomplete="off" style="width:104px;" class="felem" name="lf_destination" id="lf_destination" value="">');
document.write('                <div id="destination_autocompletition" style="display:none;width:auto !important;" class="page_autocompletition"></div>');
document.write('                <scr'+'ipt type="text/javascript">');
document.write('            new Autocompleter.Local("lf_destination", "destination_autocompletition", [\'Aalborg, Dänemark - Aalborg Arpt (AAL)\',\'Aalesund, Norwegen - Vigra Airport (AES)\',\'Aarhus, Dänemark - Tirstrup Arpt (AAR)\',\'Abbotsford, Kanada - Abbotsford Arpt (YXX)\',\'Aberdeen, Grossbritannien - Dyce Airport (ABZ)\',\'Aberdeen, USA - Aberdeen Arpt (ABR)\',\'Abha, Saudi Arabien - Abha Airport (AHB)\',\'Abilene, USA - Abilene Municipal Arpt (ABI)\',\'Abingdon, USA - Virginia Highlands Arpt (VJI)\',\'Abu Dhabi, VAE - Dhabi Intl Arpt (AUH)\',\'Abu Simbel, Ägypten - Abu Simbel Arpt (ABS)\',\'Acapulco, Mexiko - Alvarez Intl Arpt (ACA)\',\'Ada OK, USA - Ada Municipal Arpt (ADT)\',\'Adak Island, USA - Adak Island Ns (ADK)\',\'Adana, Türkei - Adana Ariport (ADA)\',\'Addis Abeba, Äthiopien - Bole Airport (ADD)\',\'Adelaide, Australien - Adelaide Arpt (ADL)\',\'Aden, Jemen - Yemen Intl Arpt (ADE)\',\'Adler Sochi, Russland - Alder Sochi Arpt (AER)\',\'Agadir, Marokko - Agadir Almassira Arpt (AGA)\',\'Agen, Frankreich - La Garenne Arpt (AGF)\',\'Agra, Indien - Kheria Arpt (AGR)\',\'Aguascalientes, Mexiko - Aguascalientes Municipal Arpt (AGU)\',\'Ahmedabad, Indien - Ahmedabad Arpt (AMD)\',\'Aiken, USA - Aiken Municipal Arpt (AIK)\',\'Ainsworth, USA - Ainsworth Minicipal Arpt (ANW)\',\'Airlie Beach, Australien - Whitsunday Airstrip (WSY)\',\'Ajaccio, Frankreich - Campo Dell Oro Arpt (AJA)\',\'Akita, Japan - Akita Airport (AXT)\',\'Akron / Canton, USA - Akron Canton Regional Arpt (CAK)\',\'Akulivik, Kanada - Akulivik Arpt (AKV)\',\'Akureyri, Island - Akureyri (AEY)\',\'Al Baha, Saudi Arabien - Al Aqiq (ABT)\',\'Al Fujairah, VAE - Fujairah Intl Arpt (FJR)\',\'Al Hoceima, Marokko - Charif Al Idrissi Arpt (AHU)\',\'Alamos, Mexiko - Alamos Arpt (XAL)\',\'Alamosa, USA - Alamosa Municipal (ALS)\',\'Albany, Australien - Albany Airport (ALH)\',\'Albany, USA - Albany Cty Arpt (ALB)\',\'Albany, USA - Dougherty Cty Arpt (ABY)\',\'Albert Lea, USA - Albert Lea Arpt (AEL)\',\'Albi, Frankreich - Le Sequestre Arpt (LBI)\',\'Albuquerque, USA - Albuquerque Intl Arpt (ABQ)\',\'Albury, Australien - Albury Airport (ABX)\',\'Alderney, Grossbritannien - The Blaye Arpt (ACI)\',\'Aleppo, Syrien - Nejrab Arpt (ALP)\',\'Alexander Bay, Südafrika - Kortdoorn Arpt (ALJ)\',\'Alexandria, Ägypten - El Nouzha Arpt (ALY)\',\'Alexandria, USA - Alexandria Airport (AXN)\',\'Alexandria, USA - Alexandria Intl Arpt (AEX)\',\'Alexandria, USA - Esler Field (ESF)\',\'Alexandroupolis, Griechenland - Dhmokritos Arpt (AXD)\',\'Algeciras, Spanien - Algeciras Arpt (AEI)\',\'Alghero, Italien - Fertilia Arpt (AHO)\',\'Algiers, Algerien - Houari Boumedienne Arpt (ALG)\',\'Alicante, Spanien - Alicante Arpt (ALC)\',\'Alice Springs, Australien - Alice Springs Arpt (ASP)\',\'Allahabad, Indien - Bamrauli Arpt (IXD)\',\'Allentown, USA - Allentown Bethlehem Easton Arpt (ABE)\',\'Alliance, USA - Alliance Municipal (AIA)\',\'Alma, Kanada - Alma Minicipal Arpt (YTF)\',\'Almaty, Kasachstan - Alma Ata Arpt (ALA)\',\'Almeria, Spanien - Almeria Arpt (LEI)\',\'Almogorodo, USA - Alamogordo Municipal (ALM)\',\'Alor Setar, Malaysia - Sultan Abdul Hamlin Arpt (AOR)\',\'Alotau, Papua Neu Guinea - Gurney Arpt (GUR)\',\'Alpena, USA - Phelps Collins Arpt (APN)\',\'Alpine, USA - Alpine Aprt (ALE)\',\'Alta, Norwegen - Elvebakken Arpt (ALF)\',\'Altoona, USA - Blair Cty Arpt (AOO)\',\'Altus, USA (LTS)\',\'Altus, USA - Altus Municipal Arpt (AXS)\',\'Amahai, Indonesien - Amahai Airport (AHI)\',\'Amami O Shima, Japan - Amami O Shima Arpt (ASJ)\',\'Amarillo, USA - Amarillo Intl Arpt (AMA)\',\'Amarillo, USA - Tradewind Airport (TDW)\',\'Ames, USA - Ames Minicipal Arpt (AMW)\',\'Amman, Jordanien - Civil Marka Arpt (ADJ)\',\'Amman, Jordanien - Queen Alia Intl Arpt (AMM)\',\'Amsterdam, Niederlande - Schiphol Arpt (AMS)\',\'Anapa, Russland - Anapa Arpt (AAQ)\',\'Anapolis, Brasilien - Anapolis Arpt (APS)\',\'Anchorage, USA - Anchorage Intl Arpt (ANC)\',\'Ancona, Italien - Falconara Arpt (AOI)\',\'Ancortes, USA - Ancortes Arpt (OTS)\',\'Andenes, Norwegen - Andenes Arpt (ANX)\',\'Anderson, USA - Anderson Arpt (AND)\',\'Anderson, USA - Anderson Municipal Arpt (AID)\',\'Andorra La Vella, Andorra - Andorra La Vella Hlpt (ALV)\',\'Andros Town, Bahamas - Andros Town Arpt (ASD)\',\'Angeles/Luzon, Philippinen - Diosdado Macapagal Intl Arpt (CRK)\',\'Angers, Frankreich - Arville Arpt (ANE)\',\'Angouleme, Frankreich - Bel Air Airport (ANG)\',\'Ankara, Türkei (ANK)\',\'Ankara, Türkei - Esenboga Arpt (ESB)\',\'Ann Arbor, USA - Ann Arbor Municipal (ARB)\',\'Annaba, Algerien - Les Salines Arpt (AAE)\',\'Annapolis, USA - Lee Annapolis Arpt (ANP)\',\'Annecy, Frankreich - Annecy Meythet Arpt (NCY)\',\'Anniston, USA - Anniston Municipal Arpt (ANB)\',\'Anquilla, Anguilla - Wallblake Municipal (AXA)\',\'Antalya, Türkei - Antalya Airport (AYT)\',\'Antananarivo, Madagaskar - Ivato Arpt (TNR)\',\'Antigua, Antigua - V C Bird Intl Arpt (ANU)\',\'Antofagasta, Chile - Cerro Moreno Arpt (ANF)\',\'Antwerpen, Belgien - Deurne Airport (ANR)\',\'Apartado, Kolumbien - Apartado Arpt (APO)\',\'Apatzingan, Mexiko - Apatzingan Arpt (AZG)\',\'Apia, Samoa - Apia Airport (APW)\',\'Apia, Samoa - Fagali Arpt (FGI)\',\'Appleton, USA - Outagamie Cty Arpt (ATW)\',\'Aqaba, Jordanien - Aqaba Airport (AQJ)\',\'Aqtau, Kasachstan - Aqtau (SCO)\',\'Aqtobe, Kasachstan - Aktyubinsk Arpt (AKX)\',\'Aquadilla, USA - Borinquen Municipal Arpt (BQN)\',\'Aracaju, Brasilien - Santa Maria Arpt (AJU)\',\'Aracatuba, Brasilien - Aracatuba Arpt (ARU)\',\'Arad, Rumänien - Arad Arpt (ARW)\',\'Araguaina, Brasilien - Araguaina Arpt (AUX)\',\'Arcadia, USA - Civic Center Arpt (JAR)\',\'Arcata / Eureka, USA - Arcata Eureka Arpt (ACV)\',\'Ardmore, USA - Ardmore Municipal Arpt (ADM)\',\'Arequipa, Peru - Rodriguez Ballon Arpt (AQP)\',\'Arica, Chile - Chacalluta Arpt (ARI)\',\'Armidale, Australien - Armidale Arpt (ARM)\',\'Arras, Frankreich - Arras Arpt (QRV)\',\'Arthurs Town, Bahamas - Arthurs Town Arpt (ATC)\',\'Aruba, Aruba - Reina Beatrix Arpt (AUA)\',\'Arushia, Tansania - Arusha Arpt (ARK)\',\'Arviat, Kanada - Arviat Arpt (YEK)\',\'Arvidsjaur, Schweden - Arvidsjaur Arpt (AJR)\',\'Asahikawa, Japan - Asahikawa Arpt (AKJ)\',\'Asheville, USA - Asheville Municipal Arpt (AVL)\',\'Ashgabat, Turkmenistan - Ashgabat Arpt (ASB)\',\'Asmara, Eritrea - Yohannes IV Arpt (ASM)\',\'Aspen, USA - Pitkin Cty Arptt Sardy Fld (ASE)\',\'Assuan, Ägypten - Daraw Arpt (ASW)\',\'Astana, Kasachstan - Astana Arpt (TSE)\',\'Astrakhan, Russland - Astrakhan Arpt (ASF)\',\'Asuncion, Paraguay - Salvio Pettirosse Arpt (ASU)\',\'Athen, Griechenland - Athen (ATH)\',\'Athen, Griechenland - Athens Hellinikon Arpt (HEW)\',\'Athen, USA - Athens Municipal (AHN)\',\'Athens, USA - Ohio University Arpt (ATO)\',\'Atibaia, Brasilien - Atibaia Arpt (ZBW)\',\'Atikokan, Kanada - Atikokan Municipal Arpt (YIB)\',\'Atlanta, USA - Beaver Ruin Helpt (JAO)\',\'Atlanta, USA - Dekalb Peachtree (PDK)\',\'Atlanta, USA - Fulton Cty Arpt (FTY)\',\'Atlanta, USA - Galleria Hlpt (JGL)\',\'Atlanta, USA - Hartsfield Intl Arpt (ATL)\',\'Atlanta, USA - Perimeter Hlpt (JAJ)\',\'Atlantic City, USA - Bader Field (AIY)\',\'Atlantic City, USA - Pomona Field (ACY)\',\'Atuona, Französisch-Polynesien - Atuona Arpt (AUQ)\',\'Atyrau, Kasachstan - Atyrau Arpt (GUW)\',\'Auckland, Neuseeland - Auckland Intl Arpt (AKL)\',\'Augusta, USA - Bush Field (AGS)\',\'Augusta, USA - Daniel Airport (DNL)\',\'Augusta, USA - Maine State Arpt (AUG)\',\'Aupaluk, Kanada - Aupaluk Arpt (YPJ)\',\'Aurangabad, Indien - Chikkalthana Arpt (IXU)\',\'Aurillac, Frankreich - Tronquieres Arpt (AUR)\',\'Aurora, USA - Aurora Municipal Arpt (AUZ)\',\'Austin, USA - Austin-Bergstrom International Airport (AUS)\',\'Avalon, Australien - Avalon Arpt (AVV)\',\'Avignon, Frankreich - Avignon Caumont Arpt (AVN)\',\'Ayers Rock, Australien - Connellan Arpt (AYQ)\',\'Ayr Au, Australien - Ayr Arpt (AYR)\',\'Azerbaijan, Aserbaidschan - Baku Arpt (BAK)\',\'Ba City, Fidschi - Ba Arpt (BFJ)\',\'Bacolod, Philippinen - Bacolod Arpt (BCD)\',\'Badajoz, Spanien - Talaveral La Real Arpt (BJZ)\',\'Badu Island, Australien - Badu Island Arpt (BDD)\',\'Bagdogra, Indien - Bagdogra Arpt (IXB)\',\'Baghdad, Irak - Al Muthana Arpt (BGW)\',\'Baghdad, Irak - Saddam Intl (SDA)\',\'Baguio, Philippinen - Loakan Arpt (BAG)\',\'Bahia Blanca, Argentinien - Commandante Airport (BHI)\',\'Bahia De Los Angeles, Mexiko - Bahia De Los Angeles Arpt (BHL)\',\'Bahrain, Bahrain - Muharraq Arpt (BAH)\',\'Baie Comeau, Kanada - Baie Comeau Arpt (YBC)\',\'Bairnsdale, Australien - Bairnsdale Airport (BSJ)\',\'Baker Lake, Kanada - Baker Lake Arpt (YBK)\',\'Bakersfield, USA - Meadows Field (BFL)\',\'Balikesir, Türkei (BZI)\',\'Balikesir, Türkei - Merkez Arpt (MQJ)\',\'Balikpapan, Indonesien - Sepingan Arpt (BPN)\',\'Ballina, Australien - Ballina Arpt (BNK)\',\'Balmaceda, Chile - Teniente Vidal Airport (BBA)\',\'Baltimore, USA - Baltimore Washington Intl Arpt (BWI)\',\'Banda Aceh, Indonesien - Blang Bintang Arpt (BTJ)\',\'Bandar Lampung, Indonesien - Bandar Lampung Arpt (TKG)\',\'Bandar Seri Begawan, Brunei - Brunei Intl Arpt (BWN)\',\'Bandung, Indonesien - Husein Sastranegara Arpt (BDO)\',\'Banff, Kanada - Banff Arpt (YBA)\',\'Bangalore, Indien - Hindustan Arpt (BLR)\',\'Bangkok, Thailand - Bangkok Intl Arpt (BKK)\',\'Bangor, USA - Bangor Intl Arpt (BGR)\',\'Banja Luka, Bosnien - Banja Luka Arpt (BNX)\',\'Bankstown, Australien - Bankstown Aerodrome (BWU)\',\'Bar Harbor, USA - Hancock County (BHB)\',\'Barahona, Dominikanische Republik - Barahona Arpt (BRX)\',\'Barbados, Barbados - Grantley Adams Intl Arpt (BGI)\',\'Barcaldine, Australien - Barcaldine Arpt (BCI)\',\'Barcelona, Spanien - Barcelona (BCN)\',\'Barcelona, Spanien - Barcelona / Reus (REU)\',\'Barcelona, Venezuela - Gen J A Anzoategui Arpt (BLA)\',\'Bardufoss, Norwegen - Bardufoss Arpt (BDU)\',\'Bari, Italien - Bari Airport (BRI)\',\'Barquisimeto, Venezuela - Airport Barquisimeto (BRM)\',\'Barra, Grossbritannien - North Bay Arpt (BRR)\',\'Barrancabermeja, Kolumbien - Variguies Arpt (EJA)\',\'Barranquilla, Kolumbien - E Cortissoz Arpt (BAQ)\',\'Barrow In Furness, Grossbritannien - Walney Island (BWF)\',\'Barrow, USA - Barrow WBAS (BRW)\',\'Bartlesville, USA - Bartlesville Municipal Arpt (BVO)\',\'Basel / Mulhouse, Frankreich - Euroairport French (MLH)\',\'Basel, Schweiz (EAP)\',\'Basel, Schweiz - EuroAirport Basel-Mulhouse-Freiburg (BSL)\',\'Basra, Irak - Basra Intl Arpt (BSR)\',\'Bastia, Frankreich - Poretta Airport (BIA)\',\'Batesville, USA - Batesville Municipal (BVX)\',\'Batesville, USA - Hillenbrand (HLB)\',\'Bathurst Isl, Australien - Bathurst Island Arpt (BRT)\',\'Bathurst, Australien - Raglan Airport (BHS)\',\'Bathurst, Kanada - Bathurst Arpt (ZBF)\',\'Baton Rouge, USA - Baton Rouge Downtown Arpt (EBR)\',\'Baton Rouge, USA - Ryan Airport (BTR)\',\'Battle Creek, USA - Wk Wellogg Regional (BTL)\',\'Batu Besar, Indonesien - Hang Nadim Arpt (BTH)\',\'Bauru, Brasilien - Bauru Arpt (BAU)\',\'Beaufort, USA - Beaufort County Arpt (BFT)\',\'Beaumont, USA - Jefferson Cty Arpt (BPT)\',\'Beaver Creek, USA - Beaver Creek Arpt (ZBV)\',\'Beaver Falls, USA - Beaver Falls Arpt (BFP)\',\'Beckleym, USA - Raleigh Cty Memorial (BKW)\',\'Bedford, USA - Bedford Arpt (BED)\',\'Bedwell Harbor, Kanada - Bedwell Harbor Arpt (YBW)\',\'Beef Island, Jungferninseln, British Virgin Islands - Beef Island Arpt (EIS)\',\'Beirut, Libanon - Beirut Intl Arpt (BEY)\',\'Belem, Brasilien - Val De Cans Arpt (BEL)\',\'Belfast, Grossbritannien - Belfast City Arpt (BHD)\',\'Belfast, Grossbritannien - Belfast Intl Arpt (BFS)\',\'Belgorod, Russland - Belgorod Arpt (EGO)\',\'Belgrad, Serbien - Batajnica Arpt (BJY)\',\'Belgrad, Serbien - Nikola-Tesla-Flughafen (BEG)\',\'Belize City, Belize - Belize City Municipal (TZA)\',\'Belize City, Belize - Belize Intl Arpt (BZE)\',\'Bella Coola, Kanada - Bella Colla Municipal (QBC)\',\'Bellingham, USA - Bellingham Intl Arpt (BLI)\',\'Belo Horizonte, Brasilien (BHZ)\',\'Belo Horizonte, Brasilien - Tancredo (CNF)\',\'Beloit, USA - Rock County Arpt (JVL)\',\'Bemidji, USA - Bemidji Municipal Arpt (BJI)\',\'Benbecula, Grossbritannien - Benbecula Arpt (BEB)\',\'Bengkulu, Indonesien - Padangkemiling Arpt (BKS)\',\'Benton Harbor, USA - Ross Field (BEH)\',\'Bergen, Norwegen - Flesland Airport (BGO)\',\'Bergerac, Frankreich - Roumaniere Arpt (EGC)\',\'Berlin, Deutschland (BER)\',\'Berlin, Deutschland - Berlin-Schönefeld (SXF)\',\'Berlin, Deutschland - Berlin-Tegel (TXL)\',\'Bermuda, Bermuda - Kindley Arpt (BDA)\',\'Bern, Schweiz - Belp Airport (BRN)\',\'Bern, Schweiz - Berne Railroad Station (ZDJ)\',\'Bethel, USA - Bethel Airport (BET)\',\'Bhopal, Indien - Bhopal Arpt (BHO)\',\'Bhubaneswar, Indien - Bhubaneswar Arpt (BBI)\',\'Biak, Indonesien - Mokmer Arpt (BIK)\',\'Biarritz, Frankreich - Bayonne Anglet Arpt (BIQ)\',\'Big Bear City, USA - Big Bear City Arpt (RBF)\',\'Bilbao, Spanien - Sondica Arpt (BIO)\',\'Billings, USA - Billings Logan Intl Arpt (BIL)\',\'Billund, Dänemark - Billund Airport (BLL)\',\'Biloela, Australien - Biloela Arpt (ZBL)\',\'Biloxi, USA - Keesler AFB (BIX)\',\'Bimini, Bahamas - Bimini Airport (BIM)\',\'Bimini, Bahamas - North Seaplane Base (NSB)\',\'Binghamton, USA - Edwin A Link Field (BGM)\',\'Bintulu, Malaysia - Bintulu Arpt (BTU)\',\'Birdsville, Australien - Birdsville Arpt (BVI)\',\'Birmingham, Grossbritannien - Birmingham Intl Arpt (BHX)\',\'Birmingham, USA - Seibels Bryan Arpt (BHM)\',\'Bisbee, USA - Bisbee Municipal Arpt (BSQ)\',\'Bishkek, Kirgisistan - Bishkek (FRU)\',\'Bishop, USA - Bishop Airport (BIH)\',\'Biskra, Algerien - Biskra Arpt (BSK)\',\'Bismarck, USA - Bismarck Municipal Arpt (BIS)\',\'Blackpool, Grossbritannien - Blackpool Airport (BLK)\',\'Blacksburg, USA - Virginia Tech Arpt (BCB)\',\'Blackwater, Australien - Blackwater Arpt (BLT)\',\'Blairsville, USA - Blairsville Arpt (BSI)\',\'Blakely Island, USA - Blakely Is Municipal (BYW)\',\'Blanc, Kanada - Blanc Sablon Arpt (YBX)\',\'Blenheim, Neuseeland - Woodbourne Arpt (BHE)\',\'Block Island, USA - Block Island Municipal (BID)\',\'Bloemfontein, Südafrika - J B M Hertzog Arpt (BFN)\',\'Bloomington, USA - Monroe Cty Arpt Indiana (BMG)\',\'Bloomington, USA - Normal Airport (BMI)\',\'Bluefield, USA - Mercer County (BLF)\',\'Blumenau, Brasilien - Blumenau Arpt (BNU)\',\'Blythe, USA - Blythe Airport (BLH)\',\'Blytheville, USA - Blytheville Municipal Arpt (HKA)\',\'Boa Vista, Brasilien - Boa Vista Arpt (BVB)\',\'Bodo, Norwegen - Bodo Arpt (BOO)\',\'Bodrum, Türkei - Bodrum (BJV)\',\'Bodrum, Türkei - Imsik Arpt (BXN)\',\'Bofors, Schweden - Orebro Airport (ORB)\',\'Bogota, Kolumbien - Eldorado Airport (BOG)\',\'Boigu Island, Australien - Boigu Island Arpt (GIC)\',\'Boise, USA - Boise Municipal Arpt Gowen Field (BOI)\',\'Bologna, Italien - Bologna / Florenz (BLQ)\',\'Bombay, Indien - Bombay Airport (BOM)\',\'Bonaire, Niederländische Antillen - Flamingo Field (BON)\',\'Bonaventure, Kanada - Bonaventure Municipal Arpt (YVB)\',\'Bora Bora, Französisch-Polynesien - Motu Mute Arpt (BOB)\',\'Bordeaux, Frankreich - Merignac Arpt (BOD)\',\'Borg El Arab, Ägypten - Borg El Arab Arpt (HBE)\',\'Bornholm, Dänemark - Bornholm Arpt (RNN)\',\'Borrego Springs, USA - Borrego Valley Arpt (BXS)\',\'Borroloola, Australien - Borroloola Arpt (BOX)\',\'Boston, USA - Logan Intl Arpt (BOS)\',\'Boulder, USA - Boulder Municipal Arpt (WBU)\',\'Bourgas, Bulgarien - Bourgas (BOJ)\',\'Bourke, Australien - Bourke Airport (BRK)\',\'Bournemouth, Grossbritannien - Bournemouth Intl Arpt (BOH)\',\'Bowling Green, USA - Warren Cty Arpt (BWG)\',\'Bozeman, USA - Gallatin Field (BZN)\',\'Bozen, Italien - Bolzano Arpt (BZO)\',\'Bradford, USA - Bradford Regional Arpt (BFD)\',\'Brainerd, USA - Crowwing Cty Arpt (BRD)\',\'Braintree, Grossbritannien - Wether Field RAF (WXF)\',\'Brandon, Kanada - Brandon Municipal Arpt (YBR)\',\'Branson, USA (ZBX)\',\'Branson, USA - M Graham Clark Arpt (PLK)\',\'Brasilia, Brasilien - Brasilia Intl Arpt (BSB)\',\'Bratislava/Pressburg, Slovakei - Ivanka Arpt (BTS)\',\'Brawley, USA - Brawley Arpt (BWC)\',\'Brazoria, USA - Brazoria County Arpt (BZT)\',\'Brazzaville, Kongo - Maya Maya Arpt (BZV)\',\'Bremen, Deutschland - Bremen Airport (BRE)\',\'Bremerton, USA - Bremerton Municipal (PWT)\',\'Brest, Frankreich - Guipavas Arpt (BES)\',\'Brevig Mission, USA - Brevig Mission Arpt (KTS)\',\'Brewarrina, Australien - Brewarrina Arpt (BWQ)\',\'Bridgeport, USA - Sikorsky Memorial Arpt (BDR)\',\'Brindisi, Italien - Apaola Casale Arpt (BDS)\',\'Brisbane, Australien - Brisbane Intl Arpt (BNE)\',\'Bristol, Grossbritannien - Bristol Arpt (BRS)\',\'Brive La Gaill, Frankreich - Laroche Airport (BVE)\',\'Brno, Tschechien - Turnay Arpt (BRQ)\',\'Brockville, Kanada - Brockville Arpt (XBR)\',\'Broken Hill, Australien - Broken Hill Arpt (BHQ)\',\'Bromont, Kanada - Bromont Regional Arpt (ZBM)\',\'Bronnoysund, Norwegen - Bronnoy Arpt (BNN)\',\'Brookings, USA - Brookings Municipal (BKX)\',\'Broome, Australien - Broome Airport (BME)\',\'Broomfield, USA - Jeffco Arpt (BJC)\',\'Brownsville, USA - South Padre Island Intl Arpt (BRO)\',\'Brownwood, USA - Brownwood Municipal Arpt (BWD)\',\'Brüssel, Belgien - Brussels South Charleroi Airport (CRL)\',\'Brüssel, Belgien - National Arpt (BRU)\',\'Brunswick, USA - Gylnco Jet Port (BQK)\',\'Brunswick, USA - McKinnon Arpt (SSI)\',\'Brunswick, USA - Naval Air Station (NHZ)\',\'Bryce, USA - Bryce Arpt (BCE)\',\'Bucaramanga, Kolumbien - Palo Negro Arpt (BGA)\',\'Budapest, Ungarn - Budapest (BUD)\',\'Buenos Aires, Argentinien (BUE)\',\'Buenos Aires, Argentinien - Jorge Newbery (AEP)\',\'Buenos Aires, Argentinien - Ministro Pistarini (EZE)\',\'Buffalo, USA - Greater Buffalo Intl Arpt (BUF)\',\'Bujumbura, Burundi - Bujumbura Intl Arpt (BJM)\',\'Bukarest, Rumänien (BUH)\',\'Bukarest, Rumänien - Baneasa Airport (BBU)\',\'Bukarest, Rumänien - Otopeni Airport (OTP)\',\'Bulawayo, Simbabwe - Bulawayo Arpt (BUQ)\',\'Bullfrog Basin, USA - Bullfrog Basin Arpt (BFG)\',\'Bullhead City, USA - Bullhead Laughlin Arpt (IFP)\',\'Bumi Hills, Simbabwe - Bumi Hills Arpt (BZH)\',\'Bunbury, Australien - Bunbury Arpt (BUY)\',\'Bundaberg, Australien - Bundaberg Arpt (BDB)\',\'Burbank, USA - Burbank Glendale Pasadena Arpt (BUR)\',\'Burbank, USA - Burbank Heliport (JPD)\',\'Burbank, USA - Heliport (JGX)\',\'Buri Ram, Thailand - Buri Ram Arpt (BFV)\',\'Burketown, Australien - Burketown Arpt (BUC)\',\'Burley, USA - Burley Arpt (BYI)\',\'Burlington, USA - Burlington Intl Arpt (BTV)\',\'Burlington, USA - Burlington Municipal Arpt (BRL)\',\'Burnie, Australien - Burnie Arpt (BWT)\',\'Bursa, Türkei - Bursa Arpt (BTZ)\',\'Bursa, Türkei - Yenisehir Arpt (YEI)\',\'Bury St Edmunds, Grossbritannien - Honington Arpt (BEQ)\',\'Bushehr, Iran - Bushehr Arpt (BUZ)\',\'Butte, USA - Bert Mooney Arpt (BTM)\',\'Butuan, Philippinen - Butuan Arpt (BXU)\',\'Buzios, Brasilien - Buzios Arpt (BZC)\',\'Bydgoszcz, Polen - Bydgoszcz Arpt (BZG)\',\'Cabimas, Venezuela - Oro Negro Arpt (CBS)\',\'Cabo Frio, Brasilien - Cabo Frio Arpt (CFB)\',\'Cachoeiro De Itapemirim, Brasilien - Cachoeiro De Itapemirim Arpt (CDI)\',\'Cacoal, Brasilien - Cacoal Arpt (OAL)\',\'Cadillac, USA - Wexford County Arpt (CAD)\',\'Caen, Frankreich - Carpiquet Arpt (CFR)\',\'Cagayan, Philippinen - Lumbia Arpt (CGY)\',\'Cagliari, Italien - Elmas Airport (CAG)\',\'Cahors, Frankreich - Laberandie Arpt (ZAO)\',\'Cairns, Australien - Cairns Airport (CNS)\',\'Calama, Chile - El Loa Arpt (CJC)\',\'Caldwell, USA - Caldwell Wright Arpt (CDW)\',\'Calexico, USA - Calexico Intl Arpt (CXL)\',\'Calgary, Kanada - Calgary Intl Arpt (YYC)\',\'Calgary, Kanada - Red Deer Arpt (YQF)\',\'Cali, Kolumbien - Alfonso Bonella Aragon Arpt (CLO)\',\'Calvi, Frankreich - Saint Catherine Arpt (CLY)\',\'Cam Ranh, Vietnam - Cam Ranh Arpt (CXR)\',\'Camaguey, Kuba - Ign Agramonte Intl Arpt (CMW)\',\'Cambridge Bay, Kanada - Cambridge Bay Arpt (YCB)\',\'Cambridge, Grossbritannien - Cambridge Arpt (CBG)\',\'Camden, USA - Harrell Fieldsandro Arpt (CDH)\',\'Camiri, Bolivien - Choreti Arpt (CAM)\',\'Camp Springs, USA - Andrews Air Force Base (ADW)\',\'Campbell River, Kanada - Campbell River Municipal (YBL)\',\'Campbell River, Kanada - Harbor Airport (YHH)\',\'Campbelltown, Grossbritannien - Machrihanish Arpt (CAL)\',\'Campeche, Mexiko - Campeche Intl Arpt (CPE)\',\'Campina Grande, Brasilien - Joao Suassuana Arpt (CPV)\',\'Campinas, Brasilien - International Campinas (CPQ)\',\'Campo Grande, Brasilien - Internacional (CGR)\',\'Campos, Brasilien - Bartolomeu Lisandro Arpt (CAW)\',\'Can Tho, Vietnam - Can Tho Arpt (VCA)\',\'Canberra, Australien - Canberra Arpt (CBR)\',\'Cancun, Mexiko - Cancun Aeropuerto Internacional (CUN)\',\'Cannes, Frankreich - Croisette Heliport (JCA)\',\'Cannes, Frankreich - Mandelieu Arpt (CEQ)\',\'Canovan Island, Dominica - Canouan Island Municipal (CIW)\',\'Cape Dorset, Kanada - Cape Dorset Arpt (YTE)\',\'Cape Girardeau, USA - Cape Girardeau Municipal Arpt (CGI)\',\'Cape May, USA - Cape May Arpt (WWD)\',\'Caracas, Venezuela - Simon Bolivar Arpt (CCS)\',\'Carajas, Brasilien - Carajas Arpt (CKS)\',\'Carbondale, USA - Southern Illinois Arpt (MDH)\',\'Carcassonne, Frankreich - Salvaza (CCF)\',\'Cardiff, Grossbritannien - Cardiff Wales Arpt (CWL)\',\'Carlisle, Grossbritannien - Carlisle Arpt (CAX)\',\'Carlsbad, USA - Carlsbad Airport (CNM)\',\'Carlsberg, USA - Carlsbad Arpt (CLD)\',\'Carnarvon, Australien - Carnarvon Arpt (CVQ)\',\'Carriacou, Dominica - Lauriston Arpt (CRU)\',\'Carson City, USA - Carson Arpt (CSN)\',\'Cartagena, Kolumbien - Rafael Nunez Arpt (CTG)\',\'Caruaru, Brasilien - Caruaru Arpt (CAU)\',\'Casablanca, Marokko - Anfa Airport (CAS)\',\'Casablanca, Marokko - Mohamed V Arpt (CMN)\',\'Cascavel, Brasilien - Cascavel Arpt (CAC)\',\'Casino, Australien - Casino Arpt (CSI)\',\'Casper, USA - Natrona Cty Intl Arpt (CPR)\',\'Castlegar, Kanada - Ralph West Arpt (YCG)\',\'Castres, Frankreich - Mazamet Arpt (DCM)\',\'Catalina Island, USA (AVX)\',\'Catalina Island, USA - Catalina Arpt (SXC)\',\'Catamarca, Argentinien - Choya Arpt (CTC)\',\'Catania, Italien - Catania/Sizilien (CTA)\',\'Caticlan, Philippinen - Malay Arpt (MPH)\',\'Caxias Do Sul, Brasilien - Campo Dos Bugres Arpt (CXJ)\',\'Cayenne, Französisch-Guyana - Rochambeau Airport (CAY)\',\'Cayman Brac, Cayman Islands - Gerrard Smith Arpt (CYB)\',\'Cayo Largo Del SR, Kuba - Cayo Largo Del SR (CYO)\',\'Cebu, Philippinen - Cebu Intl (CEB)\',\'Cedar City, USA - Cedar City Municipal (CDC)\',\'Cedar Rapids, USA - Cedar Rapids Municipal Arpt (CID)\',\'Ceduna, Australien - Ceduna Arpt (CED)\',\'Centralia, USA - Centralia Municipal Arpt (ENL)\',\'Cessnock, Australien - Cessnock Arpt (CES)\',\'Chadron, USA - Chadron Arpt (CDR)\',\'Chambery, Frankreich - Chambery Aix Les Bains Arpt (CMF)\',\'Champaign, USA - Univ Of Illinois Willard Arpt (CMI)\',\'Chandigarh, Indien - Chandigarh Arpt (IXC)\',\'Chandler, USA - Williams Airforce Base (CHD)\',\'Changchun, China - Changchun Arpt (CGQ)\',\'Changde, China - Changde Arpt (CGD)\',\'Changsha, China - Changsha Arpt (CSX)\',\'Changzhou, China - Changzhou Arpt (CZX)\',\'Chania, Griechenland - Souda Arpt (CHQ)\',\'Chapeco, Brasilien - Chapeco Arpt (XAP)\',\'Chapelco, Argentinien - Chapelco Arpt (CPC)\',\'Charleston, USA - Charleston Intl Arpt (CHS)\',\'Charleston, USA - Yeager Arpt (CRW)\',\'Charleville, Australien - Charleville Arpt (CTL)\',\'Charlo, Kanada - Charlo Municipal Arpt (YCL)\',\'Charlotte, USA - Charlotte Douglas Intl Arpt (CLT)\',\'Charlottesville, USA - Charlottesville Albemarle Arpt (CHO)\',\'Charlottetown, Kanada - Charlottetown Minicipal Arpt (YHG)\',\'Charlottetown, Kanada - Charlottetown Municipal (YYG)\',\'Chateauroux, Frankreich - Chateauroux Arpt (CHR)\',\'Chatham, Kanada - Chatham Airport (XCM)\',\'Chatham, Kanada - Chatham Arpt (YCH)\',\'Chattanooga, USA - Chattanooga Lovell Fld (CHA)\',\'Cheju, Republik Korea - Cheju Airport (CJU)\',\'Cheju, Republik Korea - Chuja Heliport (JCJ)\',\'Cheju, Republik Korea - Seogwipo Heliport (JSP)\',\'Chelyabinsk, Russland - Chelyabinsk Arpt (CEK)\',\'Chengdu, China - Chengdu Arpt (CTU)\',\'Cheongju, Republik Korea - Cheongju Arpt (CJJ)\',\'Cherbourg, Frankreich - Maupertius Arpt (CER)\',\'Chester, Grossbritannien - Chester Arpt (CEG)\',\'Chesterfield Inlet, Kanada - Chesterfield Inlet Arpt (YCS)\',\'Chetumal, Mexiko - Chetumal International (CTM)\',\'Chevery, Kanada - Chevery Arpt (YHR)\',\'Cheyenne, USA - Cheyenne Arpt (CYS)\',\'Chiang Mai, Thailand - Chiang Mai Intl Arpt (CNX)\',\'Chiang Rei, Thailand - Chaing Rai Arpt (CEI)\',\'Chibougamau, Kanada - Chibougamau Arpt (YMT)\',\'Chicago, USA (CHI)\',\'Chicago, USA - Dupage County Arpt (DPA)\',\'Chicago, USA - Marriott Heliport (JMH)\',\'Chicago, USA - Meigs Field (CGX)\',\'Chicago, USA - Midway (MDW)\',\'Chicago, USA - OHare Intl Arpt (ORD)\',\'Chicago, USA - Pal Waukee Arpt (PWK)\',\'Chichen Itza, Mexiko - Chichen Itza Arpt (CZA)\',\'Chiclayo, Peru - Cornel Ruiz Arpt (CIX)\',\'Chico, USA - Chico Municipal Arpt (CIC)\',\'Chihuahua, Mexiko - Chihuahua Airport (CUU)\',\'Chilliwack, Kanada - Chilliwack Arpt (YCW)\',\'Chincoteague, USA - Wallops Arpt (WAL)\',\'Chinju, Republik Korea - Sacheon Arpt (HIN)\',\'Chios, Griechenland - Chios Arpt (JKH)\',\'Chisasibi, Kanada - Chisasibi Arpt (YKU)\',\'Chisinau, Moldawien - Chisinau (KIV)\',\'Chita, Russland - Chita Arpt (HTA)\',\'Chittagong, Bangladesh - Patenga Arpt (CGP)\',\'Cholet, Frankreich - Le Pontreau Arpt (CET)\',\'Chongqing, China - Chongqing Arpt (CKG)\',\'Christchurch, Neuseeland - Christchurch Intl Arpt (CHC)\',\'Chumphon, Thailand - Chumphon Arpt (CJM)\',\'Churchill, Kanada - Churchill Arpt (YYQ)\',\'Ciego de Avila, Kuba - Maximo Gomez Arpt (AVI)\',\'Cienfuegos, Kuba - Cienfuegos Arpt (CFG)\',\'Cilacap, Indonesien - Tunggul Wulung Arpt (CXP)\',\'Cincinnati, USA - Cincinnati Municipal Arpt (LUK)\',\'Cincinnati, USA - Cincinnati No Kentucky Intl Arpt (CVG)\',\'Cirebon, Indonesien - Penggung Arpt (CBN)\',\'Ciudad Bolivar, Venezuela - Ciudad Boliva Arpt (CBL)\',\'Ciudad Constitucion, Mexiko - Ciudad Constitucion Arpt (CUA)\',\'Ciudad Del Carmen, Mexiko - Ciudad Del Carmen Arpt (CME)\',\'Ciudad del Este, Paraguay - Alejo Garcia Arpt (AGT)\',\'Ciudad Guayana, Venezuela - Puerto Ordaz Arpt (PZO)\',\'Ciudad Juarez, Mexiko - Intl Abraham Gonzalez (CJS)\',\'Ciudad Mante, Mexiko - Ciudad Mante Arpt (MMC)\',\'Ciudad Obregon, Mexiko - Ciudad Obregon Arpt (CEN)\',\'Ciudad Real, Spanien - Ciudad Real Arpt (CJI)\',\'Ciudad Victoria, Mexiko - Ciudad Victoria Arpt (CVM)\',\'Clarksburg, USA - Clarksburg Benedum Arpt (CKB)\',\'Clarksdale, USA - Fletcher Field (CKM)\',\'Clarksville, USA - Outlaw Field (CKV)\',\'Clear Lake City, USA - Metroport (CLC)\',\'Clemson, USA - Clemson Oconee Cty Arpt (CEU)\',\'Clermont, Australien - Clermont Arpt (CMQ)\',\'Clermont-Ferrand, Frankreich - Aulnat Arpt (CFE)\',\'Cleveland, USA - Burke Lakefront Arpt (BKL)\',\'Cleveland, USA - Cuyahoga County Airport (CGF)\',\'Cleveland, USA - Hopkins Intl Arpt (CLE)\',\'Clinton, USA - Clinton Municipal (CWI)\',\'Clinton, USA - Clinton Municipal Arpt (CLK)\',\'Clinton, USA - Sherman Arpt (CSM)\',\'Cloncurry, Australien - Cloncurry Arpt (CNJ)\',\'Clovis, USA - Clovis Airport (CVN)\',\'Cluj, Rumänien - Napoca Arpt (CLJ)\',\'Clyde River, Kanada - Clyde River (YCY)\',\'Cobar, Australien - Cobar Arpt (CAZ)\',\'Cochabamba, Bolivien - J Wilsterman Arpt (CBB)\',\'Cochin, Indien - Cochin Airport (COK)\',\'Cocoa, USA - Merrit Island Arpt (COI)\',\'Cocoa, USA - Patrick AFB (COF)\',\'Coconut Island, Australien - Coconut Island Arpt (CNC)\',\'Cody, USA - Yellowstone Regional Arpt (COD)\',\'Coen, Australien - Coen Arpt (CUQ)\',\'Coeur D Alene, USA - Coeur d Alene Municipal Arpt (COE)\',\'Coffs Harbour, Australien - Coffs Harbour Arpt (CFS)\',\'Cognac, Frankreich - Parvaud Arpt (CNG)\',\'Coimbatore, Indien - Peelamedu Airport (CJB)\',\'Coimbra, Portugal - Coimbra Arpt (CBP)\',\'Colac, Australien - Colac Arpt (XCO)\',\'Colby, USA - Colby Municipal Arpt (CBK)\',\'Cold Lake, Kanada - Cold Lake Arpt (YOD)\',\'Colima, Mexiko - Colima Arpt (CLQ)\',\'College Station, USA - Easterwood Field (CLL)\',\'Collinsville, Australien - Collinsville Arpt (KCE)\',\'Colmar, Frankreich - Colmar Houssen Arpt (CMR)\',\'Colombo, Sri Lanka - Katunayake Arpt (CMB)\',\'Colonia, Uruguay - Colonia Arpt (CYR)\',\'Colorado Springs, USA - Colorado Springs Municipal Arpt (COS)\',\'Columbia, USA - Columbia Metro Arpt (CAE)\',\'Columbia, USA - Columbia Regional (COU)\',\'Columbia, USA - Maury Country Arpt (MRC)\',\'Columbia, USA - Orangeburg Municpal (OGB)\',\'Columbus, USA - Auburn Opelika (AUO)\',\'Columbus, USA - Columbus Arpt (OLU)\',\'Columbus, USA - Columbus Metro Ft Benning Arpt (CSG)\',\'Columbus, USA - Columbus Municipal (CUS)\',\'Columbus, USA - Columbus Municipal Arpt (CLU)\',\'Columbus, USA - Golden Arpt (GTR)\',\'Columbus, USA - Lowndes Cty Arpt (UBS)\',\'Columbus, USA - Ohio State Univ Arpt (OSU)\',\'Columbus, USA - Port Columbus Intl Arpt (CMH)\',\'Columbus, USA - Rickenbacker Intl Arpt (LCK)\',\'Colville, Kanada - Colville Municipal (YCK)\',\'Comodoro Rivadavia, Argentinien - Comodoro Rivadavia Arpt (CRD)\',\'Comox, Kanada - Royal Canadian Air Force Station (YQQ)\',\'Concepcion, Chile - Carriel Sur Arpt (CCP)\',\'Concepcion, Paraguay - Mcal Lopez Arpt (CIO)\',\'Concord, USA - Buchanan Field (CCR)\',\'Concordia, Argentinien - Concordia Arpt (COC)\',\'Connaught, Irland - Horan Intl Arpt (NOC)\',\'Conroe, USA - Montgomery Co Arpt (CXO)\',\'Constanta, Rumänien - Constanta (CND)\',\'Constantine, Algerien - Ain El Bey Arpt (CZL)\',\'Coober Pedy, Australien - Coober Pedy Arpt (CPD)\',\'Cooinda, Australien - Cooinda Airport (CDA)\',\'Cooktown, Australien - Cooktown Arpt (CTN)\',\'Cooma, Australien - Cooma Airport (OOM)\',\'Coonabarabrn, Australien - Coonabarabran Arpt (COJ)\',\'Coonamble, Australien - Coonamble Arpt (CNB)\',\'Copiapo, Chile - Chamonate Arpt (CPO)\',\'Coral Harbour, Kanada - Coral Harbour Arpt (YZS)\',\'Cordoba, Argentinien - Pajas Blanco Arpt (COR)\',\'Cordoba, Spanien - Cordoba Airport (ODB)\',\'Cordova, USA - Mile 13 Field (CDV)\',\'Corinth, USA - Roscoe Turner Arpt (CRX)\',\'Cork, Irland - Cork Arpt (ORK)\',\'Cornwall, Kanada - Cornwall Regional Arpt (YCC)\',\'Coro, Venezuela - Coro Arpt (CZE)\',\'Coromandel, Neuseeland - Coromandel Arpt (CMV)\',\'Corpus Christi, USA - Aransas County Arpt (RKP)\',\'Corpus Christi, USA - Corpus Christi Intl Arpt (CRP)\',\'Corrientes, Argentinien - Camba Punta Arpt (CNQ)\',\'Cortez, USA - Montezuma County (CEZ)\',\'Corumba, Brasilien - Internacional Corumba (CMG)\',\'Corvallis, USA - Corvallis Municipal Arpt (CVO)\',\'Corvo Island, Portugal - Corvo Arpt (CVU)\',\'Cotabato, Philippinen - Awang Arpt (CBO)\',\'Cottonwood, USA - Cottonwood Airport (CTW)\',\'Council Bluffs, USA - Council Bluffs Municipal Arpt (CBF)\',\'Courchevel, Frankreich - Courchevel Arpt (CVF)\',\'Coventry, Grossbritannien - Baginton Arpt (CVT)\',\'Cowra, Australien - Cowra Arpt (CWT)\',\'Coyhaique, Chile - Teniente Vidal Arpt (GXQ)\',\'Cozumel, Mexiko - Aeropuerto Intl De Cozumel (CZM)\',\'Craig, USA - Craig Moffat (CIG)\',\'Craig, USA - Craig Seaplane Base (CGA)\',\'Cranbrook, Kanada - Cranbrook Municipal (YXC)\',\'Creil, Frankreich - Creil Arpt (CSF)\',\'Crescent City, USA - Crescent City Municipal Arpt (CEC)\',\'Creston, Kanada - Creston Arpt (CFQ)\',\'Criciuma, Brasilien - Criciuma Arpt (CCM)\',\'Crotone, Italien - Crotone Arpt (CRV)\',\'Cruzeiro Do Sul, Brasilien - Campo Intl Arpt (CZS)\',\'Cucuta, Kolumbien - Camilo Dazo Arpt (CUC)\',\'Cuenca, Ecuador - Cuenca Arpt (CUE)\',\'Cuernavaca, Mexiko - Cuernavaca Arpt (CVJ)\',\'Cuibaba, Brasilien - Marechal Rondon Arpt (CGB)\',\'Culebra, USA - Culebra Arpt (CPX)\',\'Culiacan, Mexiko - Fedl De Bachigualato Arpt (CUL)\',\'Cumberland, USA - Cumberland Municipal Arpt (CBE)\',\'Cuneo, Italien - Levaldigi Arpt (CUF)\',\'Cunnamulla, Australien - Cunnamulla Arpt (CMA)\',\'Curacao, Niederländische Antillen - Areopuerto Hato Arpt (CUR)\',\'Curitiba, Brasilien - Afonso Pena Arpt (CWB)\',\'Cuzco, Peru - Tte Velazco Astete Arpt (CUZ)\',\'Da Nang, Vietnam - Da Nang Arpt (DAD)\',\'Dabolim, Indien - Dabolim Ariport (DBL)\',\'Dakhla Oasis, Ägypten - Dakhla Arpt (DAK)\',\'Dakhla, Marokko - Dakhla Airport (VIL)\',\'Dalaman, Türkei - Dalman Airport (DLM)\',\'Dalat, Vietnam - Lienkhang (DLI)\',\'Dalby, Australien - Dalby (DBY)\',\'Dalian, China - Dalian Airport (DLC)\',\'Dallas, USA - Addison Arpt (ADS)\',\'Dallas, USA - Dallas Ft Worth Intl (DFW)\',\'Dallas, USA - Love Field (DAL)\',\'Damascus, Syrien - Damascus Intl (DAM)\',\'Dammam, Saudi Arabien - King Fahad Arpt (DMM)\',\'Danbury, USA - Danbury Municipal Arpt (DXR)\',\'Danville, USA - Danville Municipal (DAN)\',\'Danville, USA - Vermillion Cty (DNV)\',\'Danzig, Polen - Rebiechowo (GDN)\',\'Dar Es Salam, Tansania - Es Salaam Intl (DAR)\',\'Darwin, Australien - Darwin Airport (DRW)\',\'Dashoguz, Turkmenistan - Dashoguz Arpt (TAZ)\',\'Davao, Philippinen - Mati Airport (DVO)\',\'Davenport, USA - Davenport Airport (DVN)\',\'Dawson City, Kanada - Dawson City Arpt (YDA)\',\'Dawson Creek, Kanada - Dawson Creek Arpt (YDQ)\',\'Daydream Island, Australien - Daydream Island Arpt (DDI)\',\'Dayong, China - Dayong Arpt (DYG)\',\'Dayton, USA - James M Cox Dayton Intl (DAY)\',\'Daytona Beach, USA - Daytona Beach Regional Arpt (DAB)\',\'Dease Lake, Kanada - Dease Lake Arpt (YDL)\',\'Deauville, Frankreich - Saint Gatien Arpt (DOL)\',\'Decatur, USA - Decatur Municipal (DEC)\',\'Decatur, USA - Pyor Arpt (DCU)\',\'Decorah, USA - Decorah Municipal (DEH)\',\'Deer Lake, Kanada - Deer Lake Arpt (YVZ)\',\'Deer Lake, Kanada - Deer Lake Municipal (YDF)\',\'Defiance, USA - Defiance Memorial Arpt (DFI)\',\'Del Rio, USA - International Del Rio (DRT)\',\'Delhi, Indien - Delhi Indira Gandhi Intl (DEL)\',\'Denham, Australien - Denham Arpt (DNM)\',\'Deniliquin, Australien - Denilinquin Arpt (DNQ)\',\'Denizli, Türkei - Cardak Arpt (DNZ)\',\'Denpasar, Indonesien - Ngurah Rai Arpt (DPS)\',\'Denver, USA - Centennial Airport (APA)\',\'Denver, USA - Denver International Airport (DEN)\',\'Derby, Australien - Derby Airport (DRB)\',\'Des Moines, USA - Des Moines Municipal Airport (DSM)\',\'Destin, USA - Destin Arpt (DSI)\',\'Detroit, USA (DTT)\',\'Detroit, USA - Berz Macomb Arpt (UIZ)\',\'Detroit, USA - Detroit City Apt (DET)\',\'Detroit, USA - Detroit Metro Arpt (DTW)\',\'Detroit, USA - Selfridge Air Natl Guard (MTC)\',\'Detroit, USA - Willow Run Arpt (YIP)\',\'Devils Lake, USA - Devils Lake Arpt (DVL)\',\'Devonport, Australien - Devonport Arpt (DPO)\',\'Dhahran, Saudi Arabien - Dhahran Intl (DHA)\',\'Dhaka, Bangladesh - Zia Intl Airport (DAC)\',\'Dickinson, USA - Dickinson Municipal (DIK)\',\'Diegosuarez, Madagaskar - Antsiranana Arrachart Arpt (DIE)\',\'Dien Bien Phu, Vietnam - Gialam Arpt (DIN)\',\'Dieppe, Frankreich - Dieppe Arpt (DPE)\',\'Dijon, Frankreich - Longvic Airport (DIJ)\',\'Dillingham, USA - Dillingham Municipal Arpt (DLG)\',\'Dillon, USA - Dillon Arpt (DLL)\',\'Dinard, Frankreich - Pleurtuit Arpt (DNR)\',\'Dipolog, Philippinen - Dipolog Arpt (DPL)\',\'Diqing, China - Diging Arpt (DIG)\',\'Dire Dawa, Äthiopien - Aba Tenna D Yilma Arpt (DIR)\',\'Diu In, Indien - Diu Arpt (DIU)\',\'Djerba, Tunesien - Melita Airport (DJE)\',\'Dnepropetrovsk, Ukraine - Dnepropetrovsk Arpt (DNK)\',\'Dodge City, USA - Dodge City Municipal Arpt (DDC)\',\'Doha, Qatar - Doha Airport (DOH)\',\'Dole, Frankreich - Tavaux Arpt (DLE)\',\'Dominica, Dominica - Canefield Arpt (DCF)\',\'Dominica, Dominica - Melville Hall Arpt (DOM)\',\'Doncaster, Grossbritannien - Finningley (DCS)\',\'Donegal, Irland - Donegal Arpt (CFN)\',\'Donetsk, Ukraine - Donetsk Arpt (DOK)\',\'Dongara, Australien - Dongara (DOX)\',\'Dongguan, China - Dongguan Arpt (DGM)\',\'Doomadgee, Australien - Doomadgee Arpt (DMD)\',\'Dornoch, Grossbritannien - Dornoch Arpt (DOC)\',\'Dortmund, Deutschland - Dortmund (DTM)\',\'Dothan, USA - Dothan Municipal (DHN)\',\'Douglas, USA - Bisbee Douglas Intl (DUG)\',\'Dover, USA - Delaware Airpark (DVX)\',\'Dover, USA - Dover AFB (DOV)\',\'Doylestown, USA - Doylestown Arpt (DYL)\',\'Dresden, Deutschland - Dresden (DRS)\',\'Dryden, Kanada - Dryden Municipal (YHD)\',\'Dschibuti, Djibouti - Ambouli Airport (JIB)\',\'Dubai, VAE - Dubai Intl Arpt (DXB)\',\'Dubbo, Australien - Dubbo Arpt (DBO)\',\'Dublin, Irland - Dublin Arpt (DUB)\',\'Dublin, USA - Dublin Municipal Arpt (DBN)\',\'Dubois, USA - Dubois Jefferson Cty Arpt (DUJ)\',\'Dubrovnik, Kroatien - Dubrovnik Arpt (DBV)\',\'Dubuque, USA - Dubuque Municipal Arpt (DBQ)\',\'Düsseldorf, Deutschland - Düsseldorf (DUS)\',\'Düsseldorf, Deutschland - Mönchengladbach (MGL)\',\'Duluth, USA - Duluth Intl (DLH)\',\'Dundee, Grossbritannien - Riverside Park Arpt (DND)\',\'Dunedin, Neuseeland - Momona Airport (DUD)\',\'Dunk Island, Australien - Dunk Island Arpt (DKI)\',\'Dunkerque, Frankreich - Dunkerque Arpt (XDK)\',\'Durango, Mexiko - Guadalupe Victoria Arpt (DGO)\',\'Durango, USA - Durango La Plata Cty Arpt (DRO)\',\'Durban, Südafrika - Louis Botha Aprt (DUR)\',\'Durban, Südafrika - Virginia Arpt (VIR)\',\'Dushanbe, Tadschikistan - Dushanbe Arpt (DYU)\',\'Dutch Harbor, USA - Emergency Field (DUT)\',\'Eagle Pass, USA - Maverick County Arpt (EGP)\',\'Eagle River, USA - Eagle River Union Arpt (EGV)\',\'Eagle, USA - Eagle Airport (EAA)\',\'East Hampton, USA - East Hampton Arpt (HTO)\',\'East Hartford, USA - Rentschler Arpt (EHT)\',\'East London, Südafrika - Ben Schoeman Arpt (ELS)\',\'East Sound, USA - Eastsound Orcas Is Arpt (ESD)\',\'East Stroudsburg, USA - Birchwood Pocono Arpt (ESP)\',\'Easter Island, Chile - Mataveri Intl Arpt (IPC)\',\'Easton, USA - Easton Municipal Arpt (ESN)\',\'Eau Claire, USA - Claire Municipal Airport (EAU)\',\'Echuca, Australien - Echuca Arpt (ECH)\',\'Eday, Grossbritannien - Eday Arpt (EOI)\',\'Edinburgh, Grossbritannien - Turnhouse Arpt (EDI)\',\'Edmonton, Kanada (YEA)\',\'Edmonton, Kanada - Edmonton Intl Arpt (YEG)\',\'Edmonton, Kanada - Edmonton Municipal Arpt (YXD)\',\'Edmonton, Kanada - Namao Field (YED)\',\'Edson, Kanada - Edson Arpt (YET)\',\'Edward River, Australien - Edward River Arpt (EDR)\',\'Egilsstadir, Island - Egilsstadir Arpt (EGS)\',\'Eilat, Israel - Elat Airport (ETH)\',\'Eindhoven, Niederlande - Welschap Arpt (EIN)\',\'Ekaterinburg, Russland - Sverdolovsk Arpt (SVX)\',\'El Aaiun, Marokko - Hassan I Arpt (EUN)\',\'El Cajon, USA - El Cajon Arpt (CJN)\',\'El Calafate, Argentinien - El Calafate Arpt (FTE)\',\'El Centro, USA - Imperial County (IPL)\',\'El Dorado, USA - Goodwin Field (ELD)\',\'El Monte, USA - El Monte Arpt (EMT)\',\'El Paso, USA - Biggs Army Air Field (BIF)\',\'El Paso, USA - El Paso Intl Arpt (ELP)\',\'El Salvador, Chile - El Salvador Arpt (ESR)\',\'El Vigia, Venezuela - El Vigia Arpt (VIG)\',\'Elazig, Türkei - Elazig (EZS)\',\'Elba, Italien - Marina Di Campo Arpt (EBA)\',\'Elista, Russland - Elista Arpt (ESL)\',\'Elizabeth City, USA - Elizabeth Municipal Cgas (ECG)\',\'Elizabethtown, USA - Addington Field (EKX)\',\'Elk City, USA - Elk City Municipal (ELK)\',\'Elkhardt, USA - Elkhart Municipal Arpt (EKI)\',\'Elkins, USA - Randolph County Arpt (EKN)\',\'Elko, USA - J C Harris Field (EKO)\',\'Elliot Lake, Kanada - Elliot Lake Arpt (YEL)\',\'Elmira, USA - Elmira Corning Regional Arpt (ELM)\',\'Ely Mn, USA - Ely Municipal Arpt (LYU)\',\'Ely, USA - Yelland Field (ELY)\',\'Emerald, Australien - Emerald Arpt (EMD)\',\'Enid, USA - Woodring Municipal (WDG)\',\'Enniskillen, Irland - St Angelo Arpt (ENK)\',\'Ensenada, Mexiko - Ensenada Arpt (ESE)\',\'Entebbe, Uganda - Entebbe Airport (EBB)\',\'Enterprise, USA - Enterprise Municipal (ETS)\',\'Epinal, Frankreich - Mirecourt Arpt (EPL)\',\'Ercan, Zypern - Ercan Airport (ECN)\',\'Erfurt, Deutschland - Erfurt (ERF)\',\'Erie, USA - Erie Intl (ERI)\',\'Eriwan, Armenien - Eriwan - Intl. Flughafen Zvartnoz (EVN)\',\'Erzincan, Türkei - Erzincan Arpt (ERC)\',\'Erzurum, Türkei - Erzurum Arpt (ERZ)\',\'Esbjerg, Dänemark - Esbjerg Arpt (EBJ)\',\'Escanaba, USA - Delta County (ESC)\',\'Eskilstuna, Schweden - Eskilstuna Arpt (EKT)\',\'Esperance, Australien - Esperance Arpt (EPR)\',\'Esquel, Argentinien - Esquel Airport (EQS)\',\'Essaouira, Marokko - Essaouira Arpt (ESU)\',\'Estevan, Kanada - Estevan Arpt (YEN)\',\'Eufaula, USA - Weedon Field (EUF)\',\'Eugene, USA - Eugene Arpt (EUG)\',\'Evansville, USA - Evansville Regional Arpt (EVV)\',\'Eveleth, USA - Eveleth Virginia Municipal Arpt (EVM)\',\'Evenes, Norwegen - Evenes Arpt (EVE)\',\'Everett, USA - Snohomish Cty Arpt (PAE)\',\'Evreux, Frankreich - Evreux Arpt (EVX)\',\'Excursion Inlet, USA - Excursion Inlet Municipal (EXI)\',\'Exeter, Grossbritannien - Exeter Arpt (EXT)\',\'Exmouth Gulf, Australien - Exmouth Gulf (EXM)\',\'Fagernes, Norwegen - Valdres Arpt (VDB)\',\'Fair Isle, Grossbritannien - Fair Isle Arpt (FIE)\',\'Fairbanks, USA - Fairbanks Intl Arpt (FAI)\',\'Fairfield, USA - Travis AFB (SUU)\',\'Fairmont Springs, Kanada - Fairmont Springs Arpt (YCZ)\',\'Fairmont, USA - Fairmont Municipal (FRM)\',\'Fajardo, USA - Fajardo Arpt (FAJ)\',\'Fallon, USA (NFL)\',\'Fallon, USA - Fallon Municipal Arpt (FLX)\',\'Falmouth, USA - Otis AFB (FMH)\',\'Falun, Schweden - Dala Airport (BLE)\',\'Fargo, USA - Hector Airport (FAR)\',\'Farmingdale, USA - Republic Arpt (FRG)\',\'Farmington, USA - Four Corners Regional Arpt (FMN)\',\'Faro, Portugal - Faro Airport (FAO)\',\'Faroe Islands, Dänemark - Faeroe Airport (FAE)\',\'Fayetteville, USA - Fayetteville Municipal (FAY)\',\'Fergus Falls, USA - Fergus Falls Minicipal Arpt (FFM)\',\'Fernando De Noronha, Brasilien - Fernando De Noronha Arpt (FEN)\',\'Fez, Marokko - Fez Airport (FEZ)\',\'Ficksburg, Südafrika - Ficksburg Sentra Oes (FCB)\',\'Figari, Frankreich - Sud Corse Arpt (FSC)\',\'Flagstaff, USA - Flagstaff Arpt (FLG)\',\'Flin Flon, Kanada - Flin Flon Municipal Arpt (YFO)\',\'Flint, USA - Bishop Intl Arpt (FNT)\',\'Flippin, USA - Flippin Arpt (FLP)\',\'Florence, USA - Gilbert Field (FLO)\',\'Florenz, Italien - Florenz (FLR)\',\'Floriano, Brasilien - Cangapara Arpt (FLB)\',\'Florianopolis, Brasilien - Hercilio Luz Arpt (FLN)\',\'Floro, Norwegen - Florelandet Arpt (FRO)\',\'Foggia, Italien - Gino Lisa Arpt (FOG)\',\'Forde, Norwegen - Flughafen Førde (FDE)\',\'Forli, Italien - Luigi Ridolfi Arpt (FRL)\',\'Formosa, Argentinien - El Pucu Arpt (FMA)\',\'Forrest City, USA - Forrest City Municipal Arpt (FCY)\',\'Forster, Australien - Forster (FOT)\',\'Fort Collins, USA - Municipal Airport (FNL)\',\'Fort de France, Martinique - Lamentin Arpt (FDF)\',\'Fort Dodge, USA - Fort Dodge Municipal (FOD)\',\'Fort Frances, Kanada - Fort Frances Municipal (YAG)\',\'Fort Huachuca, USA - Sierra Vista Municipal (FHU)\',\'Fort Lauderdale, USA - Boca Raton Public (BCT)\',\'Fort Lauderdale, USA - Fort Lauderdale Hollywood Intl Arpt (FLL)\',\'Fort Lauderdale, USA - Ft Lauderdale Excutive (FXE)\',\'Fort Leonard Wood, USA - Forney Field (TBN)\',\'Fort Madison, USA - Fort Madison Municipal (FMS)\',\'Fort McMurray, Kanada - Fort McMurray Municipal Arpt (YMM)\',\'Fort Myers, USA - Regional Southwest Arpt (RSW)\',\'Fort Nelson, Kanada - Fort Nelson Municipal Arpt (YYE)\',\'Fort Pierce, USA - Saint Lucie County Arpt (FPR)\',\'Fort Polk, USA - Fort Polk Arpt (POE)\',\'Fort Smith, Kanada - Fort Smith Municipal Arpt (YSM)\',\'Fort Smith, USA - Fort Smith Municipal (FSM)\',\'Fort St John, Kanada - Fort St John Municipal Arpt (YXJ)\',\'Fort Stockton, USA - Pecos County Arpt (FST)\',\'Fort Walton Beach, USA - Okaloosa Cty Arpt (VPS)\',\'Fort Wayne, USA - Baer Field (FWA)\',\'Fort William, Grossbritannien - Fort William Arpt (FWM)\',\'Fort Worth, USA - Meacham Field (FTW)\',\'Fort Yukon, USA - Fayetteville Municipal Arpt (FYV)\',\'Fort Yukon, USA - Northwest Arkansas Regional Arpt (XNA)\',\'Fortaleza, Brasilien - Pinto Martines Arpt (FOR)\',\'Frankfurt / Main, Deutschland - Frankfurt Hahn (HHN)\',\'Frankfurt / Main, Deutschland - Frankfurt Main (FRA)\',\'Franklin Chess, USA - Chess Lamberton Arpt (FKL)\',\'Frederick, USA - Frederick Municipal (FDK)\',\'Fredericton, Kanada - Fredericton Municipal (YFC)\',\'Freeport, Bahamas - Freeport Intl Arpt (FPO)\',\'Frejus, Frankreich - Frejus Arpt (FRJ)\',\'Fremantle, Australien - Fremantle Heliport (JFM)\',\'Fresno, USA - Fresno Air Terminal (FAT)\',\'Fresno, USA - Fresno Chandler Arpt (FCH)\',\'Friday Harbor, USA - Friday Harbor Airport (FRD)\',\'Friedrichshafen, Deutschland - Friedrichshafen Löwenthal (FDH)\',\'Front Royal, USA - Warren County Arpt (FRR)\',\'Fuerte Olimpo, Paraguay - Fuerte Olimpo Arpt (OLK)\',\'Fuerteventura, Spanien - Fuerteventura Arpt (FUE)\',\'Fukue, Japan - Fukue Arpt (FUJ)\',\'Fukuoka, Japan - Itazuke Arpt (FUK)\',\'Fukushima, Japan - Fukushima Arpt (FKS)\',\'Fullerton, USA - Fullerton Municipal Arpt (FUL)\',\'Funchal, Portugal - Funchal Airport (FNC)\',\'Fuzhou, China - Fuzhou Arpt (FOC)\',\'Gadsden, USA - Gadsden Municipal (GAD)\',\'Gainesville, USA - Gainesville Municipal Arpt (GLE)\',\'Gainesville, USA - Gainesville Regional (GNV)\',\'Gaithersburg, USA - Montgomery Cty Arpt (GAI)\',\'Galapagos Is, Ecuador - Baltra Arpt (GPS)\',\'Galena, USA - Galena Arpt (GAL)\',\'Galesburg, USA - Galesburg Arpt (GBG)\',\'Galion, USA - Galion Municipal Arpt (GQQ)\',\'Gallivare, Schweden - Gallivare Arpt (GEV)\',\'Gallup, USA - Gallup Municipal (GUP)\',\'Galveston, USA - Scholes Field (GLS)\',\'Galway, Irland - Carnmore Arpt (GWY)\',\'Gander, Kanada - Gander International (YQX)\',\'Ganzhou, China - Ganzhou Arpt (KOW)\',\'Gap France, Frankreich - Tallard Arpt (GAT)\',\'Garden City, USA - Garden City Municipal (GCK)\',\'Gary, USA - Gary Regional Arpt (GYY)\',\'Gaspe, Kanada - Gaspe Municipal Arpt (YGP)\',\'Gassim, Saudi Arabien - Gassim Arpt (ELQ)\',\'Gatineau Hull, Kanada - Gatineau Hull Minicipal Arpt (YND)\',\'Gatlinburg, USA - Gatlinburg Arpt (GKT)\',\'Gavle, Schweden - Sandviken Arpt (GVX)\',\'Gaya, Indien - Gaya Arpt (GAY)\',\'Gaylord, USA - Otsego Arpt (GLR)\',\'Geelong, Australien - Geelong (GEX)\',\'Geilo, Norwegen - Dagali Arpt (DLD)\',\'General Santos, Philippinen - Buayan Arpt (GES)\',\'Genf, Schweiz - Geneva Arpt (GVA)\',\'Genua, Italien - Christoforo Colombo (GOA)\',\'George, Südafrika - P W Botha (GRJ)\',\'Georgetown, Bahamas - George Town Airport (GGT)\',\'Georgetown, Guyana - Timehri Airport (GEO)\',\'Georgetown, USA - Sussex County Arpt (GED)\',\'Geraldton, Australien - Geraldton Arpt (GET)\',\'Gerona, Spanien - Costa Brava Arpt (GRO)\',\'Gethsemanie, Kanada - Gethsemanie Arpt (ZGS)\',\'Gettysburg, USA - Gettysburg Arpt (GTY)\',\'Ghardaia, Algerien - Noumerate Arpt (GHA)\',\'Gibraltar, Gibraltar - North Front Arpt (GIB)\',\'Gilgit, Pakistan - Gilgit Arpt (GIL)\',\'Gillette, USA - Campbell Cty Arpt (GCC)\',\'Gisborne, Neuseeland - Gisborne Arpt (GIS)\',\'Gizan, Saudi Arabien - Gizan Aprt (GIZ)\',\'Gjoa Haven, Kanada - Gjoa Haven Arpt (YHK)\',\'Gladstone, Australien - Gladstone Airport (GLT)\',\'Glasgow, Grossbritannien - Glasgow International (GLA)\',\'Glasgow, Grossbritannien - Prestwick Arpt (PIK)\',\'Glasgow, USA - International Glasgow (GGW)\',\'Glen Falls, USA - Warren County (GFL)\',\'Glen Innes, Australien - Glen Innes Arpt (GLI)\',\'Glenwood Springs, USA - Glenwood Springs Arpt (GWS)\',\'Gloucester, Grossbritannien - Staverton Arpt (GLO)\',\'Goa, Indien - Dabolim Arpt (GOI)\',\'Göteborg, Schweden - Landvetter Arpt (GOT)\',\'Göteborg, Schweden - Saeve Arpt (GSE)\',\'Goiania, Brasilien - Santa Genoveva (GYN)\',\'Gol City, Norwegen - Klanten Arpt (GLL)\',\'Gold Coast, Australien - Coolangatta Arpt (OOL)\',\'Goldsboro, USA - Seymour Johnson AFB (GSB)\',\'Gomel, Weißrussland - Gomel Arpt (GME)\',\'Goodland, USA - Goodland Municipal (GLD)\',\'Goodyear, USA - Litchfield Goodyear Arpt (GYR)\',\'Goondiwindi, Australien - Goondiwindi Arpt (GOO)\',\'Goose Bay, Kanada - Goose Bay Municipal Arpt (YYR)\',\'Goroka, Papua Neu Guinea - Goroka Arpt (GKA)\',\'Goulburn, Australien - Majors Field Arpt (GUL)\',\'Gove, Australien - Nhulunbuy Arpt (GOV)\',\'Governador Valadares, Brasilien - Governador Valadares Arpt (GVR)\',\'Governor S Harbour, Bahamas - Governors Harbour Municipal Arpt (GHB)\',\'Graciosa Island, Portugal - Graciosa Arpt (GRW)\',\'Grafton, Australien - Grafton Arpt (GFN)\',\'Granada, Spanien - Granada Arpt (GRX)\',\'Grand Canyon, USA - Grand Canyon Natl Park Arpt (GCN)\',\'Grand Cayman, Cayman Islands - Owen Roberts Arpt (GCM)\',\'Grand Forks, USA - Grand Forks Mark Andrews Intl (GFK)\',\'Grand Island, USA - Hall Cty Regional (GRI)\',\'Grand Junction, USA - Walker Field (GJT)\',\'Grand Rapids, USA - Itasca County (GPZ)\',\'Grand Rapids, USA - Kent County Intl (GRR)\',\'Grand Turk, Turks- und Caicosinseln - Grand Turk Is Arpt (GDT)\',\'Grande Prairie, Kanada - Grande Prairie Arpt (YQU)\',\'Gravatai, Brasilien - Gravatai Arpt (GCV)\',\'Graz, Österreich - Thalerhof Arpt (GRZ)\',\'Great Barrier Island, Neuseeland - Great Barrier Island Arpt (GBZ)\',\'Great Barrington, USA - Great Barrington Arpt (GBR)\',\'Great Bend, USA - Greate Bend Municipal (GBD)\',\'Great Falls, USA - Great Falls Intl Arpt (GTF)\',\'Green Bay, USA - Austin Straubel Fld (GRB)\',\'Green River, USA - Green River Arpt (RVR)\',\'Greenfield, USA - Pope Field Arpt (GFD)\',\'Greensboro-Highpt, USA - Piedmont Triad Intl (GSO)\',\'Greenville, USA - Downtown Memorial (SPA)\',\'Greenville, USA - Greenville Downtown Arpt (GMU)\',\'Greenville, USA - Greenville Municipal (GLH)\',\'Greenville, USA - Greenville Spartanburg Arpt (GSP)\',\'Greenville, USA - Municipal Greenville (GCY)\',\'Greenville, USA - Pitt Greenville Arpt (PGV)\',\'Greenwood, USA - Leflore Arpt (GWO)\',\'Grenada, Dominica - Port Saline Intl (GND)\',\'Grenoble, Frankreich - Saint Geoirs Arpt (GNB)\',\'Griffith, Australien - Griffith Arpt (GFF)\',\'Grimsby, Grossbritannien - Binbrook Arpt (GSY)\',\'Grodna, Weißrussland - Grodna Arpt (GNA)\',\'Grosseto, Italien - Baccarini Arpt (GRS)\',\'Guadalajara, Mexiko - Miguel Hidalgo Arpt (GDL)\',\'Guam Agana Fld, Guam - Agana Field (GUM)\',\'Guam Agana Fld, Guam - Anderson Air Force Base (UAM)\',\'Guang Yuan, China - Guang Yuan Arpt (GYS)\',\'Guangzhou, China - Baiyun Airport (CAN)\',\'Guatemala City, Guatemala - La Aurora Arpt (GUA)\',\'Guayaquil, Ecuador - Simon Bolivar Airport (GYE)\',\'Guaymas, Mexiko - Gen Jose M Yanez Arpt (GYM)\',\'Guernsey, Grossbritannien - Guernsey Arpt (GCI)\',\'Guilin, China - Guilin Airport (KWL)\',\'Guiyang, China - Guiyang Arpt (KWE)\',\'Gulf Shores, USA - Edwards Arpt (GUF)\',\'Gulfport, USA - Gulfport Billoxi (GPT)\',\'Gunnedah, Australien - Gunnedah Airport (GUH)\',\'Gunnison, USA - Gunnison Cty (GUC)\',\'Gunungsitoli, Indonesien - Gunungsitoli Arpt (GNS)\',\'Gustavus, USA - Gustavus Arpt (GST)\',\'Guwahati, Indien - Borjhar Arpt (GAU)\',\'Guymon, USA - Guymon Municipal Arpt (GUY)\',\'Gweru, Simbabwe - Gweru Airport (GWE)\',\'Gympie, Australien - Gympie Arpt (GYP)\',\'Ha Apai, Tonga - Salote Pilolevu Arpt (HPA)\',\'Hachijo Jima, Japan - Hachijo Jima Arpt (HAC)\',\'Hafr Albatin, Saudi Arabien - Hafr Albatin Arpt (HBT)\',\'Hagerstown, USA - Washington Cty Regional (HGR)\',\'Haifa, Israel - Haifa Arpt (HFA)\',\'Haikou, China - Haikou Arpt (HAK)\',\'Hail, Saudi Arabien - Hail Arpt (HAS)\',\'Haines, USA - Haines Municipal Arpt (HNS)\',\'Haiphong, Vietnam - Catbi Arpt (HPH)\',\'Hakodate, Japan - Hakodate Arpt (HKD)\',\'Halifax, Kanada - Halifax Intl (YHZ)\',\'Halmstad, Schweden - Halmstad Arpt (HAD)\',\'Hamar, Norwegen - Hamar Arpt (HMR)\',\'Hamburg, Deutschland - Hamburg (HAM)\',\'Hamburg, Deutschland - Hamburg-Finkenwerder (XFW)\',\'Hamilton Island, Australien - Hamilton Island Arpt (HTI)\',\'Hamilton, Kanada - Civic Airport (YHM)\',\'Hamilton, Neuseeland - Hamilton Arpt (HLZ)\',\'Hammerfest, Norwegen - Hammerfest Arpt (HFT)\',\'Hampton, USA - Patrick Henry Intl (PHF)\',\'Hana, USA - Hana Municipal (HNM)\',\'Hangzhou, China - Hangzhou Arpt (HGH)\',\'Hanksville, USA - Intermediate Arpt (HVE)\',\'Hannover, Deutschland - Hannover (HAJ)\',\'Hanoi, Vietnam - Noibai Arpt (HAN)\',\'Harare, Simbabwe - Harare Arpt (HRE)\',\'Harbin, China - Harbin Arpt (HRB)\',\'Harbour Island, Bahamas - Harbour Island Arpt (HBI)\',\'Harlingen, USA - Industrial Airpark (HRL)\',\'Harrisburg, USA (HAR)\',\'Harrisburg, USA - Harrisburg Intl (MDT)\',\'Harrismith, Südafrika - Harrismith Arpt (HRS)\',\'Harrison, USA - Boone County Arpt (HRO)\',\'Harrogate, Grossbritannien - Linton On Ouse (HRT)\',\'Hastings, USA - Hastings Municipal (HSI)\',\'Hat Yai, Thailand - Hat Yai Arpt (HDY)\',\'Hatfield, Grossbritannien - Hatfield Arpt (HTF)\',\'Hattiesburg, USA - Bobby L Chain Municipal (HBG)\',\'Haugesund, Norwegen - Karmoy Arpt (HAU)\',\'Havanna, Kuba - Jose Marti Intl Arpt (HAV)\',\'Havre St Pierre, Kanada - Havre St Pierre Municipal Arpt (YGV)\',\'Havre, USA - City County (HVR)\',\'Hawthorne, USA - Hawthorne Arpt (HHR)\',\'Hay River, Kanada - Hay River Municipal Arpt (YHY)\',\'Hayden Yamba Valley, USA - Hayden Arpt (HDN)\',\'Hayman Island, Australien - Hayman Island Arpt (HIS)\',\'Hays, USA - Hays Municipal (HYS)\',\'Hayward, USA - Hayward Air Terminal (HWD)\',\'Hayward, USA - Hayward Municipal (HYR)\',\'Healy Lake, USA - Healy Lake Arpt (HKB)\',\'Hearst, Kanada - Hearst Municipal Arpt (YHF)\',\'Hefei, China - Hefei Arpt (HFE)\',\'Helena, USA - Helena Municipal (HLN)\',\'Helgoland, Deutschland - Flugplatz Helgoland-Düne (HGL)\',\'Helsingborg, Schweden - Angelholm Helsingborg Arpt (AGH)\',\'Helsingborg, Schweden - Helsingborg Heliport (JHE)\',\'Helsinki, Finnland - Helsinki Arpt (HEL)\',\'Hengchun, Taiwan, Republik China - Hengchun Arpt (HCN)\',\'Hengyang, China - Hengyang Arpt (HNY)\',\'Heraklion, Griechenland - N Kazantzakis Arpt (HER)\',\'Heringsdorf / Usedom, Deutschland - Heringsdorf / Usedom (HDF)\',\'Hermosillo, Mexiko - Gen Ignacio Pesqueira Garcia Arpt (HMO)\',\'Hervey Bay, Australien - Hervey Bay (HVB)\',\'Hibbing, USA - Hibbing Chisolm Arpt (HIB)\',\'Hickory, USA - Hickory Municipal (HKY)\',\'High Level, Kanada - Footner Lake Arpt (YOJ)\',\'Hillsboro, USA - Portland Hillsboro Arpt (HIO)\',\'Hilo/Hawaii, USA - Hilo Hawaii Intl (ITO)\',\'Hilton Head Island, USA - Hilton Head Municipal (HHH)\',\'Hiroshima, Japan - Hiroshima Airport (HIJ)\',\'Hluhluwe, Südafrika - Hluhluwe Arpt (HLW)\',\'Ho Chi Minh City, Vietnam - Tan Son Nhut Arpt (SGN)\',\'Hobart, Australien - Hobart Arpt (HBA)\',\'Hobbs, USA - Lea County Arpt (HOB)\',\'Hoedspruit, Südafrika - Hoedspruit Arpt (HDS)\',\'Hof, Deutschland - Hof Pirk Arpt (HOQ)\',\'Hofn, Island - Hornafjordur Arpt (HFN)\',\'Hohhot, China - Hohhot Arpt (HET)\',\'Hokitika, Neuseeland - Hokitika Airport (HKK)\',\'Holguin, Kuba - Holguin (HOG)\',\'Holland, USA - Park Township (HLM)\',\'Homer, USA - Homer Municipal Arpt (HOM)\',\'Homestead, USA - Homestead Municipal (HST)\',\'Hongkong, Hong Kong - Hongkong Intl (HKG)\',\'Honningsvag, Norwegen - Valan Arpt (HVG)\',\'Honolulu, USA - Hickam Air Force Base (HIK)\',\'Honolulu, USA - Honolulu Intl (HNL)\',\'Hoolehua, USA - Hoolehua Municipal (MKK)\',\'Hoonah, USA - Hoonah Municipal Arpt (HNH)\',\'Hope, Kanada - Hope Arpt (YHE)\',\'Hopkinsville, USA - Hopkinsville Christian Country Arpt (HOP)\',\'Horizontina, Brasilien - Horizontina Arpt (HRZ)\',\'Horn Island, Australien - Horn Island Arpt (HID)\',\'Horta, Portugal - Horta Arpt (HOR)\',\'Hoskins, Papua Neu Guinea - Hoskins Arpt (HKN)\',\'Hot Springs, USA - Ingalls Field (HSP)\',\'Hot Springs, USA - Memorial Field (HOT)\',\'Houghton, USA - Houghton Cty Memorial Arpt (CMX)\',\'Houma, USA - Terrebonne Arpt (HUM)\',\'Houston, USA - Andrau Airpark (AAP)\',\'Houston, USA - David Wayne Hooks Arpt (DWH)\',\'Houston, USA - Ellington Field (EFD)\',\'Houston, USA - Houston Hobby Arpt (HOU)\',\'Houston, USA - Houston Intl (IAH)\',\'Houston, USA - West Houston (IWS)\',\'Hsinchun, Taiwan, Republik China - Hsinchun Arpt (HSZ)\',\'Hu PG, Vietnam - Phu Bai Arpt (HUI)\',\'Hua Hin, Thailand - Hua Hin Arpt (HHQ)\',\'Huahine, Französisch-Polynesien - Flying Boat Arpt (HUH)\',\'Hualien, Taiwan, Republik China - Hualien Arpt (HUN)\',\'Huanghua, China - Changsha Huanghua Arpt (HHA)\',\'Huangyan, China - Huangyan Arpt (HYN)\',\'Huanuco, Peru - Huanuco Arpt (HUU)\',\'Huatulco, Mexiko - Bahia De Huatulco Arpt (HUX)\',\'Hudiksvall, Schweden - Hudiksvall Arpt (HUV)\',\'Hughenden, Australien - Hughenden Arpt (HGD)\',\'Huizhou, China - Huizhou Arpt (HUZ)\',\'Hultsfred, Schweden - Hultsfred Arpt (HLF)\',\'Humacao, USA - Humacao Arpt (HUC)\',\'Humberside, Grossbritannien - Humberside Arpt (HUY)\',\'Huntingburg, USA - Huntingburg Municipal (HNB)\',\'Huntington, USA - Portsmith Regional (PMH)\',\'Huntington, USA - Tri State Milton Arpt (HTS)\',\'Huntsville, USA - Huntsville Arpt (HTV)\',\'Huntsville, USA - Huntsville Madison Cty Jetplex (HSV)\',\'Hurghada, Ägypten - Hurghada Airport (HRG)\',\'Huron, USA - Huron Municipal (HON)\',\'Hutchinson, USA - Hutchinson Municipal (HUT)\',\'Hyannis, USA - Barnstable Cty Arpt (HYA)\',\'Hyderabad, Indien - Begumpet Arpt (HYD)\',\'Hyderabad, Pakistan - Hyderabad (HDD)\',\'Hyeres, Frankreich - Le Palyvestre Arpt (TLN)\',\'Iasi, Rumänien - Iasi Arpt (IAS)\',\'Ibiza, Spanien - Ibiza (IBZ)\',\'Idaho Falls, USA - Fanning Field (IDA)\',\'Iguassu Falls, Brasilien - Cataratas Arpt (IGU)\',\'Iguatu, Brasilien - Iguatu Arpt (QIG)\',\'Iguazu, Argentinien - Iguazu Intl (IGR)\',\'Ikaria Island, Griechenland - Ikaria Arpt (JIK)\',\'Iles De Madeleine, Kanada - House Harbour Arpt (YGR)\',\'Ilheus, Brasilien - Eduardo Gomes Airport (IOS)\',\'Iloilo, Philippinen - Mandurriao Arpt (ILO)\',\'Imperatriz, Brasilien - Imperatriz Arpt (IMP)\',\'Indiana, USA - Indiana County Arpt (IDI)\',\'Indianapolis, USA - Indianapolis Intl Arpt (IND)\',\'Indore, Indien - Indore Arpt (IDR)\',\'Innsbruck, Österreich - Kranebitten Airport (INN)\',\'International Falls, USA - Intl Falls Arpt (INL)\',\'Inukjuak, Kanada - Inukjuak Arpt (YPH)\',\'Inuvik, Kanada - Inuvik Airport (YEV)\',\'Invercargill, Neuseeland - Invercargill Arpt (IVC)\',\'Inverell, Australien - Inverell Arpt (IVR)\',\'Inverness, Grossbritannien - Inverness Arpt (INV)\',\'Inyokern, USA - Kern Cty Airport (IYK)\',\'Ioannina, Griechenland - Ioannina Arpt (IOA)\',\'Ipatinga, Brasilien - Usiminas Arpt (IPN)\',\'Ipiales, Kolumbien - San Luis Arpt (IPI)\',\'Ipoh, Malaysia - Ipoh Arpt (IPH)\',\'Iqaluit, Kanada - Iqaluit Arpt (YFB)\',\'Iquique, Chile - Cavancha Chucumata Arpt (IQQ)\',\'Iquitos, Peru - C F Secada Arpt (IQT)\',\'Irkutsk, Russland - Irkutsk Airport (IKT)\',\'Iron Mountain, USA - Ford Arpt (IMT)\',\'Ironwood, USA - Ironwood Arpt (IWD)\',\'Isafjordur, Island - Isafjordur Arpt (IFJ)\',\'Ischia, Italien - Ischia Arpt (ISH)\',\'Isfahan, Iran - Isfahan Arpt (IFN)\',\'Ishigaki, Japan - Ishigaki Airport (ISG)\',\'Isla Mujeres, Mexiko - Isla Mujeres Arpt (ISJ)\',\'Islay, Grossbritannien - Islay Arpt (ILY)\',\'Isle of Man, Grossbritannien - Ronaldsway Arpt (IOM)\',\'Isles Of Scilly, Grossbritannien - St Marys Arpt (ISC)\',\'Isles Of Scilly, Grossbritannien - Tresco Arpt (TSO)\',\'Islip, USA - Long Island Macarthur Arpt (ISP)\',\'Istanbul, Türkei - Istanbul (IST)\',\'Istanbul, Türkei - Sabiha Gokcen (SAW)\',\'Itaperuna, Brasilien - Itaperuna Arpt (ITP)\',\'Ithaca, USA - Tomkins County (ITH)\',\'Ivalo, Finnland - Ivalo Arpt (IVL)\',\'Ivano Frankovsk, Ukraine - Ivano Frankovsk Arpt (IFO)\',\'Ivanovo, Russland - Ivanovo Arpt (IWA)\',\'Ivujivik, Kanada - Ivujivik Arpt (YIK)\',\'Iwami, Japan - Iwami Arpt (IWJ)\',\'Ixtapa / Zihuatanejo, Mexiko - Zihuatanejo Intl (ZIH)\',\'Ixtepec, Mexiko - Ixtepec Arpt (IZT)\',\'Izhevsk, Russland - Izhevsk Arpt (IJK)\',\'Izmir, Türkei (IZM)\',\'Izmir, Türkei - Izmir (ADB)\',\'Izmir, Türkei - Izmir Cigli Military (IGL)\',\'Izumo, Japan - Izumo Arpt (IZO)\',\'Jabiru, Australien - Jabiru Arpt (JAB)\',\'Jackson, USA - Hawkins Field (HKS)\',\'Jackson, USA - Jackson Airport (JAN)\',\'Jackson, USA - Jackson Arpt (JAC)\',\'Jackson, USA - Jackson Reynolds Municipal (JXN)\',\'Jackson, USA - McKellar Fld (MKL)\',\'Jacksonville, USA - Albert J Ellis (OAJ)\',\'Jacksonville, USA - Cecil Field Nas (NZC)\',\'Jacksonville, USA - Cherokee County Arpt (JKV)\',\'Jacksonville, USA - Craig Municipal Arpt (CRG)\',\'Jacksonville, USA - Jacksonville Intl Arpt (JAX)\',\'Jacksonville, USA - Jacksonville Municipal Arpt (IJX)\',\'Jacksonville, USA - Jacksonville Nas (NIP)\',\'Jaipur, Indien - Sanganeer Arpt (JAI)\',\'Jakarta, Indonesien - Halim Perdana Kusuma Arpt (HLP)\',\'Jakarta, Indonesien - Kemayoran Arpt (JKT)\',\'Jakarta, Indonesien - Soekarno Hatta Intl (CGK)\',\'Jalapa, Mexiko - Jalapa Arpt (JAL)\',\'Jambi, Indonesien - Sultan Taha Syarifudin Arpt (DJB)\',\'Jamestown, USA - Chautauqua Cty Arpt (JHW)\',\'Jamestown, USA - Jamestown Arpt (JMS)\',\'Jammu, Indien - Satwari Arpt (IXJ)\',\'Jamnagar, Indien - Govardhanpur Arpt (JGA)\',\'Jasper, Kanada - Hinton Airport (YJA)\',\'Jeddah, Saudi Arabien - Jeddah Intl (JED)\',\'Jefferson City, USA - Jefferson City Memorial (JEF)\',\'Jerez de la Frontera, Spanien - La Parra Arpt (XRY)\',\'Jersey, Grossbritannien - States Airport (JER)\',\'Jerusalem, Israel - Atarot Airport (JRS)\',\'Ji Parana, Brasilien - Ji Parana Arpt (JPR)\',\'Jilin, China - Jilin Arpt (JIL)\',\'Jimma, Äthiopien - Jimma Arpt (JIM)\',\'Jinan, China - Jinan Arpt (TNA)\',\'Jinghong, China - Jinghong Arpt (JHG)\',\'Jinzhou, China - Jinzhou Arpt (JNZ)\',\'Jiujiang, China - Jiujiang Airport (JIU)\',\'Joacaba, Brasilien - Joacaba Arpt (JCB)\',\'Joao Pessoa, Brasilien - Castro Pinto Arpt (JPA)\',\'Jodhpur, Indien - Jodhpur Arpt (JDH)\',\'Joensuu, Finnland - Joensuu Arpt (JOE)\',\'Johannesburg, Südafrika - Grand Central Arpt (GCJ)\',\'Johannesburg, Südafrika - Jan Smuts Arpt (JNB)\',\'Johannesburg, Südafrika - Randgermiston Arpt (QRA)\',\'Johnstown, USA - Johnstown Cambria Arpt (JST)\',\'Johor Bahru, Malaysia - Sultan Ismail Intl Arpt (JHB)\',\'Joinville, Brasilien - Cubatao Arpt (JOI)\',\'Jonesboro, USA - Jonesboro Municipal (JBR)\',\'Jonkoping, Schweden - Axamo Airport (JKG)\',\'Joplin, USA - Joplin Municipal Arpt (JLN)\',\'Juazeiro Do Norte, Brasilien - Regional Do Cariri Arpt (JDO)\',\'Juist, Deutschland - Flugplatz Juist (JUI)\',\'Juiz De Fora, Brasilien - Francisco De Assis Arpt (JDF)\',\'Jujuy, Argentinien - El Cadillal Airport (JUJ)\',\'Julia Creek, Australien - Julia Creek Arpt (JCK)\',\'Juliaca, Peru - Juliaca Arpt (JUL)\',\'Juneau, USA - Juneau Arpt (JNU)\',\'Jurado, Kolumbien - Jurado Arpt (JUO)\',\'Jyvaskyla, Finnland - Jyvaskyla Arpt (JYV)\',\'Kagoshima, Japan - Yoron Airport (KOJ)\',\'Kahului, USA - Kahului Airport (OGG)\',\'Kaikoura, Neuseeland - Kaikoura Arpt (KBZ)\',\'Kairo, Ägypten - Cairo Intl Arpt (CAI)\',\'Kaitaia, Neuseeland - Kaitaia Arpt (KAT)\',\'Kajaani, Finnland - Kajaani Airport (KAJ)\',\'Kake, USA - Kake Arpt (KAE)\',\'Kalamata, Griechenland - Kalamata Airport (KLX)\',\'Kalamazoo, USA - Kalamazoo Cty Arpt (AZO)\',\'Kalaupapa, USA - Kalaupapa Municipal (LUP)\',\'Kalgoorlie, Australien - Kalgoorlie Arpt (KGI)\',\'Kalibo, Philippinen - Kalibo Arpt (KLO)\',\'Kalispell, USA - Glacier Park Intl (FCA)\',\'Kalkutta, Indien - Calcutta Airport (CCU)\',\'Kalmar, Schweden - Kalmar Arpt (KLR)\',\'Kalskag, USA - Kalskag Municipal Arpt (KLG)\',\'Kamloops, Kanada - Davie Fulton Arpt (YKA)\',\'Kamuela, USA - Waimea Arpt (MUE)\',\'Kandahar, Afghanistan - Kandahar International Airport (KDH)\',\'Kangerlussuaq, Grönland - Sondre Stromfjord Arpt (SFJ)\',\'Kangiqsualujjuaq, Kanada - Kangiqsualujjuaq Arpt (XGR)\',\'Kangiqsujuaq, Kanada - Kangiqsujuaq Arpt (YWB)\',\'Kangirsuk, Kanada - Kangirsuk Arpt (YKG)\',\'Kankakee, USA - Greater Kankakee Arpt (IKK)\',\'Kansas City, USA - Fairfax Municipal Arpt (KCK)\',\'Kansas City, USA - Johnson Executive Arpt (OJC)\',\'Kansas City, USA - Kansas City Intl (MCI)\',\'Kansas City, USA - Kansas City Municipal Arpt (MKC)\',\'Kaohsiung, Taiwan, Republik China - Kaohsiung Intl (KHH)\',\'Kapalua, USA - Kapalua Arpt (JHM)\',\'Kapstadt, Südafrika - Cape Town International Airport (CPT)\',\'Kapuskasing, Kanada - Japuskasing Municipal Arpt (YYU)\',\'Karachi, Pakistan - Karachi Arpt (KHI)\',\'Karaganda, Kasachstan - Karaganda Arpt (KGF)\',\'Kariba, Simbabwe - Kariba Arpt (KAB)\',\'Karlovy Vary, Tschechien - Karlovy Vary Arpt (KLV)\',\'Karlsruhe / Baden-Baden, Deutschland - Karlsruhe / Baden-Baden (FKB)\',\'Karlstad, Schweden - Karlstad Arpt (KSD)\',\'Karpathos, Griechenland - Karpathos (AOK)\',\'Karratha, Australien - Karratha Airport (KTA)\',\'Kars, Türkei - Kars (KSY)\',\'Karumba, Australien - Karumba Arpt (KRB)\',\'Karup, Dänemark - Karup Arpt (KRP)\',\'Kastoria, Griechenland - Aristoteles Arpt (KSO)\',\'Katherine, Australien - Tindal Airport (KTR)\',\'Kathmandu, Nepal - Tribuvan Arpt (KTM)\',\'Katowitz, Polen - Pyrzowice (KTW)\',\'Kauai Island, USA - Lihue Municipal (LIH)\',\'Kavala, Griechenland - Megas Alexandros (KVA)\',\'Kavieng, Papua Neu Guinea - Kavieng Arpt (KVG)\',\'Kayseri, Türkei - Kayseri Arpt (ASR)\',\'Kazan, Russland - Kazan Arpt (KZN)\',\'Kearney, USA - Kearney Municipal Arrpt (EAR)\',\'Keene, USA - Dilliant Hopkins Arpt (EEN)\',\'Kefalonia, Griechenland - Argostoli Arpt (EFL)\',\'Kegaska, Kanada - Kegaska Arpt (ZKG)\',\'Kelowna, Kanada - Ellison Field (YLW)\',\'Kemerovo, Russland - Kemerovo Arpt (KEJ)\',\'Kemi, Finnland - Kemi Torino Arpt (KEM)\',\'Kempsey, Australien - Kempsey Arpt (KPS)\',\'Kenai, USA - Kenai Municipal Arpt (ENA)\',\'Kennett, USA - Kennett Municipal Arpt (KNT)\',\'Kenora, Kanada - Kenora Airport (YQK)\',\'Kenosha, USA - Kenosha Municipal Arpt (ENW)\',\'Kentland, USA - Kentland Arpt (KKT)\',\'Keokuk, USA - Keokuk Arpt (EOK)\',\'Kerikeri, Neuseeland - Kerikeri Arpt (KKE)\',\'Kerman, Iran - Kerman Arpt (KER)\',\'Kermanshah, Iran - Kermanshah Arpt (KSH)\',\'Kerry County, Irland - Kerry County Arpt (KIR)\',\'Kerteh, Malaysia - Kertech Arpt (KTE)\',\'Ketchikan, USA - Ketchikan Intl Arpt (KTN)\',\'Key Largo, USA - Port Largo Arpt (KYL)\',\'Key West, USA - Key West Intl (EYW)\',\'Khabarovsk, Russland - Novyy Arpt (KHV)\',\'Khajuraho, Indien - Khajuraho Arpt (HJR)\',\'Khamis Mushait, Saudi Arabien - Khamis Mushait Arpt (KMX)\',\'Kharga, Ägypten - Kharga Arpt (UVL)\',\'Kharkov, Ukraine - Kharkov Arpt (HRK)\',\'Khartoum, Sudan - Civil Arpt (KRT)\',\'Kho Samui, Thailand - Koh Samui Arpt (USM)\',\'Khon Kaen, Thailand - Khon Kaen Arpt (KKC)\',\'Khorramabad, Iran - Khorramabad Arpt (KHD)\',\'Kiel, Deutschland - Holtenau Arpt (KEL)\',\'Kiew, Ukraine - Borispol Arpt (KBP)\',\'Kiew, Ukraine - Zhulhany Arpt (IEV)\',\'Kigali, Ruanda - Kayibanda Arpt (KGL)\',\'Kilimanjaro, Tansania - Kilimanjaro Arpt (JRO)\',\'Killeen, USA - Killeen Municipal (ILE)\',\'Killineq, Kanada - Killineq Arpt (XBW)\',\'Kimberley, Südafrika - B J Vorster Arpt (KIM)\',\'King Island, Australien - King Island Arpt (KNS)\',\'King Khalid Military City, Saudi Arabien - King Khalid Military Airport (KMC)\',\'King Of Prussia, USA - King Of Prussia Arpt (KPD)\',\'King Salmon, USA - King Salmon Arpt (AKN)\',\'Kingman, USA - Mohave County (IGM)\',\'Kings Canyon, Australien - Kings Canyon Arpt (KBJ)\',\'Kings Lynn, Grossbritannien - Marham Raf (KNF)\',\'Kingscote, Australien - Kingscote Arpt (KGC)\',\'Kingston, Jamaica - Norman Manly Arpt (KIN)\',\'Kingston, Jamaica - Tinson Arpt (KTP)\',\'Kingston, Kanada - Norman Rodgers Arpt (YGK)\',\'Kingsville, USA - Naval Air Station Arpt (NQI)\',\'Kinmen, Taiwan, Republik China - Shang Yi Arpt (KNH)\',\'Kinston, USA - East Reg Jetport Stallings (ISO)\',\'Kirkenes, Norwegen - Hoeybuktmoen Arpt (KKN)\',\'Kirkland, Kanada - Kirkland Lake Municipal Arpt (YKX)\',\'Kirksville, USA - Kirksville Municipal (IRK)\',\'Kirkwall, Grossbritannien - Kirkwall Arpt (KOI)\',\'Kiruna, Schweden - Kiruna Airport (KRN)\',\'Kiryat Shmona, Israel - Kiryat Shmona Arpt (KSW)\',\'Kissimmee, USA - Kissimmee Municipal Arpt (ISM)\',\'Kisumu, Kenia - Kisumu Arpt (KIS)\',\'Kita Kyushu, Japan - Kokura Arpt (KKJ)\',\'Kitchener, Kanada - Waterloo Wellington Arpt (YKF)\',\'Kithira, Griechenland - Kithira Arpt (KIT)\',\'Kittila, Finnland - Kittila Arpt (KTT)\',\'Klagenfurt, Österreich - Klagenfurt Arpt (KLU)\',\'Klaipeda / Palanga, Litauen - Palanga (PLQ)\',\'Klamath Falls, USA - Kingsley Field (LMT)\',\'Klawock, USA - Klawock Arpt (KLW)\',\'Knoxville, USA - McGhee Tyson Arpt (TYS)\',\'Kochi, Japan - Kochi Airport (KCZ)\',\'Kodiak, USA - Kodiak Arpt (ADQ)\',\'Kodiak, USA - Kodiak Municipal (KDK)\',\'Köln / Bonn, Deutschland - Köln / Bonn (CGN)\',\'Kokkola, Finnland - Kokkola Arpt (KOK)\',\'Kokomo, USA - Kokomo Municipal (OKK)\',\'Kokoro, Papua Neu Guinea - Kokoro Arpt (KOR)\',\'Komatsu, Japan - Komatsu Airport (KMQ)\',\'Kona/Hawaii, USA - Keahole Arpt (KOA)\',\'Konya, Türkei - Konya Arpt (KYA)\',\'Kopasker, Island - Kopasker Arpt (OPA)\',\'Kopenhagen, Dänemark - Copenhagen Arpt (CPH)\',\'Korfu, Griechenland - I Kapodistrias Arpt (CFU)\',\'Koror, Palau Islands - Airai Airport (ROR)\',\'Kos, Griechenland - Kos Arpt (KGS)\',\'Kosice, Slovakei - Barca Arpt (KSC)\',\'Kostroma, Russland - Kostroma Arpt (KMW)\',\'Kota Bharu, Malaysia - Pengkalan Chepa (KBR)\',\'Kota Kinabalu, Malaysia - Kota Kinabalu Arpt (BKI)\',\'Kotzebue, USA - Ralph Wien Memorial (OTZ)\',\'Kozhikode, Indien - Kozhikode Arpt (CCJ)\',\'Krabi, Thailand - Krabi (KBV)\',\'Krakow, Polen - Balice Arpt (KRK)\',\'Kramfors, Schweden - Kramfors Arpt (KRF)\',\'Krasnodar, Russland - Krasnodar Arpt (KRR)\',\'Krasnoyarsk, Russland - Krasnojarsk Arpt (KJA)\',\'Kristiansand, Norwegen - Kjevik Airport (KRS)\',\'Kristianstad, Schweden - Kristianstad Arpt (KID)\',\'Kristiansund, Norwegen - Kvernberget Arpt (KSU)\',\'Krugersdorp, Südafrika - Lanseria Arpt (HLA)\',\'Kuala Belait, Brunei - Kuala Belait Arpt (KUB)\',\'Kuala Lumpur, Malaysia - Subang Kuala Lumpur Intl (KUL)\',\'Kuala Lumpur, Malaysia - Sultan Abdul Aziz Shah Arpt (SZB)\',\'Kuala Terengganu, Malaysia - Sultan Mahmood Arpt (TGG)\',\'Kuantan, Malaysia - Padang Geroda Airport (KUA)\',\'Kuching, Malaysia - Kuching Airport (KCH)\',\'Kugluktuk Coppermine, Kanada - Kugluktuk Arpt (YCO)\',\'Kulu, Indien - Bhuntar Arpt (KUU)\',\'Kumamoto, Japan - Kumamoto Airport (KMJ)\',\'Kume Jima, Japan - Kumejima Arpt (UEO)\',\'Kunming, China - Kunming Airport (KMG)\',\'Kunsan, Republik Korea - Kunsan Arpt (KUV)\',\'Kununurra, Australien - Kununurra Airport (KNX)\',\'Kuopio, Finnland - Kuopio Arpt (KUO)\',\'Kursk, Russland - Kursk Arpt (URS)\',\'Kushiro, Japan - Kushiro Arpt (KUH)\',\'Kustanay, Kasachstan - Kustanay (KSN)\',\'Kuujjuaq, Kanada - Kuujjuaq Arpt (YVP)\',\'Kuusamo, Finnland - Kuusamo (KAO)\',\'Kuwait, Kuwait - Kuwait Intl (KWI)\',\'Kwajalein, Marshall Islands - Kwajalein Arpt (KWA)\',\'Kwangju, Republik Korea - Kwangju Arpt (KWJ)\',\'Kyoto, Japan - Kyoto Arpt (UKY)\',\'Kzyl-Orda, Kasachstan - Kzyl-Orda (KZO)\',\'La Baule, Frankreich - Montoir Arpt (LBY)\',\'La Coruna, Spanien - La Coruna Arpt (LCG)\',\'La Crosse, USA - La Crosse Municipal (LSE)\',\'La Grande, Kanada - La Grande Municipal Arpt (YGL)\',\'La Grange, USA - Calloway Arpt (LGC)\',\'La Palma, Spanien - La Palma Arpt (SPC)\',\'La Paz, Bolivien - El Alto Arpt (LPB)\',\'La Paz, Mexiko - Aeropuerto Gen Marquez De Leon (LAP)\',\'La Plata, Argentinien - La Plata Arpt (LPG)\',\'La Porte, USA - La Porte Arpt (LPO)\',\'La Rioja, Argentinien - La Rioja Arpt (IRJ)\',\'La Roche, Frankreich - Les Ajoncs Arpt (EDM)\',\'La Rochelle, Frankreich - Laleu Airport (LRH)\',\'La Romana, Dominikanische Republik - La Romana Arpt (LRM)\',\'La Serena, Chile - La Florida (LSC)\',\'La Tabatiere, Kanada - La Tabatiere Arpt (ZLT)\',\'La Verne, USA - Brackett Field (POC)\',\'Laage, Deutschland - Laage Arpt (RLG)\',\'Labasa, Fidschi - Labasa Arpt (LBS)\',\'Labuan, Malaysia - Labuan Arpt (LBU)\',\'Laconia, USA - Laconia Municipal Arpt (LCI)\',\'Ladysmith, Südafrika - Ladysmith Arpt (LAY)\',\'Lae Pg, Papua Neu Guinea - Nadzab Arpt (LAE)\',\'Laeso Island, Frankreich - Beziers Vias Arpt (BZR)\',\'Lafayette, USA - Lafayette Arpt (LAF)\',\'Lafayette, USA - Lafayette Municipal (LFT)\',\'Lagos De Moreno, Mexiko - Francisco P V Y R (LOM)\',\'Lahad Datu, Malaysia - Lahad Datu Arpt (LDU)\',\'Lahore, Pakistan - Lahore Arpt (LHE)\',\'Lajes, Brasilien - Lages Arpt (LAJ)\',\'Lake Charles, USA - Lake Charles Municipal (LCH)\',\'Lake Havasu City, USA - Lake Havasu City Municipal Airport (HII)\',\'Lake Jackson, USA - Lake Jackson Arpt (LJN)\',\'Lake Of The Ozarks, USA - Lee C Fine Memorial (AIZ)\',\'Lake Tahoe, USA - Lake Tahoe Arpt (TVL)\',\'Lakeland, USA - Lakeland Arpt (LAL)\',\'Lakselv, Norwegen - Banak Airport (LKL)\',\'Lamar, USA - Lamar Arpt (LAA)\',\'Lamezia Terme, Italien - S Eufemia Arpt (SUF)\',\'Lampang, Thailand - Lampang Arpt (LPT)\',\'Lampedusa, Italien - Lampedusa Arpt (LMP)\',\'Lanai, USA - Lanai Airport (LNY)\',\'Lancaster, USA - Lancaster Arpt (LNS)\',\'Lancaster, USA - Williams J Fox Arpt (WJF)\',\'Lands End, Grossbritannien - Saint Just Arpt (LEQ)\',\'Landskrona, Schweden - Landskrona Heliport (JLD)\',\'Langkawi, Malaysia - Langkawi Arpt (LGK)\',\'Lannion, Frankreich - Servel Airport (LAI)\',\'Lansing, USA - Lansing Arpt (LAN)\',\'Lanzarote, Spanien - Lanzarote Airport (ACE)\',\'Lanzhou, China - Lanzhou Arpt (LHW)\',\'Lappeenranta, Finnland - Lappeenranta Arpt (LPP)\',\'Laramie, USA - General Brees Fld (LAR)\',\'Laramie, USA - Lar Shively Arpt (SAA)\',\'Laredo, USA - Laredo Intl (LRD)\',\'Larnaca, Zypern - Larnaca Intl (LCA)\',\'Las Cruces, USA - Las Cruces Crawford Arpt (LRU)\',\'Las Palmas, Spanien - Aeropuerto De Gran Canaria (LPA)\',\'Las Piedras, Venezuela - Josefa Camejo Arpt (LSP)\',\'Las Vegas, USA - Henderson Sky Harbor Arpt (HSH)\',\'Las Vegas, USA - Las Vegas Arpt (LVS)\',\'Las Vegas, USA - Las Vegas North Air Terminal (VGT)\',\'Las Vegas, USA - McCarran Intl (LAS)\',\'Las Vegas, USA - Tucumcari Arpt (TCC)\',\'Latacunga, Ecuador - Cotapaxi Intl Arpt (LTX)\',\'Latakia, Syrien - Hmelmin Airport (LTK)\',\'Latrobe, USA - Westmorland County (LBE)\',\'Launceton, Australien - Launceston Arpt (LST)\',\'Laurel, USA - Hattiesburg Laurel Regional Arpt (PIB)\',\'Laurel, USA - Hesler Noble Field (LUL)\',\'Laverton, Australien - Laverton Airport (LVO)\',\'Lawas, Malaysia - Lawas Arpt (LWY)\',\'Lawrence, USA - Lawrence Arpt (LWM)\',\'Lawrence, USA - Lawrence Municipal (LWC)\',\'Lawton, USA - Lawton Municipal (LAW)\',\'Lazaro Cardenas Michoacan, Mexiko - Lazaro Cardenas Arpt (LZC)\',\'Le Havre, Frankreich - Octeville Arpt (LEH)\',\'Le Mans, Frankreich - Arnage Arpt (LME)\',\'Le Puy, Frankreich - Loudes Airport (LPY)\',\'Le Touquet, Frankreich - Le Touquet Arpt (LTQ)\',\'Learmonth, Australien - Learmonth Arpt (LEA)\',\'Lebanon, USA - Claremont Municipal (CNH)\',\'Lebanon, USA - Lebanon Regional (LEB)\',\'Lecce, Italien - Galatina Arpt (LCC)\',\'Leeds / Bradford, Grossbritannien - Leeds Bradford Arpt (LBA)\',\'Leesburg, USA - Leesburg Municipal Arpt (LEE)\',\'Leeton, Australien - Leeton Arpt (QLE)\',\'Leh IN, Indien - Leh Arpt (IXL)\',\'Leinster, Australien - Leinster Arpt (LER)\',\'Leipzig, Deutschland - Leipzig (LEJ)\',\'Leknes, Norwegen - Leknes Arpt (LKN)\',\'Lemnos, Griechenland - Lemnos Airport (LXS)\',\'Lencois, Brasilien - Chapada Diamantina Arpt (LEC)\',\'Leon, Spanien - Leon Arpt (LEN)\',\'Leon-Guanjuato, Mexiko - Del Bajio Arpt (BJX)\',\'Leonora, Australien - Leonora Arpt (LNO)\',\'Leros, Griechenland - Leros Arpt (LRS)\',\'Lerwick, Grossbritannien - Tingwall Arpt (LWK)\',\'Les Sables, Frankreich - Talmont Arpt (LSO)\',\'Lethbridge, Kanada - Lethbridge Arpt (YQL)\',\'Leticia, Kolumbien - General A V Cobo Arpt (LET)\',\'Lewisburg, USA - Greenbrier Valley Arpt (LWB)\',\'Lewiston, USA - Auburn Lewiston Arpt (LEW)\',\'Lewiston, USA - Lewiston Nez Pierce Arpt (LWS)\',\'Lewistown, USA - Lewistown Municipal (LWT)\',\'Lexington, USA - Blue Grass Field (LEX)\',\'Lexington, USA - Jim Kelley Field (LXN)\',\'Lhasa, China - Lhasa Arpt (LXA)\',\'Lianping, China - Lianping Arpt (LIA)\',\'Liberal, USA - Liberal Municipal (LBL)\',\'Liberia, Costa Rica - Liberia Arpt (LIR)\',\'Lidkoping, Schweden - Hovby Airport (LDK)\',\'Lightning Ridge, Australien - Lightning Ridge Arpt (LHG)\',\'Lihir Island, Papua Neu Guinea - Lihir Island Arpt (LNV)\',\'Lijiang City, China - Lijiang Arpt (LJG)\',\'Lilabari, Indien - Lilabari Arpt (IXI)\',\'Lille, Frankreich - Lesquin Arpt (LIL)\',\'Lima, Peru - Nlima Intl Jorge Chavez (LIM)\',\'Lima, USA - Allen County Arpt (AOH)\',\'Limbang, Malaysia - Limbang Arpt (LMN)\',\'Limoges, Frankreich - Bellegarde Arpt (LIG)\',\'Limon, Costa Rica - Limon Arpt (LIO)\',\'Lincoln, USA - Lincoln Municipal (LNK)\',\'Linden, USA - Linden Municipal (LDJ)\',\'Ling Ling, China - Ling Ling Arpt (LLF)\',\'Linkoping, Schweden - Saab Airport (LPI)\',\'Linz, Österreich - Hoersching Arpt (LNZ)\',\'Lismore, Australien - Lismore Airport (LSY)\',\'Lissabon, Portugal - Lissabon (LIS)\',\'Little Cayman, Cayman Islands - Little Cayman Arpt (LYB)\',\'Little Rock, USA - Little Rock Regional (LIT)\',\'Liuzhou, China - Liuzhou Airport (LZH)\',\'Livermore, USA - Bron Airport (LVK)\',\'Liverpool, Grossbritannien - Liverpool Arpt (LPL)\',\'Livingston, USA - Mission Field (LVM)\',\'Ljubljana, Slowenien - Brnik Airport (LJU)\',\'Lloydminster, Kanada - Lloydminster Arpt (YLL)\',\'Lockhart, Australien - Lockhart River Arpt (IRG)\',\'Lodz, Polen - Lodz Lublinek Arpt (LCJ)\',\'Logan, USA - Logan Arpt (LGU)\',\'London, Grossbritannien (LON)\',\'London, Grossbritannien - Gatwick Airport (LGW)\',\'London, Grossbritannien - Heathrow (LHR)\',\'London, Grossbritannien - London City Airport (LCY)\',\'London, Grossbritannien - London-Luton (LTN)\',\'London, Grossbritannien - London-Stansted (STN)\',\'London, Kanada - London Municipal (YXU)\',\'London, Kanada - Pembroke Area Municipal Arpt (YQS)\',\'London, USA - Corbin London Airport (LOZ)\',\'Londrina, Brasilien - Londrina Arpt (LDB)\',\'Long Akah, Malaysia - Long Akah Arpt (LKH)\',\'Long Beach, USA - Long Beach Municipal (LGB)\',\'Long Island, Australien - Long Island Arpt (HAP)\',\'Longreach, Australien - Longreach Arpt (LRE)\',\'Longview, USA - Greg County Arpt (GGG)\',\'Longyearbyen, Norwegen - Svalbard Arpt (LYR)\',\'Lopez Island, USA - Lopez Island Arpt (LPS)\',\'Lord Howe Island, Australien - Lord Howe Island Arpt (LDH)\',\'Loreto, Mexiko - Loreto Intl Arpt (LTO)\',\'Lorient, Frankreich - Lann Bihoue Arpt (LRT)\',\'Los Alamos, USA - Los Alamos Municipal (LAM)\',\'Los Angeles, Chile - Maria Dolores Arpt (LSQ)\',\'Los Angeles, USA - Commerce Business Plaza Heliport (JBP)\',\'Los Angeles, USA - Los Angeles Intl (LAX)\',\'Los Angeles, USA - Los Angeles Van Nuys Arpt (VNY)\',\'Los Angeles, USA - Santa Monica Municipal Arpt (SMO)\',\'Los Angeles, USA - Thousand Oaks Hlpt (JTO)\',\'Los Banos, USA - Los Banos Arpt (LSN)\',\'Los Mochis, Mexiko - Federal Los Mochis Arpt (LMM)\',\'Louangphrabang, Laos - Louangphrabang Arpt (LPQ)\',\'Louisville, USA - Standiford Fld (SDF)\',\'Lubbock, USA - Lubbock Intl (LBB)\',\'Lucca, Italien - Lucca Arpt (LCV)\',\'Lucknow, Indien - Amausi Arpt (LKO)\',\'Luderitz, Namibia - Luderitz Arpt (LUD)\',\'Ludhiana, Indien - Ludhiana Arpt (LUH)\',\'Lüttich, Belgien - Bierset Airport (LGG)\',\'Lufkin, USA - Angelina Cty Arpt (LFK)\',\'Lugano, Schweiz - Agno Airport (LUG)\',\'Lugansk, Ukraine - Lugansk Arpt (VSG)\',\'Lulea, Schweden - Kallax Airport (LLA)\',\'Lumberton, USA - Lumberton Arpt (LBT)\',\'Lutsk, Ukraine - Lutsk Arpt (UCK)\',\'Luxemburg, Luxemburg - Findel Arpt (LUX)\',\'Luxor, Ägypten - Luxor Airport (LXR)\',\'Lvov, Ukraine - Snilow Arpt (LWO)\',\'Lycksele, Schweden - Hedlunda Arpt (LYC)\',\'Lydd, Grossbritannien - Lydd Intl Arpt (LYX)\',\'Lynchburg, USA - Lynchburg Municipal (LYH)\',\'Lyon France, Frankreich - Bron Lyon (LYN)\',\'Lyon, Frankreich - Satolas Airport (LYS)\',\'Maastricht, Niederlande - Zuid Limburg Arpt (MST)\',\'Macaba, Brasilien - Macapa Intl Arpt (MCP)\',\'Macae, Brasilien - Macae Airport (MEA)\',\'Macau, Macau - Macau (MFM)\',\'Maceio, Brasilien - Palmeres Airport (MCZ)\',\'Mackay, Australien - Mackay Arpt (MKY)\',\'Macon, USA - Lewis B Wilson (MCN)\',\'Madang, Papua Neu Guinea - Madang Arpt (MAG)\',\'Madera, USA - Madera Municipal Arpt (MAE)\',\'Madison, USA - Dane Cty Regional (MSN)\',\'Madras, Indien - Meenambarkkam Arpt (MAA)\',\'Madrid, Spanien - Madrid (MAD)\',\'Madurai, Indien - Madurai Airport (IXM)\',\'Mae Hongsorn, Thailand - Mae Hong Son Arpt (HGN)\',\'Mae Sot, Thailand - Mae Sot Arpt (MAQ)\',\'Mafikeng, Südafrika - Matsu Arpt (MFK)\',\'Magadan, Russland - Magadan Arpt (GDX)\',\'Magnolia, USA - Magnolia Municipal (AGO)\',\'Mahe, Seychellen - Seychelles Intl Arpt (SEZ)\',\'Mahenye, Simbabwe - Mahenye Airfield (MJW)\',\'Mailand / Bergamo, Italien - Bergamo Orio al Serio International Airport (BGY)\',\'Mailand, Italien (MIL)\',\'Mailand, Italien - Linate Arpt (LIN)\',\'Mailand, Italien - Mailand-Malpensa (MXP)\',\'Mailand, Italien - Segrate (SWK)\',\'Maitland, Australien - Maitland Airport (MTL)\',\'Majunga, Madagaskar - Amborovy Arpt (MJN)\',\'Majuro, Marshall Islands - Amata Kabua Intl Arpt (MAJ)\',\'Makung, Taiwan, Republik China - Makung Arpt (MZG)\',\'Malabo, Equatorial Guinea - Santa Isabel Arpt (SSG)\',\'Malacca, Malaysia - Batu Berendum Arpt (MKZ)\',\'Malaga, Spanien - Malaga Arpt (AGP)\',\'Male, Malediven - Male Intl Arpt (MLE)\',\'Malelane, Südafrika - Municipal Arpt (LLE)\',\'Malindi, Kenia - Malindi Arpt (MYD)\',\'Mallorca, Spanien - Palma de Mallorca (PMI)\',\'Malmo, Schweden - Malmo City Hvc Arpt (HMA)\',\'Malmo, Schweden - Malmo Harbour Heliport (JMM)\',\'Malmo, Schweden - Malmo Metropolitan Area Arpt (MMA)\',\'Malmo, Schweden - Sturup Arpt (MMX)\',\'Maloy, Norwegen - Harbour Arpt (QFQ)\',\'Malta, Malta - Luqa Airport (MLA)\',\'Mammoth Lakes, USA - Mammoth Lakes Municipal (MMH)\',\'Manado, Indonesien - Samratulang Arpt (MDC)\',\'Managua, Nicaragua - Augusto C Sandino (MGA)\',\'Manassas, USA - Manassas Arpt (MNZ)\',\'Manaus, Brasilien - Intl Arpt Eduardo Gomes (MAO)\',\'Manchester, Grossbritannien - Manchester Intl (MAN)\',\'Manchester, USA - Manchester Arpt (MHT)\',\'Mandalay, Myanmar - Annisaton Arpt (MDL)\',\'Mangalore, Indien - Bajpe Arpt (IXE)\',\'Manhattan, USA - Manhattan Municipal Arpt (MHK)\',\'Manila, Philippinen - Ninoy Aquino Intl (MNL)\',\'Manistee, USA - Manistee Arpt (MBL)\',\'Manistique, USA - Schoolcraft County Arpt (ISQ)\',\'Manitouwadge, Kanada - Manitouwadge Municipal Arpt (YMG)\',\'Manitowoc, USA - Manitowoc Municipal Arpt (MTW)\',\'Manizales, Kolumbien - Santaguida Arpt (MZL)\',\'Mankato, USA - Mankato Municipal Arpt (MKT)\',\'Mannheim, Deutschland - Mannheim (MHG)\',\'Mansfield, USA - Mansfield Municipal (MFD)\',\'Manston, Grossbritannien - Kent International Arpt (MSE)\',\'Manta, Ecuador - Manta Arpt (MEC)\',\'Manus Island, Papua Neu Guinea - Momote Arpt (MAS)\',\'Manzanillo, Kuba - Sierra Maestra Arpt (MZO)\',\'Manzanillo, Mexiko - Aeropuerto Intl (ZLO)\',\'Manzini, Swaziland - Matsapha Intl Arpt (MTS)\',\'Maota, Samoa - Maota Arpt (MXS)\',\'Maputo, Mozambique - Maputo Intl (MPM)\',\'Mar del Plata, Argentinien - Mar Del Plata Arpt (MDQ)\',\'Maraba, Brasilien - Maraba Arpt (MAB)\',\'Maracaibo, Venezuela - La Chinita Arpt (MAR)\',\'Maracay, Venezuela - Maracay Arpt (MYC)\',\'Marathon, Kanada - Marathon Municipal Arpt (YSP)\',\'Marathon, USA - Marathon Arpt (MTH)\',\'Mardin, Türkei - Mardin Arpt (MQM)\',\'Margaret River, Australien - Margaret River Arpt (MGV)\',\'Margaret River, Australien - Margaret River Arpt (MQZ)\',\'Margate, Südafrika - Margate Arpt (MGH)\',\'Marhsall, USA - Harrison County Arpt (ASL)\',\'Maribor, Slowenien - Maribor Arpt (MBX)\',\'Mariehamn, Finnland - Mariehamn Arpt (MHQ)\',\'Marietta, USA - Dobbins Air Force Base (MGE)\',\'Marilia, Brasilien - Dr Gastao Vidigal (MII)\',\'Maringa, Brasilien - Maringa Arpt (MGF)\',\'Marion, USA - Mount Vernon Outland Arpt (MVN)\',\'Marion, USA - Williamson County (MWA)\',\'Marlborough, USA - Marlborough Arpt (MXG)\',\'Marquette, USA - Marquette Arpt (MQT)\',\'Marrakesch, Marokko - Menara Airport (RAK)\',\'Marsa Alam, Ägypten - Marsa Alam Arpt (RMF)\',\'Marseille, Frankreich - Marseille Provence Arpt (MRS)\',\'Marsh Harbour, Bahamas - Marsh Harbour Intl Arpt (MHH)\',\'Marshall, USA - Marshall Municipal (MML)\',\'Marshalltown, USA - Marshalltown Municipal (MIW)\',\'Marshfield, USA - Marshfield Municipal Arpt (MFI)\',\'Martha S Vineyard, USA - Dukes County (MVY)\',\'Martinsburgh, USA - Martinsburgh Regional Arpt (MRB)\',\'Marudi, Malaysia - Marudi Arpt (MUR)\',\'Mary, Turkmenistan - Mary Arpt (MYP)\',\'Maryborough, Australien - Maryborough Arpt (MBH)\',\'Marysville, USA - Yuba County Arpt (BAB)\',\'Marysville, USA - Yuba County Arpt (MYV)\',\'Maseru, Lesotho - Moshoeshoe Intl Arpt (MSU)\',\'Mashad, Iran - Mashad Arpt (MHD)\',\'Mason City, USA - Mason City Municipal (MCW)\',\'Massena, USA - Richards Field (MSS)\',\'Masterton, Neuseeland - Masterton Arpt (MRO)\',\'Masvingo, Simbabwe - Fort Victoria Arpt (MVZ)\',\'Matamoros, Mexiko - Servando Canales Arpt (MAM)\',\'Matane, Kanada - Matane Airport (YME)\',\'Matanzas, Kuba - Kawama Arpt (VRO)\',\'Mataram, Indonesien - Selaparang Airport (AMI)\',\'Matsumoto, Japan - Matsumoto Arpt (MMJ)\',\'Matsuyama, Japan - Matsuyama Airport (MYJ)\',\'Mattoon, USA - Coles County (MTO)\',\'Maturin, Venezuela - Quiriquire Arpt (MUN)\',\'Mauritius, Mauritius - Plaisance Arptt (MRU)\',\'Mayaguez, USA - Eugenio M De Hostos Arpt (MAZ)\',\'Mazatlan, Mexiko - Buelina Arpt (MZT)\',\'McAlester, USA - McAlester Municipal Arpt (MLC)\',\'Mcallen, USA - Miller Intl (MFE)\',\'Mccall, USA - Mccall Arpt (MYL)\',\'McCook, USA - McCook Municipal (MCK)\',\'McPherson, USA - McPherson Arpt (MPR)\',\'Meadow Lake, Kanada - Meadow Lake Arpt (YLJ)\',\'Medan, Indonesien - Polonia Airport (MES)\',\'Medellin, Kolumbien - Enrique Olaya Herrara (EOH)\',\'Medellin, Kolumbien - Jose Marie Cordova (MDE)\',\'Medford, USA - Medford Jackson Cty (MFR)\',\'Medicine Hat, Kanada - Medicine Hat Airport (YXH)\',\'Medina, Saudi Arabien - Prince Mohammad Bin Abdulaziz Arpt (MED)\',\'Meekathara, Australien - Meekatharra Arpt (MKR)\',\'Mehamn, Norwegen - Mehamn Arpt (MEH)\',\'Meixian, China - Meixian Arpt (MXZ)\',\'Melbourne, Australien - Essendon Arpt (MEB)\',\'Melbourne, Australien - Tullamarine Arpt (MEL)\',\'Melbourne, USA - Melbourne Regional (MLB)\',\'Melilla, Spanien - Melilla Arpt (MLN)\',\'Memambetsu, Japan - Memanbetsu Arpt (MMB)\',\'Memmingen, Deutschland - Flughafen Allgäu (FMM)\',\'Memphis, USA - Memphis Intl (MEM)\',\'Memphis, USA - Memphis Naval Air Station (NQA)\',\'Mendi, Papua Neu Guinea - Mendi Arpt (MDU)\',\'Mendoza, Argentinien - El Plumerillo Airport (MDZ)\',\'Menominee, USA - Menominee County (MNM)\',\'Menorca, Spanien - Aerop De Menorca (MAH)\',\'Merced, USA - Merced Municipal Arpt (MCE)\',\'Merida, Mexiko - Merida Intl (MID)\',\'Merida, Venezuela - Alberto Carnevalli Arpt (MRD)\',\'Meridian, USA - Key Field (MEI)\',\'Merimbula, Australien - Merimbula Arpt (MIM)\',\'Merritt, Kanada - Merritt Arpt (YMB)\',\'Mesa, USA - Falcon Field (MSC)\',\'Mesquite, USA - Mesquite Arpt (MFH)\',\'Metz Nancy, Frankreich - Metz Nancy Lorraine (ETZ)\',\'Metz, Frankreich - Frescaty Airport (MZM)\',\'Mexicali, Mexiko - Rodolfg Sachez Taboada (MXL)\',\'Mexico City, Mexiko - Juarez Intl (MEX)\',\'Miami, USA - Dade Collier (TNT)\',\'Miami, USA - Downtown Heliport (JDM)\',\'Miami, USA - Miami Intl (MIA)\',\'Miami, USA - Opa Locka Arpt (OPF)\',\'Miami, USA - Seaplane Base (MPB)\',\'Miami, USA - Tamiami Airport (TMB)\',\'Mian Yang, China - Mian Yang Arpt (MIG)\',\'Michigan City, USA - Michigan City Arpt (MGC)\',\'Middlemount, Australien - Middlemount Arpt (MMM)\',\'Middletown, USA - Hook Field (MWO)\',\'Midland, USA - Midland Intl Arpt (MAF)\',\'Midlanda, Schweden - Sundsvall Arpt (SDL)\',\'Mikkeli, Finnland - Mikkeli Aprt (MIK)\',\'Mildenhall, Grossbritannien - Mildenhall Arpt (MHZ)\',\'Mildura, Australien - Mildura Arpt (MQL)\',\'Miles City, USA - Miles City Municipal Arpt (MLS)\',\'Milford Sound, Neuseeland - Milford Sound Arpt (MFN)\',\'Millinocket, USA - Millinocket Arpt (MLT)\',\'Millville, USA - Millville Arpt (MIV)\',\'Milton, USA - Whiting Field Nas (NSE)\',\'Milwaukee, USA - General Mitchell Fld (MKE)\',\'Milwaukee, USA - Horlick Arpt (RAC)\',\'Minatitlan, Mexiko - Minatitlan Municipal Arpt (MTT)\',\'Minden, USA - Douglas County Arpt (MEV)\',\'Mineralnye Vody, Russland - Mineralnye Vody Arpt (MRV)\',\'Minneapolis, USA - Flying Cloud Arpt (FCM)\',\'Minneapolis, USA - Minneapolis St Paul Intl (MSP)\',\'Minocqua, USA - Noble F Lee Memorial Field (ARV)\',\'Minot, USA - Minot Intl (MOT)\',\'Minsk, Weißrussland - Minsk Arpt (MSQ)\',\'Minsk, Weißrussland - Minsk Intl 1 (MHP)\',\'Miri, Malaysia - Miri Arpt (MYY)\',\'Misawa, Japan - Misawa Arpt (MSJ)\',\'Miskolc, Ungarn - Miskolc Arpt (MCQ)\',\'Missoula, USA - Missoula Intl (MSO)\',\'Mitchell, USA - Mitchell Municipal (MHE)\',\'Miyako Jima, Japan - Hirara Arpt (MMY)\',\'Miyazaki, Japan - Miyazaki Arpt (KMI)\',\'Mmabatho, Südafrika - Mmabatho International Arpt (MBD)\',\'Mo I Rana, Norwegen - Rossvoll (MQN)\',\'Moab, USA - Moab Municipal (CNY)\',\'Mobile, USA - Mobile Municipal (MOB)\',\'Modesto, USA - Harry Sham Fld (MOD)\',\'Mogilev, Weißrussland - Mogilev Arpt (MVQ)\',\'Mohenjodaro, Pakistan - Mohenjodaro Arpt (MJD)\',\'Mojave, USA - Kern County Arpt (MHV)\',\'Mokpo, Republik Korea - Mokpo Arpt (MPK)\',\'Molde, Norwegen - Aro Arpt (MOL)\',\'Moline, USA - Quad City Arpt (MLI)\',\'Mombasa, Kenia - Moi Intl (MBA)\',\'Monaco, Monaco - Hel De Monte Carlo Airport (MCM)\',\'Monastir, Tunesien - Skanes Airport (MIR)\',\'Monclova, Mexiko - Monclova Arpt (LOV)\',\'Moncton, Kanada - Moncton Municipal (YQM)\',\'Monroe, USA - Monroe Regional (MLU)\',\'Monroeville, USA - Monroe County Arpt (MVC)\',\'Montauk, USA - Sky Portal Arpt (MTP)\',\'Monte Dourado, Brasilien - Monte Dourado Arpt (MEU)\',\'Montego Bay, Jamaica - Sangster Arpt (MBJ)\',\'Monterey, USA - Monterey Peninsula (MRY)\',\'Monterey, USA - Salinas Arpt (SNS)\',\'Monteria, Kolumbien - S Jeronimo Arpt (MTR)\',\'Monterrey, Mexiko - Aeropuerto Del Norte (NTR)\',\'Monterrey, Mexiko - Escobedo Arpt (MTY)\',\'Montes Claros, Brasilien - Montes Claros Arpt (MOC)\',\'Montevideo, Uruguay - Carrasco Arpt (MVD)\',\'Montgomery, USA - Dannelly Field (MGM)\',\'Monticello, USA - Catskills Sulivan (MSV)\',\'Montlucon, Frankreich - Gueret Arpt (MCU)\',\'Monto, Australien - Monto Arpt (MNQ)\',\'Montpelier, USA - E F Knapp Arpt (MPV)\',\'Montpellier, Frankreich - Frejorgues Arpt (MPL)\',\'Montreal, Kanada (YMQ)\',\'Montreal, Kanada - Dorval Intl (YUL)\',\'Montreal, Kanada - Mirabel Intl Arpt (YMX)\',\'Montreal, Kanada - Saint Hubert Arpt (YHU)\',\'Montreal, Kanada - Victoria Stol (YMY)\',\'Montrose, USA - Montrose County (MTJ)\',\'Montserrat, Dominica - Blackburne Arpt (MNI)\',\'Moorabbin, Australien - Moorabbin Arpt (MBW)\',\'Moorea, Französisch-Polynesien - Temae Airport (MOZ)\',\'Moosonee, Kanada - Moosonee Arpt (YMO)\',\'Mora, Schweden - Mora Arpt (MXX)\',\'Moranbah, Australien - Moranbah Arpt (MOV)\',\'Moree, Australien - Moree Arpt (MRZ)\',\'Morelia, Mexiko - Michoacan Municipal Arpt (MLM)\',\'Morgantown, USA - Morgantown Municipal (MGW)\',\'Morioka, Japan - Hanamaki Arpt (HNA)\',\'Morlaix, Frankreich - Morlaix Arpt (MXN)\',\'Morondava, Madagaskar - Morondava Arpt (MOQ)\',\'Moroni Hahaya, Comoros - Iconi Hahaya (HAH)\',\'Moroni, Comoros - Iconi Arpt (YVA)\',\'Morristown, USA - Morristown Arpt (MMU)\',\'Moruya, Australien - Moruya Arpt (MYA)\',\'Moses Lake, USA - Grant County (MWH)\',\'Mosjoen, Norwegen - Kjaerstad Arpt (MJF)\',\'Moskau, Russland (MOW)\',\'Moskau, Russland - Bykovo Arpt (BKA)\',\'Moskau, Russland - Domodedovo Arpt (DME)\',\'Moskau, Russland - Sheremetyevo Arpt (SVO)\',\'Moskau, Russland - Vnukovo Arpt (VKO)\',\'Mossoro, Brasilien - Dixsept Rosado Arpt (MVF)\',\'Mostar, Bosnien - Mostar Arpt (OMO)\',\'Moultrie, USA - Moultrie Arpt (MGR)\',\'Mount Cook, Neuseeland - Mount Cook Arpt (MON)\',\'Mount Gambier, Australien - Mount Gambier Arpt (MGB)\',\'Mount Hagen, Papua Neu Guinea - Kagamuga Arpt (HGU)\',\'Mount Holly, USA - Burlington Country Arpt (LLY)\',\'Mount Hotham, Australien - Mount Hotham Arpt (MHU)\',\'Mount Isa, Australien - Mount Isa Arpt (ISA)\',\'Mount Magnet, Australien - Mount Magnet Arpt (MMG)\',\'Mount Newman, Australien - Newman Airport (ZNE)\',\'Mount Pleasant, USA - Mount Pleasant Municipal (MOP)\',\'Mountain Home, USA - Mountain Home Arpt (WMH)\',\'Mountain Village, USA - Mountain Village Arpt (MOU)\',\'Mtwara, Tansania - Mtwara Arpt (MYW)\',\'Mudanjiang, China - Mudanjiang Arpt (MDG)\',\'Mudgee, Australien - Mudgee Arpt (DGE)\',\'München, Deutschland - München (Franz Josef Strauss) (MUC)\',\'Münster, Deutschland - Münster / Osnabrück (FMO)\',\'Muharraq Town, Bahrain - Muharraq Arpt (GBQ)\',\'Mukah, Malaysia - Mukah Arpt (MKM)\',\'Mukalla, Jemen - Mukalla Arpt (MKX)\',\'Muncie, USA - Johnson Field (MIE)\',\'Murcia, Spanien - San Javier Airport (MJV)\',\'Murmansk, Russland - Murmansk Arpt (MMK)\',\'Murry, USA - Calloway Cty Arpt (CEY)\',\'Mus Tr, Türkei - Mus Arpt (MSR)\',\'Muscat, Oman - Seeb Intl (MCT)\',\'Muscle Shoals, USA - Muscle Shoals Arpt (MSL)\',\'Muskegon, USA - Muskegon Cty Intl (MKG)\',\'Muskogee, USA - Davis Field (MKO)\',\'Muskoka, Kanada - Muskoka Arpt (YQA)\',\'Mustique, Dominica - Mustique Arpt (MQS)\',\'Mutare, Simbabwe - Mutare Arpt (UTA)\',\'Mwanza, Tansania - Mwanza Arpt (MWZ)\',\'Mykonos, Griechenland - Mykonos Greece Arpt (JMK)\',\'Myrtle Beach, USA - George Town Arpt (GGE)\',\'Myrtle Beach, USA - Grand Strand Arpt (CRE)\',\'Myrtle Beach, USA - Myrtle Beach Jetway (MYR)\',\'Mysore, Indien - Mysore Airport (MYQ)\',\'Mytilene, Griechenland - Mytilene Arpt (MJT)\',\'N Philadelphia, USA - N Philadelphia (PNE)\',\'Naberevnye Chelny, Russland - Nijnekamsk Arpt (NBC)\',\'Nadi, Fidschi - Nadi Intl (NAN)\',\'Nador, Marokko - Nador International Airport (NDR)\',\'Nagasaki, Japan - Nagasaki Airport (NGS)\',\'Nagoya, Japan - Komaki Arpt (NGO)\',\'Nagpur, Indien - Sonegaon Arpt (NAG)\',\'Nairobi, Kenia - Jomo Kenyatta Intl (NBO)\',\'Nairobi, Kenia - Wilson Airport (WIL)\',\'Nakashibetsu, Japan - Nakashibetsu Arpt (SHB)\',\'Nakhon Phanom, Thailand - Nakhon Phanom Arpt (KOP)\',\'Nakhon Ratchasima, Thailand - Nakhon Ratchasima Arpt (NAK)\',\'Nakhon Si Tham, Thailand - Nakhon Si Thammarat Arpt (NST)\',\'Nalchik, Russland - Nalchik Arpt (NAL)\',\'Namsos, Norwegen - Namsos Arpt (OSY)\',\'Nan Th, Thailand - Nan Arpt (NNT)\',\'Nanaimo, Kanada - Harbour Seaplane Base (ZNA)\',\'Nanaimo, Kanada - Nanaimo Arpt (YCD)\',\'Nanchang, China - Nanchang Airport (KHN)\',\'Nancy, Frankreich - Essey Airport (ENC)\',\'Nanjing, China - Nanjing Airport (NKG)\',\'Nanning, China - Nanning Airport (NNG)\',\'Nantes, Frankreich - Chateau Bougon Arpt (NTE)\',\'Nantucket, USA - Nantucket Memorial (ACK)\',\'Napa, USA - Napa Cty Arpt (APC)\',\'Napier, Neuseeland - Hawkes Bay Arpt (NPE)\',\'Naples, USA - Naples Municipal (APF)\',\'Naracoorte, Australien - Naracoorte Arpt (NAC)\',\'Narathiwat, Thailand - Narathiwat Arpt (NAW)\',\'Narrabri, Australien - Narrabri Arpt (NAA)\',\'Narrandera, Australien - Narrandera Arpt (NRA)\',\'Narvik, Norwegen - Framnes Arpt (NVK)\',\'Nashua, USA - Boire Field Arpt (ASH)\',\'Nashville, USA - Nashville Metro Arpt (BNA)\',\'Nassau, Bahamas - Nassau Intl (NAS)\',\'Nassau, Bahamas - Paradise Island Arpt (PID)\',\'Nassau, Bahamas - Seaplane Base Arpt (WZY)\',\'Natal, Brasilien - Augusto Severo Intl Arpt (NAT)\',\'Natashquan, Kanada - Natashquan Arpt (YNA)\',\'Natchez, USA - Natchez Adams Cty (HEZ)\',\'Navegantes, Brasilien - Navegantes Arpt (NVT)\',\'Nawabshah, Pakistan - Nawabshah Arpt (WNS)\',\'Naxxos Insel, Griechenland - Naxos Arpt (JNX)\',\'Neapel, Italien - Neapel (NAP)\',\'Needles, USA - Needles Arpt (EED)\',\'Nejran, Saudi Arabien - Nejran Arpt (EAM)\',\'Nelson, Neuseeland - Nelson Arpt (NSN)\',\'Nelspruit, Südafrika - Kruger Mpumalanga Intl Arpt (MQP)\',\'Nelspruit, Südafrika - Nelspruit Airport (NLP)\',\'Neuquen, Argentinien - Neuquen Airport (NQN)\',\'Nevis, St. Kitts - Nevis - Nevis Airport (NEV)\',\'Nevsehir, Türkei - Nevsehir Arpt (NAV)\',\'New Bedford, USA - New Bedford Municipal (EWB)\',\'New Bern, USA - Simmons Nott Arpt (EWN)\',\'New Haven, USA - Tweed New Haven Arpt (HVN)\',\'New Orleans, USA - Moisant Intl (MSY)\',\'New Orleans, USA - New Lakefront Arpt (NEW)\',\'New Plymouth, Neuseeland - New Plymouth Arpt (NPL)\',\'New Richmond, USA - New Richmond Municipal (RNH)\',\'New Ulm, USA - New Ulm Arpt (ULM)\',\'New York, USA (NYC)\',\'New York, USA - Downtown Manhattan Hlpt (JRB)\',\'New York, USA - East 34th St Hlpt (TSS)\',\'New York, USA - East 60th St Hlpt (JRE)\',\'New York, USA - John F Kennedy Intl (JFK)\',\'New York, USA - La Guardia (LGA)\',\'Newark, USA - Newark Intl Arpt (EWR)\',\'Newburgh, USA - Stewart Airport (SWF)\',\'Newcastle, Australien - Belmont Airport (BEO)\',\'Newcastle, Australien - Williamtown Arpt (NTL)\',\'Newcastle, Grossbritannien - Newcastle Intl (NCL)\',\'Newcastle, Südafrika - Newcastle Intl Arpt (NCS)\',\'Newport, USA - Newport Municipal Arpt (ONP)\',\'Newport, USA - Newport State Arpt (NPT)\',\'Newquay, Grossbritannien - Newquay Civil Arpt (NQY)\',\'Newton, USA - Municipal Newton Arpt (TNU)\',\'Newton, USA - Newton City County Arpt (EWK)\',\'Nha Trang, Vietnam - Nha Trang Arpt (NHA)\',\'Niagara Falls, USA - Niagara Falls Intl Arpt (IAG)\',\'Niigata, Japan - Niigata Arpt (KIJ)\',\'Nimes, Frankreich - Nimes Airport (FNI)\',\'Ningbo, China - Ningbo Arpt (NGB)\',\'Niteroi, Brasilien - Niteroi Arpt (QNT)\',\'Nizhnevartovsk, Russland - Nizhnevartovsk Arpt (NJC)\',\'Nizhniy Novgorod, Russland - Nizhniy Novgorod Arpt (GOJ)\',\'Nizza, Frankreich - Nizza (NCE)\',\'Nogales, Mexiko - Nogales Arpt (NOG)\',\'Nogales, USA - International Arpt (OLS)\',\'Nome, USA - Nome Arpt (OME)\',\'Noosa, Australien - Noosa Airport (NSA)\',\'Norfolk, USA - Karl Stefan Fld (OFK)\',\'Norfolk, USA - Norfolk Intl Arpt (ORF)\',\'Norman Wells, Kanada - Norman Wells Municipal Arpt (YVQ)\',\'Norrkoping, Schweden - Kungsangen Arpt (NRK)\',\'Norseman, Australien - Norseman Arpt (NSM)\',\'North Battleford, Kanada - North Battleford Arpt (YQW)\',\'North Bay, Kanada - North Bay Municipal (YYB)\',\'North Bend, USA - North Bend Municipal (OTH)\',\'North Caicos, Turks- und Caicosinseln - North Caicos Municipal Arpt (NCA)\',\'North Eleuthera, Bahamas - North Eleuthera Intl (ELH)\',\'North Platte, USA - Lee Bird Field (LBF)\',\'North Ronaldsay, Grossbritannien - North Ronaldsay Arpt (NRL)\',\'Norwalk, USA - Norwalk Heliport (ORQ)\',\'Norwich, Grossbritannien - Norwich Airport (NWI)\',\'Norwood, USA - Norwood Ma Arpt (OWD)\',\'Nossi Be, Madagaskar - Fascene Arpt (NOS)\',\'Notodden, Norwegen - Notodden Arpt (NTB)\',\'Nottingham, Grossbritannien - East Midlands Arpt (EMA)\',\'Nottingham, Grossbritannien - Nottingham Arpt (NQT)\',\'Nouackchott, Mauritania - Nouakchott Arpt (NKC)\',\'Noumea, Neu Kaledonien - Magenta Arpt (GEA)\',\'Noumea, Neu Kaledonien - Tontouta Arpt (NOU)\',\'Novo Hamburgo, Brasilien - Novo Hamburgo Arpt (QHV)\',\'Nowra, Australien - Nowra Arpt (NOA)\',\'Nürnberg, Deutschland - Nürnberg (NUE)\',\'Nueva Gerona, Kuba - Rafael Cabrera Arpt (GER)\',\'Nuevo Laredo, Mexiko - Quetzalcoatl Intl (NLD)\',\'Nulato, USA - Nulato Arpt (NUL)\',\'Nullarbor, Australien - Nullarbor Arpt (NUR)\',\'Nykoping, Schweden - Skavsta Airport (NYO)\',\'Nyngan, Australien - Nyngan Arpt (NYN)\',\'Oak Harbor, USA - Oak Harbour Municipal (ODW)\',\'Oakland, USA - Metro Oakland Intl Arpt (OAK)\',\'Oakland, USA - Oakland Conv Ctr Hlpt (JCE)\',\'Oamaru, Neuseeland - Oamaru Airport (OAM)\',\'Oaxaca, Mexiko - Xoxocotlan Arpt (OAX)\',\'Obihiro, Japan - Obihiro Arpt (OBO)\',\'Ocala, USA - Taylor Field (OCF)\',\'Ocean City, USA - Ocean City Airport (OCE)\',\'Ocean Reef, USA - Ocean Reef Arpt (OCA)\',\'Oceanside, USA - Oceanside Municipal Arpt (OCN)\',\'Odate Noshiro, Japan - Odate Noshiro Arpt (ONJ)\',\'Odense, Dänemark - Odense Airport (ODE)\',\'Odessa, Ukraine - Central Arpt (ODS)\',\'Ogallala, USA - Searle Field (OGA)\',\'Ogden, USA - Ogden Municipal (OGD)\',\'Ogdensburg, USA - Ogdensburg Municipal (OGS)\',\'Oita, Japan - Oita Arpt (OIT)\',\'Okayama, Japan - Okayama Arpt (OKJ)\',\'Okeechobee, USA - Okeechobee County Arpt (OBE)\',\'Okinawa, Japan - Naha Field (OKA)\',\'Okino Erabu, Japan - Okino Erabu Arpt (OKE)\',\'Oklahoma City, USA - Downtown Airpark (DWN)\',\'Oklahoma City, USA - Wiley Post Arpt (PWA)\',\'Oklahoma City, USA - Will Rogers World Arpt (OKC)\',\'Olbia, Italien - Olbia (Sardinien) (OLB)\',\'Olsztyn, Polen - Olsztyn Arpt (QYO)\',\'Olympia, USA - Olympia Arpt (OLM)\',\'Olympic Dam, Australien - Olympic Dam Arpt (OLP)\',\'Omaha, USA - Eppley Airfield (OMA)\',\'Omaha, USA - Millard Airport (MIQ)\',\'Oneonta, USA - Oneonta Municpal (ONH)\',\'Ontario, USA - Ontario Intl (ONT)\',\'Oradea, Rumänien - Oradea Arpt (OMR)\',\'Oran, Algerien - Oran (ORN)\',\'Orange, Australien - Cudal Arpt (CUG)\',\'Orange, Australien - Springhill Arpt (OAG)\',\'Oranjemund, Namibia - Oranjemund Arpt (OMD)\',\'Orlando, USA - Herndon Arpt (ORL)\',\'Orlando, USA - Orlando Intl Arpt (MCO)\',\'Ornskoldsvik, Schweden - Ornskoldsvik Arpt (OER)\',\'Orpheus Island, Australien - Waterport Arpt (ORS)\',\'Orsta Volda, Norwegen - Hovden Arpt (HOV)\',\'Osaka, Japan (OSA)\',\'Osaka, Japan - Itami Arpt (ITM)\',\'Osaka, Japan - Kansai International Arpt (KIX)\',\'Oshawa, Kanada - Oshawa Municipal Arpt (YOO)\',\'Oshima, Japan - Oshima Arpt (OIM)\',\'Oshkosh, USA - Wittman Field (OSH)\',\'Oskarshamn, Schweden - OSkarshamn (OSK)\',\'Oslo, Norwegen - Fornebu Arpt (FBU)\',\'Oslo, Norwegen - Gardemoen Arpt (GEN)\',\'Oslo, Norwegen - Oslo (OSL)\',\'Osorno, Chile - Canal Balo Arpt (ZOS)\',\'Ostend, Belgien - Ostend Airport (OST)\',\'Ostersund, Schweden - Froesoe Airport (OSD)\',\'Ostrava, Tschechien - Mosnov Arpt (OSR)\',\'Ottawa, Kanada - Ottawa Intl Arpt (YOW)\',\'Ottumwa, USA - Industrial Arpt (OTM)\',\'Ouazazate, Marokko - Ourzazate (OZZ)\',\'Oudtshoorn, Südafrika - Oudtshoorn Arpt (OUH)\',\'Oujda, Marokko - Les Angades Arpt (OUD)\',\'Oulu, Finnland - Oulu Airport (OUL)\',\'Ourilandia, Brasilien - Ourilandia Arpt (OIA)\',\'Ovda, Israel - Ovda Arpt (VDA)\',\'Oviedo, Spanien - Asturias Airport (OVD)\',\'Owatonna, USA - Owatonna Arpt (OWA)\',\'Owen Sound, Kanada - Billy Bishop Regional Arpt (YOS)\',\'Oxford, Grossbritannien - Brize Norton Raf Station (BZZ)\',\'Oxford, Grossbritannien - Kidlington Arpt (OXF)\',\'Oxnard / Ventura, USA - Oxnard Ventura Arpt (OXR)\',\'Padang, Indonesien - Tabing Arpt (PDG)\',\'Paderborn, Deutschland - Paderborn (PAD)\',\'Paducah, USA - Buckley Regional (PAH)\',\'Page, USA - Page Airport (PGA)\',\'Pago Pago, Samoa - Pago Pago Arpt (PPG)\',\'Pagosa Springs, USA - Stevens Field Arpt (PGO)\',\'Painesville, USA - Casement Arpt (PVZ)\',\'Pakersburg / Marietta, USA - Wood County (PKB)\',\'Pakuashipi, Kanada - Pakuashipi Arpt (YIF)\',\'Palembang, Indonesien - Mahmud Badaruddin Li Arpt (PLM)\',\'Palenque, Mexiko - Palenque Arpt (PQM)\',\'Palermo, Italien - Palermo/Sizilien (PMO)\',\'Palm Desert, USA - Bermuda Dunes Arpt (UDD)\',\'Palm Springs, USA - Palm Springs Municipal (PSP)\',\'Palmas, Brasilien - Palmas Arpt (PMW)\',\'Palmdale, USA - Airforce 42 (PMD)\',\'Palmerston, Neuseeland - Palmerstown North Arpt (PMR)\',\'Palo Alto, USA - Palo Alto Arpt (PAO)\',\'Pamplona, Spanien - Pamplona Noain Arpt (PNA)\',\'Panama City, USA - Bay County Arpt (PFN)\',\'Panama, Panama - Paitilla Arpt (PAC)\',\'Panama, Panama - Tocumen Intl Arpt (PTY)\',\'Pangkor, Malaysia - Pangkor Arpt (PKG)\',\'Pangnirtung, Kanada - Pangnirtung Arpt (YXP)\',\'Papa Westray, Grossbritannien - Papa Westray Arpt (PPW)\',\'Papeete, Französisch-Polynesien - Intl Tahiti Faaa (PPT)\',\'Paphos, Zypern - Paphos Intl Airport (PFO)\',\'Paraburdoo, Australien - Paraburdoo Arpt (PBO)\',\'Paramaribo, Suriname - Zanderij Intl Arpt (PBM)\',\'Paramaribo, Suriname - Zorg En Hoop Arpt (ORG)\',\'Parana, Argentinien - Parana Arpt (PRA)\',\'Paranagua, Brasilien - Paranagua Municipal (PNG)\',\'Paranagua, Brasilien - Petrolina Internacional Arpt (PNZ)\',\'Paraparaumu, Neuseeland - Paraparaumu Arpt (PPQ)\',\'Pardubice, Tschechien - Pardubice Arpt (PED)\',\'Paris, Frankreich (PAR)\',\'Paris, Frankreich - Disneyland Paris Heliport (DLP)\',\'Paris, Frankreich - Issy Les Moulineaux Arpt (JDP)\',\'Paris, Frankreich - Le Bourget Arpt (LBG)\',\'Paris, Frankreich - Orly (ORY)\',\'Paris, Frankreich - Paris (CDG)\',\'Paris, Frankreich - Villacoublay (VIY)\',\'Paris, USA - Henry County Arpt (PHT)\',\'Paris, USA - Paris Cox Field Arpt (PRX)\',\'Parkes, Australien - Parkes Arpt (PKE)\',\'Parma, Italien - Parma Arpt (PMF)\',\'Parnaiba, Brasilien - Santos Dumont Airport (PHB)\',\'Paros, Griechenland - Paros Community Arpt (PAS)\',\'Parry Sound, Kanada - Parry Sound Municipal Arpt (YPD)\',\'Pascagoula, USA - Jackson Cnty (PGL)\',\'Pasco, USA - Tri city Arpt (PSC)\',\'Paso Robles, USA - Paso Robles Cty (PRB)\',\'Passo Fundo, Brasilien - Passo Fundo Arpt (PFB)\',\'Patna, Indien - Patna Arpt (PAT)\',\'Pato Branco, Brasilien - Pato Branco Municipal (PTO)\',\'Patras, Griechenland - Araxos Arpt (GPA)\',\'Pattaya, Thailand - Pattaya Arpt (PYX)\',\'Pau, Frankreich - Uzein Airport (PUF)\',\'Pavlodar, Kasachstan - Pavlodar (PWQ)\',\'Payson, USA - Payson Arpt (PJB)\',\'Peace River, Kanada - Peace River Municipal Arpt (YPE)\',\'Pekanbaru, Indonesien - Simpang Tiga Arpt (PKU)\',\'Peking, China (BJS)\',\'Peking, China - Peking Capital Arpt (PEK)\',\'Pellston, USA - Emmet Cty Arpt (PLN)\',\'Pelly Bay, Kanada - Dewline Site Arpt (YUF)\',\'Pelly Bay, Kanada - Townsite Arpt (YBB)\',\'Pelotas, Brasilien - Pelotas Federal Arpt (PET)\',\'Pembroke, Kanada - Pembroke And Area (YTA)\',\'Penang, Malaysia - Penang Intl Arpt (PEN)\',\'Pendleton, USA - Pendleton Municipal (PDT)\',\'Penglai, China - Sha He Kou Arpt (PNJ)\',\'Pensacola, USA - Pensacola Regional Municipal (PNS)\',\'Penticton, Kanada - Penticton Municipal Arpt (YYF)\',\'Penza, Russland - Penza Arpt (PEZ)\',\'Penzance, Grossbritannien - Penzance Arpt (PZE)\',\'Peoria, USA - Greater Peoria Arpt (PIA)\',\'Pereira, Kolumbien - Matecana Arpt (PEI)\',\'Perigueux, Frankreich - Perigueux Arpt (PGX)\',\'Perm, Russland - Perm Arpt (PEE)\',\'Perpignan, Frankreich - Llabanere Arpt (PGF)\',\'Perth, Australien - Perth Arpt (PER)\',\'Peru, USA - Illinois Valley Regional Arpt (VYS)\',\'Perugia, Italien - Sant Egidio Arpt (PEG)\',\'Pescara, Italien - Liberi Airport (PSR)\',\'Peschiei, Italien - Peschiei Arpt (PEJ)\',\'Peshawar, Pakistan - Peshawar (PEW)\',\'Peterborough, Kanada - Peterborough Arpt (YPQ)\',\'Petersburg, USA - Petersburg Municipal (PSG)\',\'Petersburg, USA - Petersburg Municipal Arpt (PTB)\',\'Petropavlovsk Kamchatskiy, Russland - Petropavlovsk Kamchatskiy Arpt (PKC)\',\'Petropavlovsk, Kamchatka, Russland - Petropavlovsk, Kamchatka (PPK)\',\'Petrozavodsk, Russland - Petrozavodsk Arpt (PES)\',\'Phalaborwa, Südafrika - Hlndrick Van Eck Arpt (PHW)\',\'Phan Thiet, Vietnam - Phan Thiet Arpt (PHH)\',\'Philadelphia, USA - Philadelphia Intl Arpt (PHL)\',\'Philipsburg, USA - Midstate Arpt (PSB)\',\'Phitsanulok, Thailand - Phitsanulok Arpt (PHS)\',\'Phnom Penh, Kambodscha - Pochentong Arpt (PNH)\',\'Phoenix / Scottsdale, USA - Sky Harbor Intl Arpt (PHX)\',\'Phrae, Thailand - Phrae Arpt (PRH)\',\'Phu Quoc, Vietnam - Duong Dang Arpt (PQC)\',\'Phuket, Thailand - Phuket Intl Airport (HKT)\',\'Pickle Lake, Kanada - Provincial Airport (YPL)\',\'Pico Island, Portugal - Pico Arpt (PIX)\',\'Picton, Neuseeland - Koromiko (PCN)\',\'Piedras Negras, Mexiko - Piedras Negras Intl Arpt (PDS)\',\'Pierre, USA - Pierre Municipal (PIR)\',\'Piestany, Slovakei - Piestany Arpt (PZY)\',\'Pietermaritzburg, Südafrika - Pietermaritzburg Arpt (PZB)\',\'Pietersburg, Südafrika - Pietersburg Arpt (PTG)\',\'Pine Bluff, USA - Pine Bluff Arpt (PBF)\',\'Pinotepa Nacional, Mexiko - Pinotepa Nacional Arpt (PNO)\',\'Pisa, Italien - Florenz / Pisa (PSA)\',\'Pittsburg, USA - Atkinson Municipal Arpt (PTS)\',\'Pittsburgh, USA - Allegheny Cty Arpt (AGC)\',\'Pittsburgh, USA - Pittsburgh Intl Arpt (PIT)\',\'Pittsfield, USA - Pittsfield Municipal (PSF)\',\'Piura, Peru - Piura Arpt (PIU)\',\'Placencia, Belize - Placencia Arpt (PLJ)\',\'Plainview, USA - Hale County Arpt (PVW)\',\'Plattsburgh, USA - Clinton Cty Municipal (PLB)\',\'Playa De Carmen, Mexiko - Playa Del Carmen Arpt (PCM)\',\'Pleasanton, USA - Hacienda Business Park Hlpt (JBS)\',\'Pleiku, Vietnam - Pleiku Arpt (PXU)\',\'Plettenberg Bay, Südafrika - Plettenberg Bay Arpt (PBZ)\',\'Plymouth, Grossbritannien - Roborough Arpt (PLH)\',\'Plymouth, USA - Plymouth Municipal Arpt (PLY)\',\'Pocatello, USA - Pocatello Municipal Arpt (PIH)\',\'Podgorica, Montenegro - Flughafen Podgorica (TGD)\',\'Pohang, Republik Korea - Pohang Arpt (KPO)\',\'Point Lay, USA - Dew Station Arpt (PIZ)\',\'Pointe Noire, Kongo - Pointe Noire Arpt (PNR)\',\'Pointe-A-Pitre, Guadeloupe - Le Raizet Arpt (PTP)\',\'Poitiers, Frankreich - Biard Airport (PIS)\',\'Pokhara, Nepal - Pokhara Arpt (PKR)\',\'Poltava, Ukraine - Poltava Arpt (PLV)\',\'Pompano Beach, USA - Pompano Beach Arpt (PPM)\',\'Ponca City, USA - Ponca City Municipal Arpt (PNC)\',\'Ponce, USA - Mercedita Arpt (PSE)\',\'Ponta Delgada, Portugal - Nordela Arpt (PDL)\',\'Ponta Pora, Brasilien - International (PMG)\',\'Pontiac, USA - Oakland Pontiac Arpt (PTK)\',\'Pontoise, Frankreich - Cormeille En Vexin (POX)\',\'Popayan, Kolumbien - Machangara Arpt (PPN)\',\'Poplar Bluff, USA - Earl Fields Memorial (POF)\',\'Porbandar, Indien - Porbandar Arpt (PBD)\',\'Pori, Finnland - Pori Airport (POR)\',\'Porlamar, Venezuela - Delcaribe Gen S Marino Arpt (PMV)\',\'Port Alberni, Kanada - Port Alberni Arpt (YPB)\',\'Port Angeles, USA - William Fairchild Intl Arpt (CLM)\',\'Port au Prince, Haiti - Mais Gate Arpt (PAP)\',\'Port Augusta, Australien - Port Augusta Arpt (PUG)\',\'Port Blair, Indien - Port Blair Arpt (IXZ)\',\'Port Douglas, Australien - Port Douglas Arpt (PTI)\',\'Port Elizabeth, Südafrika - H F Verwoerd Arpt (PLZ)\',\'Port Hardy, Kanada - Port Hardy Municipal (YZT)\',\'Port Hawkesbury, Kanada - Port Hawkesbury Arpt (YPS)\',\'Port Hedland, Australien - Port Hedland Arpt (PHE)\',\'Port Huron, USA - St Clair County Intl Arpt (PHN)\',\'Port Lincoln, Australien - Port Lincoln Arpt (PLO)\',\'Port Menier, Kanada - Port Menier Arpt (YPN)\',\'Port Moresby, Papua Neu Guinea - Jackson Field (POM)\',\'Port of Spain, Trinidad & Tobago - Piarco Arpt (POS)\',\'Port Pirie, Australien - Port Porie Arpt (PPI)\',\'Port Vila, Vanuatu - Bauerfield Arpt (VLI)\',\'Portimao, Portugal - Portimao Airport (PRM)\',\'Portland, Australien - Portland Arpt (PTJ)\',\'Portland, USA - Portland Intl Arpt (PDX)\',\'Portland, USA - Portland Intl Jetport (PWM)\',\'Porto Alegre, Brasilien - Porto Alegre Airport (POA)\',\'Porto Santo / Madeira, Portugal - Porto Santo Arpt (PXO)\',\'Porto Seguro, Brasilien - Porto Seguro (BPS)\',\'Porto Velho, Brasilien - Belmonte Arpt (PVH)\',\'Porto, Portugal - Porto Airport (OPO)\',\'Portoheli, Griechenland - Alexion Arpt (PKH)\',\'Portoroz, Slowenien - Portoroz Airport (POW)\',\'Portsmouth, Grossbritannien - Portsmouth Arpt (PME)\',\'Portsmouth, USA - Pease AFB (PSM)\',\'Posadas, Argentinien - Posadas Arpt (PSS)\',\'Posen / Poznan, Polen - Lawica Arpt (POZ)\',\'Poste De La Baleine, Kanada - Kuujjuaraapik Arpt (YGW)\',\'Pottstown, USA - Pottstown Limerick (PTW)\',\'Poughkeepsie, USA - Dutchess County (POU)\',\'Powell River, Kanada - Westview Arpt (YPW)\',\'Poza Rica, Mexiko - Tajin Arpt (PAZ)\',\'Prag, Tschechien - Prag-Ruzyne (PRG)\',\'Praia, Kap Verde - Francisco Mendes (RAI)\',\'Prairie Du Chien, USA - Prairie Du Chien Municipal Arpt (PCD)\',\'Praslin Island, Seychellen - Praslin Island Arpt (PRI)\',\'Prescott, USA - Prescott Municipal (PRC)\',\'Presidente Prudente, Brasilien - A De Barros (PPB)\',\'Presque Isle, USA - Northern Maine Regional (PQI)\',\'Pretoria, Südafrika - Wonderboom Arpt (PRY)\',\'Preveza / Lefkas, Griechenland - Aktion Arpt (PVK)\',\'Price, USA - Carbon Cty Municipal Arpt (PUC)\',\'Prince Albert, Kanada - Prince Albert Municipal Arpt (YPA)\',\'Prince George, Kanada - Prince George Municipal (YXS)\',\'Prince Rupert, Kanada - Digby Island Arpt (YPR)\',\'Prince Rupert, Kanada - Seal Cove Arpt (ZSW)\',\'Princeville, USA - Princeville Arpt (HPV)\',\'Pristina, Kosovo - Flughafen Pristina (PRN)\',\'Propriano, Frankreich - Propriano Arpt (PRP)\',\'Proserpine, Australien - Proserpine Arpt (PPP)\',\'Providc.Turks&Caicos Is., Turks- und Caicosinseln - Providenciales Intl (PLS)\',\'Providence, USA - T F Green St Arpt (PVD)\',\'Provincetown, USA - Provincetown Municipal (PVC)\',\'Provo, USA - Provo Arpt (PVU)\',\'Prudhoe Bay Deadhorse, USA - Prudhoe Bay Deadhorse Arpt (SCC)\',\'Pskov, Russland - Pskov Arpt (PKV)\',\'Pt Macquarie, Australien - Port Mac Quarie Airport (PQQ)\',\'Pucallpa, Peru - Capitan Rolden Arpt (PCL)\',\'Pucon, Chile - Pucon Arpt (ZPC)\',\'Puebla, Mexiko - Huejostingo Arpt (PBC)\',\'Pueblo, USA - Las Animas Arpt (TAD)\',\'Pueblo, USA - Pueblo Arpt (PUB)\',\'Puerto Aisen, Chile - Puerto Aisen Arpt (WPA)\',\'Puerto Escondido, Mexiko - Puerto Escondido Municipal (PXM)\',\'Puerto La Victoria, Paraguay - Puerto La Victoria Arpt (PCJ)\',\'Puerto Madryn, Argentinien - El Tehuelche Arpt (PMY)\',\'Puerto Maldonado, Peru - Puerto Maldonado Arpt (PEM)\',\'Puerto Montt, Chile - Tepual Airport (PMC)\',\'Puerto Natales, Chile - Teniente Julio Gallardo Arpt (PNT)\',\'Puerto Penasco, Mexiko - Puerto Penasco Municipal (PPE)\',\'Puerto Plata, Dominikanische Republik - La Union Arpt (POP)\',\'Puerto Princesa, Philippinen - Puerto Princesa Arpt (PPS)\',\'Puerto Vallarta, Mexiko - Ordaz Arpt (PVR)\',\'Pula, Kroatien - Pula Arpt (PUY)\',\'Pulaski, USA - Pulaski New River Valley Arpt (PSK)\',\'Pullman, USA - Pullman Moscow Arpt (PUW)\',\'Pune, Indien - Lohegaon Arpt (PNQ)\',\'Punta Arenas, Chile - Presidente Ibanez Arpt (PUQ)\',\'Punta Cana, Dominikanische Republik - Punta Cana (PUJ)\',\'Punta Del Este, Uruguay - Cap Curbelo Arpt (PDP)\',\'Punta Garda, USA - Charlotte County (PGD)\',\'Punta Renes, Costa Rica - Punta Renes Arpt (JAP)\',\'Pusan, Republik Korea - Kimhae Arpt (PUS)\',\'Puvirnituq, Kanada - Povungnituk Arpt (YPX)\',\'Qingdao, China - Liuting Arpt (TAO)\',\'Qinhuangdao, China - Qinhuangdao Arpt (SHP)\',\'Qiqihar, China - Qiqihar Arpt (NDG)\',\'Quakertown, USA - Upper Bucks Arpt (UKT)\',\'Qualicum, Kanada - Qualicum Arpt (XQU)\',\'Quaqtaq, Kanada - Quaqtaq Arpt (YQC)\',\'Quebec, Kanada - Quebec Intl (YQB)\',\'Quebec, Kanada - Riviere Du Loup Arpt (YRI)\',\'Queen Charlotte Island, Kanada - Queen Charlotte Island Arpt (ZQS)\',\'Queensboro, USA - Daviess County Arpt (OWB)\',\'Queenstown, Australien - Queenstown Arpt (UEE)\',\'Queenstown, Neuseeland - Frankton Airport (ZQN)\',\'Queenstown, Südafrika - Queenstown Airport (UTW)\',\'Quepos, Costa Rica - Quepos Arpt (XQP)\',\'Queretaro, Mexiko - Queretaro Arpt (QRO)\',\'Quesnel, Kanada - Quesnel Arpt (YQZ)\',\'Qui Nhon, Vietnam - Qui Nhon Arpt (UIH)\',\'Quilpie, Australien - Quilpie Arpt (ULP)\',\'Quimber, Frankreich - Pluguffan Arpt (UIP)\',\'Quincy, USA - Baldwin Field (UIN)\',\'Quirindi, Australien - Quirindi Arpt (UIR)\',\'Quito, Ecuador - Mariscal Arpt (UIO)\',\'Rabat, Marokko - Sale Airport (RBA)\',\'Rabaul, Papua Neu Guinea - Lakunai Arpt (RAB)\',\'Rabil, Kap Verde - Aeroporto de Rabil (BVC)\',\'Rach Gia, Vietnam - Rach Gia Arpt (VKG)\',\'Raiatea, Französisch-Polynesien - Raiatea Arpt (RFP)\',\'Rainbow Lake, Kanada - Rainbow Lake Arpt (YOP)\',\'Raleigh / Durham, USA - Raleigh Durham Intl Arpt (RDU)\',\'Ranger, USA - Ranger Municipal Arpt (RGR)\',\'Rangiroa Island, Französisch-Polynesien - Rangiroa Arpt (RGI)\',\'Rangoon, Myanmar - Mingaladon (RGN)\',\'Rankin Inlet, Kanada - Rankin Inlet Arpt (YRT)\',\'Ranong, Thailand - Ranong Arpt (UNN)\',\'Rapid City, USA - Regional Arpt (RAP)\',\'Rarotonga, Cook Islands - Rarotonga Arpt (RAR)\',\'Ras al Khaymah, VAE - Ras Al Khaimah Arpt (RKT)\',\'Raton, USA - Crews Fld (RTN)\',\'Rawlins, USA - Rawlins Municipal (RWL)\',\'Reading, USA - Reading Municipal (RDG)\',\'Recife, Brasilien - Recife Airport (REC)\',\'Red Lake, Kanada - Federal Red Lake (YRL)\',\'Redding, USA - Flight Service Station (RBL)\',\'Redding, USA - Redding Municipal Arpt (RDD)\',\'Redmond, USA - Roberts Field (RDM)\',\'Reggio Calabria, Italien - Tito Menniti Arpt (REG)\',\'Regina, Kanada - Moose Jaw Arpt (YMJ)\',\'Regina, Kanada - Regina Municipal (YQR)\',\'Reims, Frankreich - Champagne Arpt (RHE)\',\'Renmark, Australien - Renmark Airport (RMK)\',\'Rennes, Frankreich - Saint Jacques Arpt (RNS)\',\'Reno, USA - Reno Cannon Intl Arpt (RNO)\',\'Reno, USA - Truckee Airport (TKF)\',\'Resistencia, Argentinien - Resistencia Arpt (RES)\',\'Reykjavik, Island - Keflavik Intl Arpt (KEF)\',\'Reykjavik, Island - Reykjavik Arpt (REK)\',\'Reykjavik, Island - Reykjavik Domestic Arpt (RKV)\',\'Reynosa, Mexiko - General Lucio Blanco Arpt (REX)\',\'Rhinelander, USA - Oneida County (RHI)\',\'Rhodos, Griechenland - Diagoras Arpt (RHO)\',\'Ribeirao Preto, Brasilien - Leite Lopes (RAO)\',\'Richards Bay, Südafrika - Richards Bay Arpt (RCB)\',\'Richfield, USA - Reynolds Municipal Arpt (RIF)\',\'Richmond, USA - Byrd Intl (RIC)\',\'Rifle, USA - Garfield Cty Arpt (RIL)\',\'Riga, Lettland - Riga Arpt (RIX)\',\'Rijeka, Kroatien - Rijeka Arpt (RJK)\',\'Rimini, Italien - Miramare Airport (RMI)\',\'Rimouski Mont Joli, Kanada - Mont Joli (YYY)\',\'Rimouski, Kanada - Rimouski Municipal Arpt (YXK)\',\'Rio Branco, Brasilien - Pres Medici Arpt (RBR)\',\'Rio Cuarto, Argentinien - Rio Cuarto Arpt (RCU)\',\'Rio de Janeiro, Brasilien (RIO)\',\'Rio de Janeiro, Brasilien - Rio Internacional (GIG)\',\'Rio de Janeiro, Brasilien - Santos Dumont Arpt (SDU)\',\'Rio Gallegos, Argentinien - Rio Gallegos Internacional Arpt (RGL)\',\'Rio Grande, Argentinien - Rio Grande Arpt (RGA)\',\'Rio Grande, Brasilien - Rio Grande Airport (RIG)\',\'Riverside, USA - Riverside Municipal (RAL)\',\'Riverton, USA - Riverton Municipal (RIW)\',\'Riyadh, Saudi Arabien - King Khaled Intl (RUH)\',\'Roanne, Frankreich - Renaison Arpt (RNE)\',\'Roanoke Rapids, USA - Halifax Cty Arpt (RZZ)\',\'Roanoke, USA - Roanoke Regional Arpt (ROA)\',\'Roatan, Honduras - Roatan Arpt (RTB)\',\'Roberval, Kanada - Roberval Airport (YRJ)\',\'Roche Harbor, USA - Roche Harbor Arpt (RCE)\',\'Rochefort, Frankreich - Saint Agnant Arpt (RCO)\',\'Rochester, USA - Monroe Cty Arpt New York (ROC)\',\'Rochester, USA - Rochester Municipal (RST)\',\'Rock Sound, Bahamas - S Eleuthera Arpt (RSD)\',\'Rock Springs, USA - Rock Springs Municipal (RKS)\',\'Rockford, USA - Peoria Rockford Bus Terminal (ZRF)\',\'Rockford, USA - Rockford Arpt (RFD)\',\'Rockhampton, Australien - Rockhampton Arpt (ROK)\',\'Rockland, USA - Rockland Arpt (RKD)\',\'Rocky Mount, USA - Wilson Arpt (RWI)\',\'Rodez, Frankreich - Marcillac (RDZ)\',\'Roervik, Norwegen - Ryumsjoen Arpt (RVK)\',\'Rogers, USA - Rogers Arpt (ROG)\',\'Rolla, USA - National Arpt (RLA)\',\'Rom, Italien (ROM)\',\'Rom, Italien - Rom-Ciampino (CIA)\',\'Rom, Italien - Rom-Fiumicino (FCO)\',\'Roma, Australien - Roma Arpt (RMA)\',\'Rome, USA - Richard B Russell Arpt (RMG)\',\'Rondonopolis, Brasilien - Rondonopolis Arpt (ROO)\',\'Ronneby, Schweden - Kallinge Arpt (RNB)\',\'Roros, Norwegen - Roros Arpt (RRS)\',\'Rosario, Argentinien - Fisherton Airport (ROS)\',\'Roseburg, USA - Roseburg Municipal (RBG)\',\'Rosh Pina, Israel - Rosh Pina Arpt (RPN)\',\'Roskilde, Dänemark - Roskilde Arpt (RKE)\',\'Rostov, Russland - Rostov Arpt (ROV)\',\'Roswell, USA - Industrial Aircenter (ROW)\',\'Rota, Marianna Islands - Rota Arpt (ROP)\',\'Rotorua, Neuseeland - Rotorua Arpt (ROT)\',\'Rotterdam, Niederlande - Rotterdam Arpt (RTM)\',\'Rottnest, Australien - Rottnest Island Arpt (RTS)\',\'Rouen, Frankreich - Boos Airport (URO)\',\'Rouyn Noranda, Kanada - Rouyn Noranda Arpt (YUY)\',\'Rovaniemi, Finnland - Rovaniemi Arpt (RVN)\',\'Ruidoso, USA - Ruidoso Municipal Arpt (RUI)\',\'Ruston, USA - Ruston Regional Arpt (RSN)\',\'Rutland, USA - Rutland Arpt (RUT)\',\'Rzeszow, Polen - Jasionka Arpt (RZE)\',\'Saarbrücken, Deutschland - Ensheim Arpt (SCN)\',\'Saarmelleek, Ungarn - Saarmelleek Balaton Arpt (SOB)\',\'Saba, Niederländische Antillen - Juancho Yraus Quinl (SAB)\',\'Sacramento, USA - Mather Air Force Base (MHR)\',\'Sacramento, USA - Sacramento Executive Arpt (SAC)\',\'Sacramento, USA - Sacramento Metropolitan (SMF)\',\'Saga, Japan - Saga Arpt (HSG)\',\'Saginaw, USA - Saginaw Arpt (MBS)\',\'Saguenay, Kanada - Bagotville Arpt (YBG)\',\'Saint Augustine, USA - St Augustine Arpt (UST)\',\'Saint Brieuc, Frankreich - Tremuson Armor Arpt (SBK)\',\'Saint Cloud, USA - Saint Cloud Municipal (STC)\',\'Saint Entienne, Frankreich - Boutheon Arpt (EBU)\',\'Saint George, USA - Saint George Municipal Arpt (SGU)\',\'Saint John, Kanada - Saint John Municipal (YSJ)\',\'Saint Johns, Kanada - Saint Johns Arpt (YYT)\',\'Saint Kitts, St. Kitts - Nevis - Golden Rockus Quinl Arpt (SKB)\',\'Saint Leonard, Kanada - Edmonton Arpt (YSL)\',\'Saint Louis, USA - East St Louis (CPS)\',\'Saint Louis, USA - Lambert St Louis Arpt (STL)\',\'Saint Louis, USA - Spirit Of St Louis Arpt (SUS)\',\'Saint Lucia, Dominica - Hewanorra (UVF)\',\'Saint Lucia, Dominica - Vigie Field (SLU)\',\'Saint Maarten, Niederländische Antillen - Juliana Arpt (SXM)\',\'Saint Nazaire, Frankreich - Montoir Airport (SNR)\',\'Saint Paul, USA - Downtown St Paul Arpt (STP)\',\'Saint Petersburg, USA - Saint Petersburg Clearwater Arpt (PIE)\',\'Saint Petersburg, USA - Whitted Airport (SPG)\',\'Saint Pierre, Kanada - Saint Pierre Arpt (FSP)\',\'Saint Theris Point, Kanada - Saint Therese Pt Municipal (YST)\',\'Saint Thomas, USA - Cyril E King Arpt (STT)\',\'Saint Tropez, Frankreich (LTT)\',\'Saint Tropez, Frankreich - St Tropez Hlpt (JSZ)\',\'Saipan, Marianna Islands - Saipan Intl (SPN)\',\'Sakon Nakhon, Thailand - Sakon Nakhon Arpt (SNO)\',\'Sal, Kap Verde - Amilcar Cabral Intl Arpt (SID)\',\'Salalah, Oman - Salalah Arpt (SLL)\',\'Salamanca, Spanien - Matacan Arpt (SLM)\',\'Saldanha Bay, Südafrika - Langebaanweg Arpt (SDB)\',\'Sale, Australien - Sale Arpt (SXE)\',\'Salem, USA - McNary Field (SLE)\',\'Salina Cruz, Mexiko - Salina Cruz Arpt (SCX)\',\'Salina, USA - Salina Municipal (SLN)\',\'Salisbury, USA - Salisbury Wicomico Cty Arpt (SBY)\',\'Salluit, Kanada - Salluit Arpt (YZG)\',\'Salmon Arm, Kanada - Salmon Arm Municipal (YSN)\',\'Salt Lake City, USA - Salt Lake City Intl Arpt (SLC)\',\'Salta, Argentinien - General Belgrano Intl Arpt (SLA)\',\'Saltillo, Mexiko - Saltillo Arpt (SLW)\',\'Salto, Uruguay - Salto Arpt (STY)\',\'Salvador, Brasilien - Dois De Julho Arpt (SSA)\',\'Salzburg, Österreich - Salzburg Arpt (SZG)\',\'Samana, Dominikanische Republik - El Portillo Arpt (EPS)\',\'Samana, Dominikanische Republik - Samana International (AZS)\',\'Samara, Russland - Samara Arpt (KUF)\',\'Samarkand, Usbekistan - Samarkand Arpt (SKD)\',\'Sambava, Madagaskar - Sambava Arpt (SVB)\',\'Samos, Griechenland - Samos Arpt (SMI)\',\'Samsun, Türkei (SSX)\',\'Samsun, Türkei - Carsamba Arpt (SZF)\',\'San Andres Island, Kolumbien - San Andres Island Arpt (ADZ)\',\'San Angelo, USA - Mathis Field (SJT)\',\'San Antonio, USA - San Antonio Intl (SAT)\',\'San Antonio, Venezuela - San Antonio Arpt (SVZ)\',\'San Bernardino, USA (SBT)\',\'San Bernardino, USA - San Bernardino Intl Arpt (SBD)\',\'San Carlos de Baril., Argentinien - San Carlos De Bariloche Intl Arpt (BRC)\',\'San Carlos, USA - San Carlos Arpt (SQL)\',\'San Cristobal De Las Casas, Mexiko - San Cristobal Arpt (SZT)\',\'San Cristobal, Ecuador - San Cristobal Airport (SCY)\',\'San Crystobal, Venezuela - Aeropuerto Santo Domingo (SCI)\',\'San Diego, USA - Brown Fld Municipal (SDM)\',\'San Diego, USA - Gillespie Field (SEE)\',\'San Diego, USA - Lindbergh Intl Arpt (SAN)\',\'San Diego, USA - Montogomery Fld (MYF)\',\'San Domino Island, Italien - San Domino Island Arpt (TQR)\',\'San Felipe, Mexiko - San Felipe Arpt (SFH)\',\'San Felipe, Venezuela - San Felipe Airport (SNF)\',\'San Felix, Venezuela - San Felix Arpt (SFX)\',\'San Fernando, Philippinen - San Fernando Arpt (SFE)\',\'San Fernando, Venezuela - Las Flecheras (SFD)\',\'San Francisco, USA - China Basin Hlpt (JCC)\',\'San Francisco, USA - San Francisco Intl Arpt (SFO)\',\'San Giovanni Rotondo, Italien - San Giovanni Rotondo Arpt (GBN)\',\'San Jorge, Portugal - San Jorge Arpt (SJZ)\',\'San Jose del Cabo, Mexiko - Los Cabos Arpt (SJD)\',\'San Jose, Costa Rica - Juan Santa Maria Intl (SJO)\',\'San Jose, Costa Rica - Tobias Bolanos Intl (SYQ)\',\'San Jose, USA - Moffett Field (NUQ)\',\'San Jose, USA - Reid Hillview Of Santa Clara County (RHV)\',\'San Jose, USA - San Jose Intl Arpt (SJC)\',\'San Juan, Argentinien - San Juan Arpt (UAQ)\',\'San Juan, USA - Luiz Munoz Marin Intl (SJU)\',\'San Louis Obispo, USA - O Sullivan Army Air Field (CSL)\',\'San Louis Obispo, USA - San Luis Obispo Cty Arpt (SBP)\',\'San Luis Potosi, Mexiko - San Luis Potosi Municipal Arpt (SLP)\',\'San Luis Rio Colorado, Mexiko - San Luis Rio Colorado Municipal (UAC)\',\'San Luis, Argentinien - San Luis Cty Arpt (LUQ)\',\'San Matias, Bolivien - San Matias Arpt (MQK)\',\'San Pedro Sula, Honduras - La Mesa Airport (SAP)\',\'San Pedro, Belize - San Pedro Arpt (SPR)\',\'San Quintin, Mexiko - San Quintin Arpt (SNQ)\',\'San Salvador, Bahamas - San Salvador Arpt (ZSA)\',\'San Salvador, El Salvador - El Salvador Intl Arpt (SAL)\',\'San Sebastian De La Gomera, Spanien - La Gomera Arpt (GMZ)\',\'San Sebastian, Spanien - Fuenterrabia Arpt (EAS)\',\'San Tome, Venezuela - El Tigre Arpt (SOM)\',\'Sanaa, Jemen - Sanaa Intl Airport (SAH)\',\'Sancti Spiritus, Kuba - Sancti Spiritus Arpt (USS)\',\'Sandakan, Malaysia - Sandakan Arpt (SDK)\',\'Sandane, Norwegen - Anda Airport (SDN)\',\'Sanday, Grossbritannien - Sanday Arpt (NDY)\',\'Sandefjord, Norwegen - Torp Arpt (TRF)\',\'Sandnessjoen, Norwegen - Stokka Arpt (SSJ)\',\'Sandspit, Kanada - Federal Airport (YZP)\',\'Sandusky, USA - Griffing Sandusky Arpt (SKY)\',\'Sandy Lake, Kanada - Sandy Lake Arpt (ZSJ)\',\'Sanford, USA - Central Florida Regional Arpt (SFB)\',\'Sanikiluaq, Kanada - Sanikiluaq Arpt (YSK)\',\'Sanli Urfa, Türkei - Sanli Urfa Arpt (SFQ)\',\'Sansibar, Tansania - Kisauni Arpt (ZNZ)\',\'Santa Ana, USA - John Wayne Intl Orange County Arpt (SNA)\',\'Santa Ana, USA - Newport Beach Heliport (JNP)\',\'Santa Ana, USA - Santa Ana Heliport (JOR)\',\'Santa Barbara, USA - Santa Barbara Arpt (SBA)\',\'Santa Barbara, Venezuela - Las Delicias Arpt (STB)\',\'Santa Clara, Kuba - Santa Clara Arpt (SNU)\',\'Santa Cruz Flores, Portugal - Aerodromo Das Flores (FLW)\',\'Santa Cruz, Bolivien - El Trompillo Arpt (SRZ)\',\'Santa Cruz, Bolivien - Viru Viru Intl Arpt (VVI)\',\'Santa Cruz, Costa Rica - Guanacaste Arpt (SZC)\',\'Santa Cruz, USA - Skypark Arpt (SRU)\',\'Santa Fe, Argentinien - Santa Fe Arpt (SFN)\',\'Santa Fe, USA - Santa Fe Municipal (SAF)\',\'Santa Maria, Brasilien - Base Aerea Arpt (RIA)\',\'Santa Maria, Portugal - Vilo Do Porto Arpt (SMA)\',\'Santa Maria, USA - Lompoc Arpt (LPC)\',\'Santa Maria, USA - Santa Maria Public Arpt (SMX)\',\'Santa Marta, Kolumbien - Simon Bolivar (SMR)\',\'Santa Rosa, USA - Sonoma Cty Arpt (STS)\',\'Santa Rosalia, Mexiko - Santa Rosalia Arpt (SRL)\',\'Santa Ynez, USA - Santa Ynez Arpt (SQA)\',\'Santander, Spanien - Santander Airport (SDR)\',\'Santarem, Brasilien - Eduardo Gomes Arpt (STM)\',\'Santia. de Compostela, Spanien - Santiago Airport (SCQ)\',\'Santiago de Chile, Chile - Arturo Merino Benitez (SCL)\',\'Santiago de Chile, Chile - Los Cerrillos (ULC)\',\'Santiago Del Estero, Argentinien - Santiago Des Estero Arpt (SDE)\',\'Santiago, Dominikanische Republik - Santiago Municipal (STI)\',\'Santiago, Kuba - Santiago (SCU)\',\'Santo Domingo, Dominikanische Republik - Las Americas Arpt (SDQ)\',\'Santo Domingo, Venezuela - Mayor Humberto Vivas Guerrero Arpt (STD)\',\'Santos, Brasilien - Santos Arpt (SSZ)\',\'Sanya, China - Sanya Arpt (SYX)\',\'Sao Jose Do Rio Preto, Brasilien - Sao Jose Do Rio Preto (SJP)\',\'Sao Jose Dos Campos, Brasilien - Sao Jose Dos Campos Arpt (SJK)\',\'Sao Luiz, Brasilien - Tirirical Arpt (SLZ)\',\'Sao Paulo, Brasilien (SAO)\',\'Sao Paulo, Brasilien - Congonhas Arpt (CGH)\',\'Sao Paulo, Brasilien - Guarulhos Arpt (GRU)\',\'Sao Paulo, Brasilien - Sao Paulo (GUJ)\',\'Sao Paulo, Brasilien - Viracopos Arpt (VCP)\',\'Sapporo, Japan - Chitose Arpt (CTS)\',\'Sapporo, Japan - Okadama Arpt (OKD)\',\'Sapporo, Japan - Sapporo Airport (SPK)\',\'Sarajevo, Bosnien - Butmir Arpt (SJJ)\',\'Saranac Lake, USA - Adirondack Arpt (SLK)\',\'Sarasota / Bradenton, USA - Sarasota Bradenton Arpt (SRQ)\',\'Saratov, Russland - Saratov Arpt (RTW)\',\'Sarnia, Kanada - Sarnia Airport (YZR)\',\'Saskatoon, Kanada - Kindersley Arpt (YKY)\',\'Saskatoon, Kanada - Saskatoon Municipal (YXE)\',\'Saudarkrokur, Island - Saudarkrokur Arpt (SAK)\',\'Sault Sainte Marie, USA - Chippewa Cnty Intl (CIU)\',\'Sault Sainte Marie, USA - County Airport (SSM)\',\'Sault Ste Marie, Kanada - Sault Ste Marie Arpt (YAM)\',\'Sausalito, USA - Marin County Arpt (JMC)\',\'Savannah, USA - Travis Field (SAV)\',\'Savonlinna, Finnland - Savonlinna Arpt (SVL)\',\'Savusavu, Fidschi - Savusavu Airport (SVU)\',\'Schefferville, Kanada - Schefferville Arpt (YKL)\',\'Schenectady, USA - Schenectady County Arpt (SCH)\',\'Schesqasghan, Kasachstan - Schesqasghan (DZN)\',\'Schymkent, Kasachstan - Schymkent (CIT)\',\'Scone, Australien - Scone Airport (NSO)\',\'Scottsbluff, USA - Scottsbluff Municipal (BFF)\',\'Scottsdale, USA - Scottsdale Municipal Arpt (SCF)\',\'Scranton, USA - Wilkes Barre Scranton Intl Arpt (AVP)\',\'Seattle, USA - Kenmore Air Harbor (KEH)\',\'Seattle, USA - Lake Union Seaplane Base (LKE)\',\'Seattle, USA - Seattle Boeing Field (BFI)\',\'Seattle, USA - Seattle Tacoma Intl Arpt (SEA)\',\'Sebring, USA - Air Terminal Arpt (SEF)\',\'Sechelt, Kanada - Sechelt Arpt (YHS)\',\'Secunda, Südafrika - Secunda Arpt (ZEC)\',\'Sedalia, USA - Sedalia Memorial Arpt (DMO)\',\'Sedona, USA - Sedona Arpt (SDX)\',\'Seinajoki, Finnland - Ilmajoki Arpt (SJY)\',\'Selawik, USA - Selawik Arpt (WLK)\',\'Seldovia, USA - Seldovia Arpt (SOV)\',\'Semarang, Indonesien - Achmad Uani Arpt (SRG)\',\'Semey (Semipalatinsk), Kasachstan - Semey (Semipalatinsk) (PLX)\',\'Sendai, Japan - Sendai Arpt (SDJ)\',\'Seoul, Republik Korea - Gimpo Intl Arpt (GMP)\',\'Seoul, Republik Korea - Incheon International Airport (ICN)\',\'Seoul, Republik Korea - Kimpo Intl (SEL)\',\'Sept Iles, Kanada - Sept Iles Municipal Arpt (YZV)\',\'Sevilla, Spanien - Sevilla (SVQ)\',\'Seward, USA - Seward Airport (SWD)\',\'Sfax, Tunesien - El Maou Airport (SFA)\',\'Shahre Kord, Iran - Shahre Kord Arpt (CQD)\',\'Shanghai, China - Hongqiao (SHA)\',\'Shanghai, China - Pu Dong (PVG)\',\'Shannon, Irland - Shannon Arpt (SNN)\',\'Shantou, China - Shantou Airport (SWA)\',\'Shanzhou, China - Shanzhou Arpt (SZO)\',\'Sharjah, VAE - Sharjah Airport (SHJ)\',\'Sharm el Sheik, Ägypten - Ophira Arpt (SSH)\',\'Sharurah, Saudi Arabien - Sharurah Arpt (SHW)\',\'Shawnee, USA - Shawnee Airport (SNL)\',\'Sheboygan, USA - Sheboygan Arpt (SBM)\',\'Sheffield, Grossbritannien - Sheffield City Arpt (SZD)\',\'Shenyang, China - Shenyang Arpt (SHE)\',\'Shenzhen, China - Shenzhen Arpt (SZX)\',\'Shepparton, Australien - Shepparton (SHT)\',\'Sherbrooke, Kanada - Sherbrooke Airport (YSC)\',\'Sheridan, USA - Sheridan Cty Arpt (SHR)\',\'Sherman, USA - Grayson County Arpt (PNX)\',\'Shetland Islands Area, Grossbritannien (SDZ)\',\'Shetland Islands Area, Grossbritannien - Scatsta (SCS)\',\'Shetland Islands Area, Grossbritannien - Sumburgh Airport (LSI)\',\'Shijiazhuang, China - Daguocun Arpt (SJW)\',\'Shiraz, Iran - Shiraz Arpt (SYZ)\',\'Shonai, Japan - Shonai Arpt (SYO)\',\'Show Low, USA - Show Low Arpt (SOW)\',\'Shreveport, USA - Shreveport Regional Arpt (SHV)\',\'Shute Hrb, Australien - Shute Harbour Heliport (JHQ)\',\'Sialkot, Pakistan - Sialkot Arpt (SKT)\',\'Sibiu, Rumänien - Sibiu (SBZ)\',\'Sibu, Malaysia - Sibu Arpt (SBW)\',\'Sidney, USA - Sidney Municipal (SNY)\',\'Sidney, USA - Sindey Richland Municipal Arpt (SDY)\',\'Siena, Italien - Siena Arpt (SAY)\',\'Siguanea, Kuba - Siguanea Arpt (SZJ)\',\'Silver City, USA - Grant County Airport (SVC)\',\'Simferopol, Ukraine - Simferopol (SIP)\',\'Simla, Indien - Simla Arpt (SLV)\',\'Singapur, Singapur - Changi Intl Arpt (SIN)\',\'Singleton, Australien - Singleton Arpt (SIX)\',\'Sioux City, USA - Sioux Gateway Arpt (SUX)\',\'Sioux Falls, USA - Joe Foss Field (FSD)\',\'Sioux Lookout, Kanada - Sioux Lookout Municipal Arpt (YXL)\',\'Sitka, USA - Sitka Airport (SIT)\',\'Skagway, USA - Skagway Arpt (REP)\',\'Skagway, USA - Skagway Minicipal Arpt (SGY)\',\'Skelleftea, Schweden - Skelleftea Arpt (SFT)\',\'Skiathos, Griechenland - Skiathos Arpt (JSI)\',\'Skien, Norwegen - Skien Arpt (SKE)\',\'Skopje, Mazedonien - Skopje Arpt (SKP)\',\'Skovde, Schweden - Skovde Arpt (KVB)\',\'Skukuza, Südafrika - Skukuza Arpt (SZK)\',\'Sliac, Slovakei - Sliac Arpt (SLD)\',\'Sligo, Irland - Collooney (SXL)\',\'Smithers, Kanada - Smithers Municipal (YYD)\',\'Smithfield, USA - Smithfield Arpt (SFZ)\',\'Smyrna, USA - Smyrna Arpt (MQY)\',\'Soderhamn, Schweden - Soderhamn Arpt (SOO)\',\'Sofia, Bulgarien - Sofia Intl (SOF)\',\'Sogndal, Norwegen - Haukasen Arpt (SOG)\',\'Sokcho, Republik Korea - Seolak Arpt (SHO)\',\'Solo City, Indonesien - Adi Sumarno Arpt (SOC)\',\'Somerset, USA - Pulaski County Arpt (SME)\',\'Son La, Vietnam - Na San Arpt (SQH)\',\'Sonderborg, Dänemark - Sonderborg Arpt (SGD)\',\'Songpan, China - Jiu Zhai Huang Long Arpt (JZH)\',\'Sophia Antipolis, Frankreich - Sophia Antipolis Hlpt (SXD)\',\'Sorocaba, Brasilien - Sorocaba Arpt (SOD)\',\'Sorong, Indonesien - Jefman Arpt (SOQ)\',\'Sorrento, Italien - Sorrento Arpt (RRO)\',\'Sousse, Tunesien - Flughafen Enfidha Zine El Abidine Ben Ali intl. (NBE)\',\'South Andros, Bahamas - South Andros Arpt (TZN)\',\'South Bend, USA - Michiana Regional Arpt (SBN)\',\'South Caicos, Turks- und Caicosinseln - South Caicos Intl Arpt (XSC)\',\'South Molle, Australien - South Molle Island Arpt (SOI)\',\'Southampton, Grossbritannien - Eastleigh Arpt (SOU)\',\'Southend, Grossbritannien - Southend Municipal Arpt (SEN)\',\'Southern Pines, USA - Pinehurst Arpt (SOP)\',\'Sparta, USA - Camp Mccoy Aaf (CMY)\',\'Sparta, USA - Sparta Community Airport (SAR)\',\'Spearfish, USA - Black Hills Clyde Ice Field (SPF)\',\'Spencer, USA - Spencer Municipal (SPW)\',\'Spiddal, Irland - Connemara Arpt (NNR)\',\'Split, Kroatien - Sinj (SPU)\',\'Spokane, USA - Felts Field (SFF)\',\'Spokane, USA - Spokane Intl Arpt (GEG)\',\'Springbok, Südafrika - Springbok Arpt (SBU)\',\'Springdale, USA - Springdale Municipal Arpt (SPZ)\',\'Springfield, USA (SFY)\',\'Springfield, USA - Bradley Intl Arpt (BDL)\',\'Springfield, USA - Brainard Arpt (HFD)\',\'Springfield, USA - Capital Airport (SPI)\',\'Springfield, USA - Springfield Regional Arpt (SGF)\',\'Springfield, USA - Westover Metro (CEF)\',\'Srinagar, Indien - Srinagar Arpt (SXR)\',\'St Anthony, Kanada - St Anthony Arpt (YAY)\',\'St George, Australien - St George Arpt (SGO)\',\'St Helens, Australien - St Helens Arpt (HLS)\',\'St Pierre, Kanada - Pikangikum Arpt (YPM)\',\'St. Denis de la Reunion, Reunion - Gillot Airport (RUN)\',\'St. Gallen, Schweiz - Altenrhein Arpt (ACH)\',\'St. Petersburg, Russland - Pulkovo Airport (LED)\',\'St. Petersburg, Russland - Rzhevka Arpt (RVH)\',\'St.Croix Island, USA - Alexander Hamilton Arpt (STX)\',\'St.Eustatius, Niederländische Antillen - Roosevelt Field (EUX)\',\'St.Martin, Niederländische Antillen - Esperance Airport (SFG)\',\'St.Vincent, Dominica - Arnos Vale Arpt (SVD)\',\'Stanthorpe, Australien - Stanthorpe (SNH)\',\'State College, USA - Univ Park Arpt (SCE)\',\'Statesville, USA - Statesville Municipal Arpt (SVH)\',\'Staunton, USA - Shenahoah Valley Regional (SHD)\',\'Stavanger, Norwegen - Sola Airport (SVG)\',\'Stavropol, Russland - Stavropol Arpt (STW)\',\'Steamboat Springs, USA - Steamboat Arpt (SBS)\',\'Stephenville, Kanada - Stephenville Municipal (YJT)\',\'Stephenville, USA - Clark Field (SEP)\',\'Sterling, USA - Whiteside Cty Municipal (SQI)\',\'Stetin / Szczecin, Polen - Goleniow Arpt (SZZ)\',\'Stevens Point, USA - Stevens Point Municipal (STE)\',\'Stillwater, USA - Searcy Fld (SWO)\',\'Stockholm, Schweden (STO)\',\'Stockholm, Schweden - Arlanda Arpt (ARN)\',\'Stockholm, Schweden - Bromma Airport (BMA)\',\'Stockton, USA - Stockton Metro Arpt (SCK)\',\'Stokmarknes, Norwegen - Skagen Arpt (SKN)\',\'Stord, Norwegen - Stord Arpt (SRP)\',\'Stornoway, Grossbritannien - Stornoway Arpt (SYY)\',\'Storuman, Schweden - Gunnarn Arpt (SQO)\',\'Strahan, Australien - Strahan Arpt (SRN)\',\'Strassburg, Frankreich - Enzheim Arpt (SXB)\',\'Stronsay, Grossbritannien - Stronsay Arpt (SOY)\',\'Stuart, USA - Witham Field (SUA)\',\'Sturgeon Bay, USA - Door Country Arpt (SUE)\',\'Sturgis, USA - Kirsch Municipal (IRS)\',\'Stuttgart, Deutschland - Stuttgart (STR)\',\'Stuttgart, USA - Stuttgart Municipal (SGT)\',\'Subic Bay, Philippinen - Subic Bay Intl Arpt (SFS)\',\'Sucre, Bolivien - Sucre Arpt (SRE)\',\'Sudbury, Kanada - Sudbury Municipal (YSB)\',\'Sugar Land, USA - Hull Field Arpt (SGR)\',\'Sukhothai, Thailand - Sukhothai Arpt (THS)\',\'Sumare, Brasilien - Sumare Arpt (RWS)\',\'Sumpter, USA - Sumter Municipal Arpt (SUM)\',\'Sumy, Ukraine - Sumy Arpt (UMY)\',\'Sun City, Südafrika - Pilansberg Arpt (NTY)\',\'Sun Valley, USA - Friedman Memorial (SUN)\',\'Sunshine Coast, Australien - Maroochydore Arpt (MCY)\',\'Superior, USA - Richard I Bong Arpt (SUW)\',\'Surabaya, Indonesien - Juanda Arpt (SUB)\',\'Surathani, Thailand - Surat Thani Arpt (URT)\',\'Suva, Fidschi - Nausori Airport (SUV)\',\'Sveg, Schweden - Sveg Arpt (EVG)\',\'Svolvaer, Norwegen - Helle (SVJ)\',\'Swan Hill, Australien - Swan Hill Arpt (SWH)\',\'Swan River, Kanada - Swan River Municipal Arpt (ZJN)\',\'Swansea, Grossbritannien - Fairwood Comm (SWS)\',\'Swift Current, Kanada - Swift Current Arpt (YYN)\',\'Sydney, Australien - Au Rose Bay Arpt (RSE)\',\'Sydney, Australien - Palm Beach Arpt (LBH)\',\'Sydney, Australien - Sydney Kingsford Smith Arpt (SYD)\',\'Sydney, Australien - Useless Loop Arpt (USL)\',\'Sydney, Kanada - Sydney Airport (YQY)\',\'Syktyvkar, Russland - Syktyvkar Arpt (SCW)\',\'Sylhet, Bangladesh - Sylhet Osmany Arpt (ZYL)\',\'Syracuse, USA - Hancock Intl (SYR)\',\'Syros Island, Griechenland - Syros Island Arpt (JSY)\',\'Taba, Ägypten - Taba (TCP)\',\'Tabarka, Tunesien - Tabarka (TBJ)\',\'Tabatinga, Brasilien - Tabatinga Intl Arpt (TBT)\',\'Tabuk, Saudi Arabien - Tabuk Arpt (TUU)\',\'Tacloban, Philippinen - D Z Romualdez Arpt (TAC)\',\'Tacoma, USA - Tacoma Industrial Arpt (TIW)\',\'Taegu, Republik Korea - Taegu Arpt (TAE)\',\'Taichung, Taiwan, Republik China - Taichung Arpt (TXG)\',\'Taif, Saudi Arabien - Taif Airport (TIF)\',\'Tainan, Taiwan, Republik China - Tainan Arpt (TNN)\',\'Taipei, Taiwan, Republik China - Chiang Kai Shek Arpt (TPE)\',\'Taipei, Taiwan, Republik China - Sung Shan Arpt (TSA)\',\'Taitung, Taiwan, Republik China - Taitung Arpt (TTT)\',\'Taiyuan, China - Taiyuan Arpt (TYN)\',\'Takamatsu, Japan - Takamatsu Arpt (TAK)\',\'Tallahassee, USA - Tallahassee Municipal (TLH)\',\'Tallinn, Estland - Ulemiste Arpt (TLL)\',\'Taloyoak, Kanada - Taloyoak Arpt (YYH)\',\'Tamarindo, Costa Rica - Tamarindo Arpt (TNO)\',\'Tamatave, Madagaskar - Tamatave Arpt (TMM)\',\'Tambor, Costa Rica - Tambor Arpt (TMU)\',\'Tamky, Vietnam - Chulai Arpt (VCL)\',\'Tampa, USA - Peter O Knight Arpt (TPF)\',\'Tampa, USA - Tampa Intl (TPA)\',\'Tampere, Finnland - Tampere Pirkkala Arpt (TMP)\',\'Tampico, Mexiko - General F Javier Mina (TAM)\',\'Tamworth, Australien - Tamworth Arpt (TMW)\',\'Tanana, USA - Ralph Calhoun Arpt (TAL)\',\'Tandil, Argentinien - Tandil Arpt (TDL)\',\'Tanega Shima, Japan - Tanega Shima Arpt (TNE)\',\'Tanga, Tansania - Tanga Arpt (TGT)\',\'Tanger, Marokko - Boukhalef Arpt (TNG)\',\'Tanjung Pandan, Indonesien - Bulutumbang Arpt (TJQ)\',\'Tanna, Vanuatu - Tanna Arpt (TAH)\',\'Taos, USA - Taos Airport (TSM)\',\'Tapachula, Mexiko - Tapachula Arpt (TAP)\',\'Taranto, Italien - M A  Grottag Arpt (TAR)\',\'Tarbes / Lourdes, Frankreich - Tarbes Intl Arpt (LDE)\',\'Taree, Australien - Taree Arpt (TRO)\',\'Tari, Papua Neu Guinea - Tari Arpt (TIZ)\',\'Tarija, Bolivien - Tarija Arpt (TJA)\',\'Tashkent, Usbekistan - Vostohny (TAS)\',\'Tasiujaq, Kanada - Tasiujaq Arpt (YTQ)\',\'Tatry Poprad, Slovakei - Tatry Poprad (TAT)\',\'Taupo, Neuseeland - Taupo Arpt (TUO)\',\'Tauranga, Neuseeland - Tauranga Arpt (TRG)\',\'Taveuni, Fidschi - Matei Arpt (TVU)\',\'Tawau, Malaysia - Tawau Arpt (TWU)\',\'Te Anau, Neuseeland - Manapouri Airport (TEU)\',\'Teesside, Grossbritannien - Teesside Arpt (MME)\',\'Tefe, Brasilien - Tefe Arpt (TFF)\',\'Tegucigalpa, Honduras - Toncontin Arpt (TGU)\',\'Teheran, Iran - Imam Khomeini (IKA)\',\'Teheran, Iran - Mehrabad Arpt (THR)\',\'Tehuacan, Mexiko - Tehuacan Arpt (TCN)\',\'Tel Aviv Yafo, Israel - Ben Gurion Intl Arpt (TLV)\',\'Tel Aviv Yafo, Israel - Dov Airport (SDV)\',\'Telemaco Borba, Brasilien - Telemaco Borba Arpt (TEC)\',\'Telluride, USA - Telluride Municipal Arpt (TEX)\',\'Temple, USA - Temple Airport (TPL)\',\'Temuco, Chile - Manquehue Arpt (ZCO)\',\'Teneriffa, Spanien (TCI)\',\'Teneriffa, Spanien - Reina Sofia Arpt (TFS)\',\'Teneriffa, Spanien - Tenerife Norte Los Rodeos Arpt (TFN)\',\'Tennant Creek, Australien - Tennant Creek Arpt (TCA)\',\'Tepic, Mexiko - Tepic Arpt (TPQ)\',\'Terceira, Portugal - Lajes Arpt (TER)\',\'Teresina, Brasilien - Teresina Arpt (THE)\',\'Terrace Bay, Kanada - Terrace Bay Municipal Arpt (YTJ)\',\'Terrace, Kanada - Terrace Municipal (YXT)\',\'Terre Haute, USA - Hulman Field (HUF)\',\'Terrell, USA - Terrell Field Arpt (TRL)\',\'Tete A La Baleine, Kanada - Tete A La Baleine Arpt (ZTB)\',\'Teterboro, USA - Teterboro Arpt (TEB)\',\'Texarkana, USA - Texarkana Municipal (TXK)\',\'Thaba Nchu, Südafrika - Thaba Nchu Arpt (TCU)\',\'Thames, Neuseeland - Thames Arpt (TMZ)\',\'Thangool, Australien - Thangool Arpt (THG)\',\'Thargomindah, Australien - Thargomindah Arpt (XTG)\',\'The Dalles, USA - The Dalles Municipal Arpt (DLS)\',\'The Pas, Kanada - The Pas Municipal (YQD)\',\'Thermopolis, USA - Hot Springs (THP)\',\'Thessaloniki, Griechenland - Thessaloniki (SKG)\',\'Thief River Falls, USA - Thief River Falls Numicipal (TVF)\',\'Thira, Griechenland - Santorini Arpt (JTR)\',\'Thisted, Dänemark - Thisted Arpt (TED)\',\'Thompson, Kanada - Thompson Arpt (YTH)\',\'Thunder Bay, Kanada - Thunder Bay Arpt (YQT)\',\'Thursday Island, Australien - Thursday Island Arpt (TIS)\',\'Tianjin, China - Tianjin Airport (TSN)\',\'Tiflis / Tbilisi, Georgien - Novo Alexeyevka Arpt (TBS)\',\'Tifton, USA - Henry Tift Myers Arpt (TMA)\',\'Tijuana, Mexiko - Gen Abelardo Rodriguez (TIJ)\',\'Tikehau, Französisch-Polynesien - Tikehau Arpt (TIH)\',\'Timaru, Neuseeland - Timaru Arpt (TIU)\',\'Timika, Indonesien - Timika Arpt (TIM)\',\'Timisoara, Rumänien - Timisoara (TSR)\',\'Timmins, Kanada - Timmins Municipal Arpt (YTS)\',\'Tingwon, Papua Neu Guinea - Tingwon Arpt (TIG)\',\'Tioman, Malaysia - Tioman Arpt (TOD)\',\'Tirana, Albanien - Rinas Arpt (TIA)\',\'Tiree, Grossbritannien - Tiree Arpt (TRE)\',\'Tirgu Mures, Rumänien - Tirgu Mures Arpt (TGM)\',\'Tiruchirappali, Indien - Tiruchirapally Civil Arpt (TRZ)\',\'Tirupati, Indien - Tirupati Arpt (TIR)\',\'Titusville, USA - Space Center Executive Arpt (TIX)\',\'Tivat, Montenegro - Flughafen Tivat (TIV)\',\'Tobago, Trinidad & Tobago - Crown Point Arpt (TAB)\',\'Tobolsk, Russland - Tobolsk Arpt (TOX)\',\'Tocumwal, Australien - Tocumwal Arpt (TCW)\',\'Tofino, Kanada - Tofino Arpt (YAZ)\',\'Togiak, USA - Togiak Village Arpt (TOG)\',\'Tok Ak, USA - Tok Arpt (TKJ)\',\'Tokio, Japan (TYO)\',\'Tokio, Japan - Haneda Arpt (HND)\',\'Tokio, Japan - Narita (NRT)\',\'Tokunoshima, Japan - Tokunoshima Arpt (TKN)\',\'Tokushima, Japan - Tokushima Arpt (TKS)\',\'Toledo, Brasilien - Toledo Arpt (TOW)\',\'Toledo, USA - Toledo Express Arpt (TOL)\',\'Toluca, Mexiko - Morelos Arpt (TLC)\',\'Tom Price, Australien - Tom Price (TPR)\',\'Tomsk, Russland - Tomsk Arpt (TOF)\',\'Tongatapu, Tonga - Tongatapu Intl (TBU)\',\'Tonopah, USA - Tonopah Arpt (TPH)\',\'Toowoomba, Australien - Toowoomba Arpt (TWB)\',\'Topeka, USA - Forbes Field (FOE)\',\'Topeka, USA - Phillip Billard Arpt (TOP)\',\'Toronto, Kanada (YTO)\',\'Toronto, Kanada - Buttonville Arpt (YKZ)\',\'Toronto, Kanada - Downtown Hlpt Toronto (YBZ)\',\'Toronto, Kanada - Lester B Pearson Intl (YYZ)\',\'Toronto, Kanada - Toronto Island Arpt (YTZ)\',\'Torreon, Mexiko - Francisco Sarabia Arpt (TRC)\',\'Torrington, USA - Torrington Minicipal Arpt (TOR)\',\'Tortola, Jungferninseln, British Virgin Islands (TOV)\',\'Tortola, Jungferninseln, British Virgin Islands - Road Town Arpt (RAD)\',\'Tortoli, Italien - Arbatax Arpt (TTB)\',\'Tortuquero, Costa Rica - Tortuquero Arpt (TTQ)\',\'Tottori, Japan - Tottori Arpt (TTJ)\',\'Toulouse, Frankreich - Blagnac Arpt (TLS)\',\'Tours, Frankreich - Saint Symphorien Arpt (TUF)\',\'Townsville, Australien - Townsville Arpt (TSV)\',\'Toyama, Japan - Toyama Arpt (TOY)\',\'Tozeur, Tunesien - Tozeur (TOE)\',\'Trabzon, Türkei - Trabzon Arpt (TZX)\',\'Trang, Thailand - Trang Arpt (TST)\',\'Trapani, Italien - Birgi Arpt (TPS)\',\'Traralgon, Australien - Traralgon Arpt (TGN)\',\'Trat, Thailand - Trat Arpt (TDX)\',\'Traverse, USA - Cherry Capital Arpt (TVC)\',\'Treasure Cay, Bahamas - Treasure Cay Arpt (TCB)\',\'Trelew, Argentinien - Trelew Arpt (REL)\',\'Trenton, Kanada - Trenton Municipal Arpt (YTR)\',\'Trenton, USA - Mercer Cty (TTN)\',\'Tres Arroyos, Argentinien - Tres Arroyos Arpt (OYO)\',\'Treviso, Italien - Treviso Arpt (TSF)\',\'Tri-City, USA - Tri City Regional Arpt (TRI)\',\'Trieste, Italien - Ronchi Dei Legionari Arpt (TRS)\',\'Trinidad, Bolivien - Trinidad Arpt (TDD)\',\'Trinidad, Kuba - Trinidad CU Arpt (TND)\',\'Tripoli, Libyen (TIP)\',\'Trivandrum, Indien - Trivandrum Arpt (TRV)\',\'Trois Rivieres, Kanada - Three Rivers Arpt (YRQ)\',\'Trollhattan, Schweden - Trollhattan Arpt (THN)\',\'Trombetas, Brasilien - Trombetas Arpt (TMT)\',\'Tromso, Norwegen - Tromso Langnes Arpt (TOS)\',\'Trondheim, Norwegen - Trondheim Vaernes Arpt (TRD)\',\'Troutdale, USA - Troutdale Arpt (TTD)\',\'Trujillo, Peru - Trujillo Arpt (TRU)\',\'Tsushima, Japan - Tsushima Arpt (TSJ)\',\'Tububil, Papua Neu Guinea - Tabubil Arpt (TBG)\',\'Tucson, USA - Tucson Intl Arpt (TUS)\',\'Tucuman, Argentinien - Benjamin Matienzo Airport (TUC)\',\'Tucurui, Brasilien - Tucurui Arpt (TUR)\',\'Tulare, USA - Mefford Field (TLR)\',\'Tulear, Madagaskar - Tulear Arpt (TLE)\',\'Tulsa, USA - Tulsa Intl (TUL)\',\'Tulum, Mexiko - Tulum Arpt (TUY)\',\'Tumbes, Peru - Tumbes Arpt (TBP)\',\'Tunis, Tunesien - Carthage Arpt (TUN)\',\'Tunxi, China - Tunxi Arpt (TXN)\',\'Tupelo, USA - C D Lemons Municipal (TUP)\',\'Turaif, Saudi Arabien - Turaif Arpt (TUI)\',\'Turbat, Pakistan - Turbat Arpt (TUK)\',\'Turin, Italien - Casselle Arpt (TRN)\',\'Turkmanbashi, Turkmenistan - Turkmanbashi Arpt (KRW)\',\'Turkmenabad, Turkmenistan - Turkmenabad Arpt (CRZ)\',\'Turku, Finnland - Turku Arpt (TKU)\',\'Turtle Island, Fidschi - Turtle Island (TTL)\',\'Tuscaloosa, USA - Van De Graff Arpt (TCL)\',\'Tuxtla Gutierrez, Mexiko - Llano San Juan Arpt (TGZ)\',\'Tuy Hoa, Vietnam - Tuy Hoa Arpt (TBB)\',\'Tuzla, Bosnien - Tuzla Intl Arpt (TZL)\',\'Twin Falls, USA - Sun Valley Regional (TWF)\',\'Twin Hills, USA - Twin Hills Arpt (TWA)\',\'Tyler, USA - Pounds Field (TYR)\',\'Tyumen, Russland - Tyumen Arpt (TJM)\',\'Tzaneen, Südafrika - Letaba Aprt (LTA)\',\'Ube Jp, Japan - Ube Airport (UBJ)\',\'Uberaba, Brasilien - Uberaba Airport (UBA)\',\'Uberlandia, Brasilien - Eduardo Gomes Airprt (UDI)\',\'Ubon Ratchathani, Thailand - Muang Ubon Arpt (UBP)\',\'Udaipur, Indien - Dabok Airport (UDR)\',\'Udine, Italien - Campoformido Arpt (UDN)\',\'Udon Thani, Thailand - Udon Thani Arpt (UTH)\',\'Ufa RU, Russland - Ufa Arpt (UFA)\',\'Ujung Pandang, Indonesien - Hasanudin Arpt (UPG)\',\'Ukiah, USA - Ukiah Arpt (UKI)\',\'Ulan Ude, Russland - Ulan Ude Arpt (UUD)\',\'Ulan-Bator, Mongolei - Chinggis Khaan Int Airport (ULN)\',\'Ulsan, Republik Korea - Ulsan Arpt (USN)\',\'Umea, Schweden - Umea Airport (UME)\',\'Umiujaq, Kanada - Umiujaq Arpt (YUD)\',\'Umtata, Südafrika - K D Matamzima Arpt (UTT)\',\'Umuarama, Brasilien - Ernesto Geisel Arpt (UMU)\',\'Una BR, Brasilien - Una Airport (UNA)\',\'Unalakleet, USA - Unalakleet Arpt (UNK)\',\'University Oxford, USA - University Oxford (UOX)\',\'Unst, Grossbritannien - Baltasound Arpt (UNT)\',\'Upington, Südafrika - Upington Municipal Arpt (UTN)\',\'Uralsk, Kasachstan - Uralsk (URA)\',\'Uruapan, Mexiko - Uruapan Arpt (UPN)\',\'Uruguaina, Brasilien - Ruben Berta Arpt (URG)\',\'Urumqi, China - Urumqi Arpt (URC)\',\'Ushuaia, Argentinien - Ushuaia Arpt (USH)\',\'Ust Kamenogorsk, Kasachstan - Ust Kamenogorsk Arpt (UKK)\',\'Utapao, Thailand - Utapao Airport (UTP)\',\'Utica, USA - Oneida County Arpt (UCA)\',\'Vaasa, Finnland - Vaasa Arpt (VAA)\',\'Vadodara, Indien - Vadodara Arpt (BDQ)\',\'Vadso, Norwegen - Vadso (VDS)\',\'Vail / Eagle, USA - Eagle County Arpt (EGE)\',\'Vail, USA - Avon Stolport (WHR)\',\'Val D Or, Kanada - Val d Or Municipal Arpt (YVO)\',\'Valdez, USA - Valdez Municipal Arpt (VDZ)\',\'Valdivia, Chile - Pichoy (ZAL)\',\'Valdosta, USA - Valdosta Regional (VLD)\',\'Valence, Frankreich - Cahbeuil Airport (VAF)\',\'Valencia, Spanien - Valencia (VLC)\',\'Valencia, Venezuela - Valenica Arpt (VLN)\',\'Valera, Venezuela - Carvajal Arpt (VLV)\',\'Valladolid, Spanien - Valladolid Arpt (VLL)\',\'Vallejo, USA - Stolport Arpt (VLO)\',\'Vallemi, Paraguay - Inc Arpt (VMI)\',\'Valparaiso, Chile - Valparaiso (VAP)\',\'Valparaiso, USA - Porter County (VPZ)\',\'Valverde, Spanien - Hierro Arpt (VDE)\',\'Van Horn, USA - Culberson Cty Arpt (VHN)\',\'Vancouver, Kanada - Coal Harbor Sea Plane Arpt (CXH)\',\'Vancouver, Kanada - Vancouver Intl Arpt (YVR)\',\'Vanimo, Papua Neu Guinea - Vanimo Arpt (VAI)\',\'Vannes, Frankreich - Muecon Arpt (VNE)\',\'Varadero, Kuba - Juan Gualberto Gomez Arpt (VRA)\',\'Varanasi, Indien - Babatpur Airport (VNS)\',\'Vardoe, Norwegen - Vardoe Luftan (VAW)\',\'Varginha, Brasilien - Maj Brig Trompowsky Arpt (VAG)\',\'Varkaus, Finnland - Varkaus (VRK)\',\'Varna, Bulgarien - Varna (VAR)\',\'Vasteras, Schweden - Hasslo Airport (VST)\',\'Vaxjo, Schweden - Vaxjo Airport (VXO)\',\'Vejle, Dänemark - Vejle Arpt (VEJ)\',\'Venedig, Italien - Venedig (VCE)\',\'Vera Cruz, Mexiko - Las Bajadas General Heriberto Jara (VER)\',\'Vermilion, Kanada - Vermilion Arpt (YVG)\',\'Vernal, USA - Vernal Municipal (VEL)\',\'Vernon, Kanada - Vernon Municipal Arpt (YVE)\',\'Vero Beach, USA - Vero Beach Minicipal (VRB)\',\'Verona, Italien - Verona Airport (VRN)\',\'Vestmannaeyjar, Island - Vestmannaeyjar Arpt (VEY)\',\'Vicenza, Italien - Vicenza Arpt (VIC)\',\'Vichy, Frankreich - Charmeil Arpt (VHY)\',\'Vicksburg, USA - Vicksburg Arpt (VKS)\',\'Victoria Falls, Simbabwe - Victoria Falls Arpt (VFA)\',\'Victoria, Kanada - Inner Harbor Sea Plane Arpt (YWH)\',\'Victoria, Kanada - Victoria Intl Arpt (YYJ)\',\'Victoria, USA - Victoria Regional (VCT)\',\'Victorville, USA - George AFB (VCV)\',\'Vidalia, USA - Vidalia Municipal Arpt (VDI)\',\'Vientiane, Laos - Wattay Arpt (VTE)\',\'Vieste, Italien - Vieste Arpt (VIF)\',\'Vigo, Spanien - Vigo Airport (VGO)\',\'Vila Real, Portugal - Vila Real Arpt (VRL)\',\'Vilhelmina, Schweden - Vilhelmina Arpt (VHM)\',\'Vilhena, Brasilien - Vilhena Arpt (BVH)\',\'Villa Constitucion, Mexiko - Villa Constitucion Arpt (VIB)\',\'Villa Gesell, Argentinien - Villa Gesell Arpt (VLG)\',\'Villa Mercedes, Argentinien - Villa Mercedes Arpt (VME)\',\'Villahermosa, Mexiko - Capt Carlos Rovirosa Perez (VSA)\',\'Vilnius, Litauen - Vilnius Arpt (VNO)\',\'Vina Del Mar, Chile - Vina Del Mar Arpt (KNA)\',\'Vincennes, USA - Oneal Arpt (OEA)\',\'Vinh City, Vietnam - Vinh City Arpt (VII)\',\'Vinnitsa, Ukraine - Vinnitsa Arpt (VIN)\',\'Virgin Gorda, Jungferninseln, British Virgin Islands - Virgin Gorda Arpt (VIJ)\',\'Visalia, USA - Visalia Municipal (VIS)\',\'Visby, Schweden - Visby Airport (VBY)\',\'Vishakhapatanam, Indien - Vishakhapatnam (VTZ)\',\'Vitebsk, Weißrussland - Vitebsk Arpt (VTB)\',\'Vitoria Da Conquista, Brasilien - Vitoria Da Conquista Arpt (VDC)\',\'Vitoria, Brasilien - Eurico Sales Arpt (VIX)\',\'Vitoria, Spanien - Vitoria Arpt (VIT)\',\'Vladivostok, Russland - Vladivostok Arpt (VVO)\',\'Vojens, Dänemark - Shrydstrup Airport (SKS)\',\'Volgograd, Russland - Volgograd (VOG)\',\'Vologda, Russland - Vologda Arpt (VGD)\',\'Volos, Griechenland - Nea Anchialos Arpt (VOL)\',\'Vryheid, Südafrika - Vryheid Arpt (VYD)\',\'Wabush, Kanada - Wabush Municipal Arpt (YWK)\',\'Waco, USA - Madison Cooper Arpt (ACT)\',\'Wagga Wagga, Australien - Forest Hill Arpt (WGA)\',\'Wakkanai, Japan - Hokkaido Arpt (WKJ)\',\'Walgett, Australien - Walgett Arpt (WGE)\',\'Walla Walla, USA - Walla Walla City County (ALW)\',\'Walterboro, USA - Walterboro Municipal Arpt (RBW)\',\'Walvis Bay, Namibia - Rooikop Arpt (WVB)\',\'Wanaka, Neuseeland - Wanaka Arpt (WKA)\',\'Wanganui, Neuseeland - Wanganui Arpt (WAG)\',\'Wangaratta, Australien - Wangaratta (WGT)\',\'Wanxian, China - Wanxian Arpt (WXN)\',\'Wapakoneta, USA - Neil Armstrong Arpt (AXV)\',\'Warrnambool, Australien - Warrnambool Arpt (WMB)\',\'Warschau, Polen - Okecie Arpt (WAW)\',\'Warwick, Australien - Warwick Arpt (WAZ)\',\'Washington, USA (WAS)\',\'Washington, USA - USN Heliport (NDV)\',\'Washington, USA - Washington Dulles Intl (IAD)\',\'Washington, USA - Washington Natl Arpt (DCA)\',\'Waskaganish, Kanada - Waskaganish Arpt (YKQ)\',\'Waterford, Irland - Waterford Arpt (WAT)\',\'Waterloo, USA - Livingston Betsworth Fld (ALO)\',\'Watertown, USA - Watertown Arpt (ART)\',\'Watertown, USA - Watertown Municipal (ATY)\',\'Waterville, USA - Robert La Fleur Arpt (WVL)\',\'Watson Lake, Kanada - Watson Lake Arpt (YQH)\',\'Watsonville, USA - Watsonville Municipal Arpt (WVI)\',\'Waukegan, USA - Memorial Arpt (UGN)\',\'Wausau, USA - Central Wisconsin Arpt (CWA)\',\'Wausau, USA - Wausau Municipal Arpt (AUW)\',\'Wawa, Kanada - Wawa Municipal Arpt (YXZ)\',\'Waycross, USA - Ware County (AYS)\',\'Weatherford, USA - Parker County Airport (WEA)\',\'Wee Waa, Australien - Wee Waa Airport (WEW)\',\'Weeze, Deutschland - Airport Weeze (NRN)\',\'Weihai, China - Weihai Arpu (WEH)\',\'Weipa, Australien - Weipa Arpt (WEI)\',\'Welkom, Südafrika - Welkom Arpt (WEL)\',\'Wellington, Neuseeland - Wellington Intl (WLG)\',\'Welshpool, Australien - Welshpool Arpt (WHL)\',\'Wenatchee, USA - Pangborn Memorial Fld (EAT)\',\'Wenzhou, China - Wenzhou Arpt (WNZ)\',\'West Bend, USA - West Bend Arpt (ETB)\',\'West Palm Beach, USA - Palm Beach County Arpt (LNA)\',\'West Palm Beach, USA - Palm Beach Intl Arpt (PBI)\',\'West Yellowstone, USA - West Yellowstone Arpt (WYS)\',\'Westerland / Sylt, Deutschland - Westerland / Sylt (GWT)\',\'Westerly, USA - Westerly Municipal (WST)\',\'Westport, Neuseeland - Westport Airport (WSZ)\',\'Westray, Grossbritannien - Westray Arpt (WRY)\',\'Wewak, Papua Neu Guinea - Boram Arpt (WWK)\',\'Wexford, Irland - Castlebridge Arpt (WEX)\',\'Whakatane, Neuseeland - Whakatane Arpt (WHK)\',\'Whale Cove, Kanada - Whale Cove Arpt (YXN)\',\'Whangarei, Neuseeland - Whangarei Arpt (WRE)\',\'Whistler, Kanada - Whistler Arpt (YWS)\',\'White Plains, USA - Westchester Cty Arpt (HPN)\',\'Whitehorse, Kanada - Whitehorse Arpt (YXY)\',\'Whyalla, Australien - Whyalla Arpt (WYA)\',\'Wichita Falls, USA - Wichita Falls Municipal (SPS)\',\'Wichita, USA - Mid Continent Arpt (ICT)\',\'Wick, Grossbritannien - Wick Arpt (WIC)\',\'Wien, Österreich - Wien (VIE)\',\'Williams Lake, Kanada - Williams Lake Municipal (YWL)\',\'Williamsport, USA - Williamsport Lycoming Municipal (IPT)\',\'Williston, USA - Sloulin Field Intl Arpt (ISN)\',\'Wilmington, USA - Greater Wilmington New Castle (ILG)\',\'Wilmington, USA - New Hanover Cty Arpt (ILM)\',\'Winchester, USA - Winchester Arpt (WGO)\',\'Windhoek, Namibia - Eros Arpt (ERS)\',\'Windhoek, Namibia - Windhoek Intl Arpt (WDH)\',\'Windorah, Australien - Windorah Arpt (WNR)\',\'Windsor, Kanada - Windsor Intl Arpt (YQG)\',\'Winfield, USA - Arkansas City Arpt (WLD)\',\'Winnemucca, USA - Winnemucca Municipal Arpt (WMC)\',\'Winnipeg, Kanada - Winnipeg Intl Arpt (YWG)\',\'Winslow, USA - Winslow Municipal (INW)\',\'Winston-Salem, USA - Smith Reynolds Arpt (INT)\',\'Winter Haven, USA - Gilbert Fld (GIF)\',\'Wiscasset, USA - Wiscasset Arpt (ISS)\',\'Wollongong, Australien - Wollongong Arpt (WOL)\',\'Woodward, USA - West Woodward Arpt (WWR)\',\'Worcester, USA - Worcester Arpt (ORH)\',\'Worland, USA - Worland Municipal (WRL)\',\'Worthington, USA - Worthington Arpt (OTG)\',\'Wrangell, USA - Wrangell Seaplane Base (WRG)\',\'Wroclaw, Polen - Strachowice (WRO)\',\'Wuhan, China - Wuhan Arpt (WUH)\',\'Wuyishan, China - Wuyishan Arpt (WUS)\',\'Wyndham, Australien - Wyndham Arpt (WYN)\',\'Xi An, China - Xianyang Arpt (XIY)\',\'Xi An, China - Xiguan Airport (SIA)\',\'Xiamen, China - Xiamen Intl Airport (XMN)\',\'Xiangfan, China - Xiangfan Arpt (XFN)\',\'Yakima, USA - Yakima Terminal Arpt (YKM)\',\'Yakutat, USA - Yakutat Arpt (YAK)\',\'Yam Island, Australien - Yam Island Arpt (XMY)\',\'Yamagata, Japan - Yamagata Airport (GAJ)\',\'Yanbo, Saudi Arabien - Yanbo Arpt (YNB)\',\'Yandicoogina, Australien - Yandi Arpt (YNN)\',\'Yanji, China - Yanji Arpt (YNJ)\',\'Yankton, USA - Chan Gurney Municipal (YKN)\',\'Yantai, China - Laishan Arpt (YNT)\',\'Yarmouth, Kanada - Yarmouth Municipal Arpt (YQI)\',\'Yaroslavl, Russland - Yaroslavl Arpt (IAR)\',\'Yazd, Iran - Yazd Arpt (AZD)\',\'Yellowknife, Kanada - Yellowknife Arpt (YZF)\',\'Yeosu, Republik Korea - Yeosu Arpt (RSU)\',\'Yichang, China - Yichang Arpt (YIH)\',\'Yiwu, China - Yiwu Arpt (YIW)\',\'Ylivieska, Finnland - Ylivieska Arpt (YLI)\',\'Yogyakarta, Indonesien - Adisutjipto Arpt (JOG)\',\'Yonago, Japan - Miho Arpt (YGJ)\',\'York, USA - York Arpt (THV)\',\'Yorkton, Kanada - Yorkton Airport (YQV)\',\'Yotvata, Israel - Yotvata Arpt (YOT)\',\'Young, Australien - Young Arpt (NGA)\',\'Youngstown, USA - Youngstown Municipal (YNG)\',\'Yuma, USA - Yuma Intl (YUM)\',\'Yuzhno Sakhalinsk, Russland - Yuzhno Sakhalinsk Arpt (UUS)\',\'Zacatecas, Mexiko - Zacatecas Airport (ZCL)\',\'Zadar, Kroatien - Zadar Arpt (ZAD)\',\'Zagreb, Kroatien - Zagreb Arpt (ZAG)\',\'Zakynthos, Griechenland - Zakinthos Arpt (ZTH)\',\'Zanesville, USA - Zanesville Arpt (ZZV)\',\'Zanjan, Iran - Zanjan Arpt (JWN)\',\'Zaporozhe, Ukraine - Zaporozhye Arpt (OZH)\',\'Zaragoza, Spanien - Zaragoza Airport (ZAZ)\',\'Zhangjiang, China - Zhanjiang Airport (ZHA)\',\'Zhengzhou, China - Zhengzhou Arpt (CGO)\',\'Zhuhai, China - Zhuhai Arpt (ZUH)\',\'Zielona, Polen - Babimost Arpt (IEG)\',\'Zürich, Schweiz - Zürich (ZRH)\',\'Zweibrücken, Deutschland - Zweibrücken (ZQW)\'], {choices:3000,frequency:0.1, fullSearch:true, partialChars:0, ignoreCase:true, partialSearch:true, minChars:3})');
document.write('                </scr'+'ipt>');
document.write('            </td>');
document.write('            <td width="42" class="al">');
document.write('                <span class="searchH">Zur&uuml;ck</span>');
document.write('            </td>');
document.write('            <td width="73" class="al">');
document.write('                <input style="width:63px;" type="text" class="felem" id="return_date" name="return_date" value="12.08.2010">');
document.write('            </td>');
document.write('            <td width="95" class="al">');
document.write('                <img src="http://www.lturfly.com/lturfly/images/shim.gif" border="0" width="95" height="25" usemap="#searchNow">');
document.write('            </td>');
document.write('        </tr>');
document.write('    </table>');
document.write('</div>');
document.write('</form>');
}
