8   var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
 
   9   this.Class = function(){};
 
  10   Class.extend = function(prop) {
 
  11     var _super = this.prototype;
 
  13     var prototype = new this();
 
  15     for (var name in prop) {
 
  16       prototype[name] = typeof prop[name] == "function" &&
 
  17         typeof _super[name] == "function" && fnTest.test(prop[name]) ?
 
  20             var tmp = this._super;
 
  21             this._super = _super[name];
 
  22             var ret = fn.apply(this, arguments);       
 
  26         })(name, prop[name]) :
 
  30       if ( !initializing && this.init )
 
  31         this.init.apply(this, arguments);
 
  33     Class.prototype = prototype;
 
  34     Class.constructor = Class;
 
  35     Class.extend = arguments.callee;   
 
  42   this.render_template = function render_template(str, data){
 
  43     // Figure out if we're getting a template, or if we need to
 
  44     // load the template - and be sure to cache the result.
 
  45     var fn = !/^[\d\s-_]/.test(str) ?
 
  46       cache[str] = cache[str] ||
 
  47         render_template(document.getElementById(str).innerHTML) :
 
  49       // Generate a reusable function that will serve as a template
 
  50       // generator (and which will be cached).
 
  52         "var p=[],print=function(){p.push.apply(p,arguments);};" +
 
  54         // Introduce the data as local variables using with(){}
 
  55         "with(obj){p.push('" +
 
  57         // Convert the template into pure JavaScript
 
  59           .replace(/[\r\t\n]/g, " ")
 
  60           .split("<%").join("\t")
 
  61           .replace(/((^|%>)[^\t]*)'/g, "$1\r")
 
  62           .replace(/\t=(.*?)%>/g, "',$1,'")
 
  63           .split("\t").join("');")
 
  64           .split("%>").join("p.push('")
 
  65           .split("\r").join("\\'")
 
  66       + "');}return p.join('');");
 
  68       // Provide some basic currying to the user
 
  69     return data ? fn( data ) : fn;
 
  74   var slice = Array.prototype.slice;
 
  76   function update(array, args) {
 
  77     var arrayLength = array.length, length = args.length;
 
  78     while (length--) array[arrayLength + length] = args[length];
 
  82   function merge(array, args) {
 
  83     array = slice.call(array, 0);
 
  84     return update(array, args);
 
  87   Function.prototype.bind = function(context) {
 
  88     if (arguments.length < 2 && typeof arguments[0] === 'undefined') {
 
  92     var args = slice.call(arguments, 1);
 
  94       var a = merge(args, arguments);
 
  95       return __method.apply(context, a);
 
 103 var documentsUrl = '/api/documents/';
 
 106 var Model = Class.extend({
 
 111   signal: function(event, data) {
 
 112     console.log('signal', this, event, data);
 
 113     if (this.observers[event]) {
 
 114       for (var i=0; i < this.observers[event].length; i++) {
 
 115         this.observers[event][i].handle(event, data);
 
 121   addObserver: function(observer, event) {
 
 122     if (!this.observers[event]) {
 
 123       this.observers[event] = [];
 
 125     this.observers[event].push(observer);
 
 129   removeObserver: function(observer, event) {
 
 131       for (e in this.observers) {
 
 132         this.removeObserver(observer, e);
 
 135       for (var i=0; i < this.observers[event].length; i++) {
 
 136         if (this.observers[event][i] === observer) {
 
 137           this.observers[event].splice(i, 1);
 
 145 var DocumentModel = Model.extend({
 
 146   data: null, // name, text_url, latest_rev, latest_shared_rev, parts_url, dc_url, size
 
 152   getData: function(callback) {
 
 153     console.log('get:', documentsUrl + fileId);
 
 156       url: documentsUrl + fileId,
 
 158       success: this.successfulGetData.bind(this, callback)
 
 162   successfulGetData: function(callback, data) {
 
 164     this.signal('changed');
 
 166       (callback.bind(this))(data);
 
 170   getXML: function(callback) {
 
 171     this.signal('xml-freeze');
 
 173       this.getData(this.getXML);
 
 175       console.log('getXML:', this.data.text_url);
 
 178         url: this.data.text_url,
 
 180         success: this.successfulGetXML.bind(this, callback)
 
 185   successfulGetXML: function(callback, data) {
 
 186     if (data != this.xml) {
 
 188       this.signal('changed');
 
 189       this.signal('xml-changed');
 
 191     this.signal('xml-unfreeze');
 
 195 var leftPanelView, rightPanelContainer, doc;
 
 198   doc = new DocumentModel();
 
 199   var splitView = new SplitView('#splitview', doc);
 
 200   leftPanelView = new PanelContainerView('#left-panel-container', doc);
 
 201   rightPanelContainer = new PanelContainerView('#right-panel-container', doc);