//
// AceCodeEditor
//
var AceCodeEditor = Control.subclass({
    className: "AceCodeEditor"
});
AceCodeEditor.prototype.extend({
    
    content: function( content ) {
        var editor = this._editor();
        if ( content === undefined ) {
            return editor
                ? editor.getSession().getValue()
                : this._content();
        } else {
            if ( editor ) {
                editor.getSession().setValue( content );
            } else {
                this._content( content );
            }
            return this;
        }
    },
    
    initialize: function() {
        this.inDocument( function( $control ) {
            var content = $control.content();
            var id = $control.prop( "id" );
            var editor = ace.edit( id );
            $control._editor( editor );
            var session = editor.getSession();
            session.setUseSoftTabs( true );
            editor.renderer.setShowGutter( false );
            editor.renderer.setHScrollBarAlwaysVisible( false );
            var JavaScriptMode = require( "ace/mode/javascript" ).Mode;
            session.setMode( new JavaScriptMode() );
            $control.content( content );
        });
    },
    
    // Copy of the content, used to save content until editor is ready.
    _content: Control.property(),
    
    _editor: Control.property()
});

//
// AddThis
//
var AddThis = Control.subclass({
    className: "AddThis",
    content: " <div class=\"addthis_toolbox addthis_default_style\">\n    <a href=\"http://www.addthis.com/bookmark.php?v=250&amp;pub=janmiksovsky\" class=\"addthis_button_compact\">Share</a>\n    <span class=\"addthis_separator\">|</span>\n    <a class=\"addthis_button_twitter\"></a>\n    <a class=\"addthis_button_facebook\"></a>\n    <a class=\"addthis_button_email\"></a>\n    <a class=\"addthis_button_favorites\"></a>\n    <a class=\"addthis_button_print\"></a>\n    </div> "
});
var addthis_share = {
    content: "Hello, world!",
    templates: {
        twitter: "QuickUI creates modular jQuery controls that can be used like new HTML tags {{url}}"
    },
    title: "QuickUI",
    url: "http://quickui.org"
};

//
// BlogModule
//
var BlogModule = Control.subclass({
    className: "BlogModule",
    content: [
        " ",
        {
            control: "Blog",
            apiKey: "ABQIAAAAduw93ooM51B8Jdy2C9HxvhSBC_FVBxnf9EUyrmx06S6ZVKWCwhRUIdI-JHlMvEGhOu9DbYTG8OA89Q",
            count: "5",
            feed: "http://blog.quickui.org/feed/"
        },
        " "
    ]
});

//
// CatalogNavigationLinks
//
var CatalogNavigationLinks = Control.subclass({
    className: "CatalogNavigationLinks",
    content: [
        " ",
        {
            control: "Link",
            href: "/catalog/",
            content: "Index"
        },
        " ",
        {
            control: "Link",
            href: "/catalog/usingCatalog.html",
            content: "How to use the catalog"
        },
        " ",
        {
            control: "List",
            id: "listControls",
            itemClass: "CatalogLink"
        },
        " "
    ]
});
CatalogNavigationLinks.prototype.extend({
    initialize: function() {
        this.$listControls()
            .mapFunction( function( controlRecord ) {
                this.content( controlRecord.name )
            })
            .items( controlRecords );
    }
});

//
// CodeEditor
//
var CodeEditor = Control.subclass({
    className: "CodeEditor",
    content: [
        " ",
        {
            html: "<div />",
            id: "runner",
            content: [
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                " ",
                                {
                                    html: "<span class=\"label\">Edit JavaScript here</span>",
                                    id: "CodeEditor_heading"
                                },
                                " "
                            ]
                        },
                        " ",
                        {
                            html: "<div class=\"label\" />",
                            content: [
                                " ",
                                {
                                    control: "SiteButton",
                                    id: "buttonRun",
                                    content: "▶ Run"
                                },
                                " "
                            ]
                        },
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            id: "codePane",
                            content: [
                                " ",
                                {
                                    html: "<div />",
                                    id: "CodeEditor_code"
                                },
                                " "
                            ]
                        },
                        " ",
                        {
                            html: "<div />",
                            id: "result"
                        },
                        " "
                    ]
                },
                " "
            ]
        },
        " ",
        {
            html: "<div />",
            id: "CodeEditor_error"
        },
        " "
    ]
});
CodeEditor.prototype.extend({
    
    // True if code should be run whenever it changes.
    autoRun: Control.property.bool( null, true ),
    
    code: Control.chain( "$CodeEditor_code", "content", function() {
        if ( this.inDocument() && this.autoRun() ) {
            this.run();
        } else {
            this.$result().content( "(Click Run to see result.)" );
        }
    }),
    
    error: Control.chain( "$CodeEditor_error", "content" ),
    
    heading: Control.chain( "$CodeEditor_heading", "content" ),
    
    initialize: function() {
        
        var self = this;
        this.$buttonRun().click( function() {
            self.run();
        });
        
        this
            .keydown( function( event ) {
                self._keydown( event );
            })
            .inDocument( function() {
                if ( this.autoRun() ) {
                    this.run();
                }
                this.$CodeEditor_code().focus();
            });
         
        /* As of 1/27/2012, ACE doesn't run in IE8. */
        if ( $.browser.msie && parseInt( $.browser.version ) < 9 ) {
            this.$CodeEditor.code().content(
                "(Open this page in a newer version of Internet Explorer to see a live demo.)"
            );
            this.autoRun( false );
        } else {
            this.$CodeEditor_code().control( AceCodeEditor );
        }
    },
    
    result: Control.chain( "$result", "content" ),
    
    run: function() {
        
        this.error( null );
        
        var $demo = $( "<div id='demo'/>" );
        this.$result().html( $demo );
        var code = this.code();
        try {
            eval( code );
        }
        catch ( error ) {
            console.log( "Error: " + error.toString() );
            this.error( error.toString() );
        }
    },
    
    _insertTextAtCursor: function( text ) {
        var $editor = this.$CodeEditor_code();
        var position = $editor.cursorPosition();
        var content = $editor.content();
        content = content.substr( 0, position ) + text + content.slice( position );
        $editor
            .content( content )
            .cursorPosition( position + text.length );
    },
    
    _keydown: function( event ) {
        if ( event.which === 13 && event.ctrlKey ) {
            this.run();
            event.stopPropagation( true );
            event.preventDefault();
            return false;
        } else if ( event.which === 9 ) {
            event.stopPropagation();
            event.preventDefault();
            this._insertTextAtCursor( "    " );
            return false;
        }
    }
    
});

// Set/get the position of the cursor in an element (namely, an input box or text area).
// TODO: Fold into CodeEditor.
jQuery.fn.cursorPosition = function( position ) {
    if ( position === undefined ) {
        var position = 0;
        var element = $(this).get(0);
        if ( !element ) {
            position = -1;
        } else if ( document.selection ) {
            element.focus();
            var selection = document.selection.createRange();
            var length = selection.text.length;
            selection.moveStart( "character" , -element.value.length) ;
            position = selection.text.length - length;
        } else if ( element.selectionStart ) {
            // Firefox
            position = element.selectionStart;
        }
        return position;
    } else {
        return this.each(function(index, element) {
            if ( element.createTextRange ) {
                var range = element.createTextRange();
                range.move( "character", position );
                range.select();
            } else if ( element.setSelectionRange ) {
                // Firefox
                element.focus();
                element.setSelectionRange( position, position );
            }
        });
    }
};

//
// CodeOutput
//
var CodeOutput = Control.subclass({
    className: "CodeOutput",
    content: [
        " ",
        {
            html: "<div />",
            id: "CodeOutput_content"
        },
        " "
    ]
});
CodeOutput.prototype.extend({
    content: Control.chain("$CodeOutput_content", "content")
})

//
// ControlClassHierarchy
//
var ControlClassHierarchy = Control.subclass({
    className: "ControlClassHierarchy",
    content: [
        " ",
        {
            control: "List",
            id: "classList",
            itemClass: "CatalogLink"
        },
        " "
    ]
});
ControlClassHierarchy.prototype.extend({
    
    controlClass: Control.property[ "class" ]( function( controlClass ) {
        var classes = controlClass.classHierarchy.split( " " );
        this.$classList().items( classes );
    })

});

//
// DemoTile
//
var DemoTile = Control.subclass({
    className: "DemoTile",
    content: [
        " ",
        {
            html: "<div />",
            id: "classNameContainer",
            content: [
                " ",
                {
                    control: "CatalogLink",
                    id: "className"
                },
                " "
            ]
        },
        " ",
        {
            html: "<p />",
            id: "description"
        },
        " ",
        {
            html: "<div />",
            id: "demoContainer",
            content: [
                " ",
                {
                    html: "<div />",
                    id: "demo"
                },
                " "
            ]
        },
        " "
    ]
});
DemoTile.prototype.extend({

    controlRecord: Control.property( function( controlRecord ) {
        this.$className().content( controlRecord.name );
        var demoClass = controlRecord.demoClass != null
            ? controlRecord.demoClass
            : controlRecord.name;
        if ( demoClass ) {
            this.$demo().transmute( demoClass );
        }
        this.$description().content( controlRecord.description );
    })

});

//
// FileContents
//
var FileContents = Control.subclass({
    className: "FileContents",
    tag: "pre"});
FileContents.prototype.extend({
    
    content: Control.chain( "text" ),

    /*
     * Path of the file whose contents should be shown. 
     */
    path: Control.property( function( path ) {
        var self = this;
        $.get( path )
            .success( function( data) {
                self.content( data );
            });
    })
    
});

//
// GoogleAnalytics
//
var GoogleAnalytics = Control.subclass({
    className: "GoogleAnalytics"
});
GoogleAnalytics.prototype.extend({
    
    // The Google Analytics profile ID
    profileId: Control.property(),
    
    initialize: function() {
        
        // Begin Google Analytics snippet.
        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', this.profileId()]);
        _gaq.push(['_trackPageview']);
        
        (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
        })();
        // End Google Analytics snippet.
        
    }
});

//
// Link
//
var Link = Control.subclass({
    className: "Link",
    tag: "a"});
Link.prototype.extend({
    
    href: Control.chain( "prop/href" ),
    target: Control.chain( "prop/target" ),
    
    initialize: function() {
        if ( this.href() === "" )
        {
            // Use a placeholder href so the browser will use a hand cursor.
            this.href( "javascript:" );
        }
    }
});

//
// Logo
//
var Logo = Control.subclass({
    className: "Logo",
    content: [
        " ",
        {
            control: "Link",
            href: "/",
            id: "logotype",
            content: " <span class=\"bracket\">&lt;</span>QuickUI<span class=\"bracket\">&gt;</span> "
        },
        " ",
        {
            html: "<div>Web control framework</div>",
            id: "tagline"
        },
        " "
    ]
});

//
// NavigationBar
//
var NavigationBar = Control.subclass({
    className: "NavigationBar",
    content: [
        " ",
        {
            control: "Link",
            href: "/",
            content: "Home"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial",
            content: "Tutorial"
        },
        " ",
        {
            control: "Link",
            href: "/docs",
            content: "Docs"
        },
        " ",
        {
            control: "Link",
            href: "/catalog",
            content: "Catalog"
        },
        " ",
        {
            control: "Link",
            href: "/markup/",
            content: "Markup"
        },
        " ",
        {
            control: "Link",
            href: "http://blog.quickui.org",
            content: "Blog"
        },
        " ",
        {
            control: "Link",
            href: "http://discussions.zoho.com/quickui",
            content: "Discuss"
        },
        " ",
        {
            control: "Link",
            href: "https://github.com/JanMiksovsky/quickui",
            content: "Contribute"
        },
        " "
    ]
});
NavigationBar.prototype.extend({

    highlightCurrentArea: function() {
        // Highlight the link for the area we're in.
        var area = this.page() && this.page().area();
        if (area != null) {
            this.find(".Link").eachControl(function() {
                this.toggleClass("highlight", this.content() === area);
            });
        }
    }
    
});

//
// NavigationLinks
//
var NavigationLinks = Control.subclass({
    className: "NavigationLinks"
});
NavigationLinks.prototype.extend({

    // Highlight the link for the page we're on.
    highlightCurrentPage: function() {
        var pageHref = window.location.href;
        this.find( ".Link" ).eachControl( function( index, $control ) {
            var linkHref = $control.href();
            var pageHrefRight = pageHref.substring( pageHref.length - linkHref.length )
            $control.toggleClass( "highlight", pageHrefRight === linkHref );
        });
    }
    
});

//
// Popout
//
var Popout = Control.subclass({
    className: "Popout"
});
Popout.prototype.extend({
    initialize: function() {
        var self = this;
        this.hover(
            function hoverIn() { self.addClass("hovered"); },
            function hoverOut() { self.removeClass("hovered");  }
        )
    }
});

//
// ScreencastLink
//
var ScreencastLink = Control.subclass({
    className: "ScreencastLink",
    content: [
        " ",
        {
            html: "<img src=\"/resources/play.png\" />",
            id: "iconPlay"
        },
        " ",
        {
            control: "Link",
            id: "ScreencastLink_content"
        },
        " "
    ]
});
ScreencastLink.prototype.extend({
    
    content: Control.chain("$ScreencastLink_content", "content"),
    href: Control.chain("$ScreencastLink_content", "href"),
    
    initialize: function() {
        var self = this;
        this.$iconPlay().click(function() {
            self.$ScreencastLink_content().trigger("click");
        });
    }
});

//
// SiteButton
//
var SiteButton = BasicButton.subclass({
    className: "SiteButton"
});

//
// SitePage
//
var SitePage = Page.subclass({
    className: "SitePage",
    content: [
        " ",
        {
            control: "GoogleAnalytics",
            profileId: "UA-11520232-1"
        },
        " ",
        {
            html: "<div />",
            id: "tableMain",
            content: [
                " ",
                {
                    html: "<div />",
                    id: "topRow",
                    content: [
                        " ",
                        {
                            control: "Logo",
                            id: "logo"
                        },
                        " ",
                        {
                            control: "NavigationBar",
                            id: "navigationBar"
                        },
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            id: "leftNavigation",
                            content: [
                                " ",
                                "<h1 />",
                                " ",
                                {
                                    control: "NavigationLinks",
                                    id: "SitePage_navigationLinks"
                                },
                                " ",
                                {
                                    html: "<div />",
                                    id: "SitePage_sidebar"
                                },
                                " "
                            ]
                        },
                        " ",
                        {
                            html: "<div />",
                            id: "pageCanvas",
                            content: [
                                " ",
                                {
                                    html: "<h1 />",
                                    id: "SitePage_title"
                                },
                                " ",
                                {
                                    html: "<div />",
                                    id: "SitePage_content"
                                },
                                " "
                            ]
                        },
                        " "
                    ]
                },
                " "
            ]
        },
        " "
    ]
});
SitePage.prototype.extend({
    
    content: Control.chain("$SitePage_content", "content"),
    navigationLinks: Control.chain("$SitePage_navigationLinks", "content"),
    sidebar: Control.chain("$SitePage_sidebar", "content"),
    
    initialize: function() {
        
        this._super();
        this.$SitePage_navigationLinks().highlightCurrentPage();
        
        if ( this.$SitePage_title().content().length === 0
            && this.title().length > 0 ) {
            // Extract default page heading from dehydrated document title.
            this.title( this.title() );
        }
    },
    
    area: Control.property( function( area ) {
        this.$navigationBar().highlightCurrentArea();
    }),
    
    title: function(value) {
        if (value === undefined)
        {
            return this._super();
        } else {
            this.$SitePage_title().content( value );
            return this._super( value + " - QuickUI" );
        }
    }
    
});

//
// SourceCode
//
var SourceCode = Control.subclass({
    className: "SourceCode",
    tag: "pre"});
SourceCode.prototype.extend({
    
    // TODO: Remove this complexity once Highlight.js can handle working
    // against a pre element not in the DOM.
    _needsRefresh: Control.property.bool(),
    
    initialize: function() {
        this._super();
        this
            .genericIfClassIs( SourceCode )
            .addClass( "language-html" )
            .inDocument( function( $control ) {
                if ( $control._needsRefresh() ) {
                    $control._refresh();
                    $control._needsRefresh( false );
                }
            });
    },
    
    content: Control.property( function ( content ) {
        if ( this.inDocument() ) {
            this._refresh();
        } else {
            this._needsRefresh( true );
        }
    }),
    
    _refresh: function() {
        
        // To simplify the use of this control with CDATA elements,
        // which add extra space unless the CDATA and its contents are
        // jammed against the opening SourceCode tag, we trim whitespace
        // at the beginning and end of the contents.
        var text = $.trim( this.content() ); 
            
        // Remove carriage returns so IE8 doesn't render extra lines.
        text = text.replace( /\r/g, "" );

        // Using $.text() escapes the HTML/XML in the content.
        this
            .empty()
            .text( text );
        
        // Colorize code with highlight.js if installed
        if ( window.hljs ) {
            // HACK: disable highlighting in IE8, which does weird things
            // with formatted XML tags, until this can be resolved. 
            if ( !$.browser.msie || parseInt( $.browser.version ) >= 9 ) {
                this.each( function( index, element ) {
                    hljs.highlightBlock( element );
                });
            }
        }
    }
    
})

//
// SourceFileContents
//
var SourceFileContents = Control.subclass({
    className: "SourceFileContents",
    content: [
        " ",
        {
            control: "SourceCode",
            id: "SourceFileContents_content"
        },
        " ",
        {
            html: "<div />",
            id: "linkContainer",
            content: [
                " ",
                {
                    html: "<a />",
                    id: "link",
                    content: [
                        "→ ",
                        {
                            html: "<span />",
                            id: "linkText"
                        }
                    ]
                },
                " "
            ]
        },
        " "
    ]
});
SourceFileContents.prototype.extend({
    
    content: Control.chain( "$SourceFileContents_content", "content" ),
    
    path: Control.property( function( path ) {

        // Load the file's contents.
        var self = this;
        $.get( path )
            .success( function( data) {
                self.content( data );
            });

        // Show the path to the file.
        if ( path !== undefined ) {
            this.$link().attr( "href", path );
            var pathNames = path ? path.split( "/" ) : null;
            var fileName = ( pathNames && pathNames.length > 0 )
                ? pathNames[ pathNames.length - 1 ]
                : null;
            this.$linkText().html( fileName );
        }
        
    })
    
});

//
// Tag
//
var Tag = Control.subclass({
    className: "Tag",
    tag: "span",
    content: [
        "&lt;",
        {
            html: "<span />",
            id: "Tag_content"
        },
        ">"
    ]
});
Tag.prototype.extend({
    content: Control.chain("$Tag_content", "content")
});

//
// Text
//
var Text = Control.subclass({
    className: "Text"
});
Text.prototype.extend({
    
    _spacesForTab: Control.property(),
        
    content: Control.property( function( content ) {
        
        // Map line breaks to break tags, special characters to entities,
        // tabs to spaces;
        var html = content
            .replace( /&/g, "&amp;" )   // Ampersands before other entities
            .replace( /</g, "&lt;" )
            .replace( />/g, "&gt;" )
            .replace( /\n/g, "<br/>" );
        
        var spacesForTab = this._spacesForTab();
        if ( spacesForTab ) {
            html = html.replace( /\t/g, spacesForTab );
        }
            
        // Convert runs of remaining whitespace to non-breaking spaces.
        var regex = /\s\s+/g;
        var match = regex.exec( html );
        while ( match !== null ) {
            var whitespace = match[0];
            var length = whitespace.length;
            var index = match.index;
            var nonBreakingSpaces = Array( length + 1 ).join( "&nbsp;" );
            html = html.slice( 0, index ) + nonBreakingSpaces
                + html.slice( index + length );
            match = regex.exec( html );
        }
        
        this.html( html );
    }),
    
    /*
     * If set, tabs in the file will be replaced this this many non-breaking
     * spaces.
     */
    tabToSpacesCount: Control.property.integer( function( count ) {
        var spaces = count
            ? Array( count + 1 ).join( "&nbsp;" )    // a run of <count> spaces
            : null;
        this._spacesForTab( spaces );
    })    
});

//
// TutorialPage
//
var TutorialPage = SitePage.subclass({
    className: "TutorialPage",
    area: "Tutorial",
    navigationLinks: [
        " ",
        {
            control: "Link",
            href: "/tutorial/",
            content: "Introduction"
        },
        " ",
        "<h2>Using controls</h2>",
        " ",
        {
            control: "Link",
            href: "/tutorial/context-independent.html",
            content: "Context independence"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/defined-by-classes.html",
            content: "Control classes"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/controls-are-composable.html",
            content: "Controls are composable"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/inherit-from-jQuery.html",
            content: "Inheriting from jQuery"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/content.html",
            content: "Control content"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/properties.html",
            content: "Control properties"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/casting.html",
            content: "Casting jQuery objects"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/controls-from-elements.html",
            content: "Using existing elements"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/css-classes.html",
            content: "CSS class names"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/manipulating-arrays.html",
            content: "Control arrays"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/event-handlers.html",
            content: "Handling events"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/meta-controls.html",
            content: "Meta-controls"
        },
        " ",
        "<h2>Creating control classes</h2>",
        " ",
        {
            control: "Link",
            href: "/tutorial/creating-control-class.html",
            content: "Creating a new class"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/json-content.html",
            content: "Setting default content"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/extending-control-prototype.html",
            content: "Adding functionality"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/element-reference-functions.html",
            content: "Referencing elements"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/defining-properties.html",
            content: "Exposing properties"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/handling-content.html",
            content: "Properties handling content"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/control-chain-helper.html",
            content: "Concise property definition"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/subclassing-other-classes.html",
            content: "Subclassing other classes"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/overriding-content-property.html",
            content: "Custom content properties"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/initialize.html",
            content: "Initialization"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/control-property-helper.html",
            content: "Property storage"
        },
        " ",
        "<h2>Advanced topics</h2>",
        " ",
        {
            control: "Link",
            href: "/tutorial/jQuery-UI.html",
            content: "QuickUI + jQuery UI"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/rehydration.html",
            content: "Controls in static HTML"
        },
        " ",
        {
            control: "Link",
            href: "/tutorial/inDocument.html",
            content: "Waiting to be in the DOM"
        },
        " ",
        "<h2>Conclusion</h2>",
        " ",
        {
            control: "Link",
            href: "/tutorial/using-QuickUI.html",
            content: "QuickUI in your projects"
        },
        " "
    ],
    content: [
        " ",
        " ",
        {
            html: "<div />",
            id: "TutorialPage_content"
        },
        " ",
        {
            control: "CodeEditor",
            id: "editor"
        },
        " ",
        {
            control: "SiteButton",
            id: "buttonNext",
            content: "Next »"
        },
        " "
    ]
});
TutorialPage.prototype.extend({
    
    content: Control.chain( "$TutorialPage_content", "content" ),
    
    initialize: function() {
        
        this._super();
        
        var self = this;
        this.$buttonNext().click( function() {
            var nextPage = self.nextPage();
            if ( nextPage ) {
                window.location = nextPage;
            }
        });
        
        this.$editor().code( this._demo() );
    },
    
    nextPage: Control.property( function( nextPage) {
        this.$buttonNext().css( "display", nextPage ? "inline-block": "none" );
    }),
    
    editorVisible: Control.chain( "$editor", "visibility" ),
    
    // Return the code from the page's script tag.
    _demo: function() {
        var code = $.trim( $( "script#demo" ).html() );
        if ( code.length > 0 ) {
            // Remove the first and last lines: the demo function wrapper.
            lines = code.split( "\n" );
            lines = lines.slice( 1, lines.length - 2 );
            code = $.trim( lines.join( "\n" ) );
        }
        return code;
    }

});

//
// VersionedFileLink
//
var VersionedFileLink = Link.subclass({
    className: "VersionedFileLink"
});
VersionedFileLink.prototype.extend({
    
    file: Control.property( function( file ) {
        var fileInfo = quickUIVersion[ file ];
        this.content( fileInfo.fileName );
        var releaseUrl = "/release/";
        var url = releaseUrl + fileInfo.fileName;
        this.href( url );
    })
    
});

//
// YouTubeVideo
//
var YouTubeVideo = Control.subclass({
    className: "YouTubeVideo",
    content: [
        " ",
        {
            html: "<iframe title=\"YouTube video player\" width=\"640\" height=\"390\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\" />",
            id: "iframe"
        },
        " "
    ]
});
YouTubeVideo.prototype.extend({
    videoId: Control.property(function(videoId) {
        var url = "http://www.youtube.com/embed/" + videoId;
        this.$iframe().attr("src", url);
    })
});

//
// CatalogIndexListPage
//
var CatalogIndexListPage = SitePage.subclass({
    className: "CatalogIndexListPage",
    title: "QuickUI Catalog",
    area: "Catalog",
    navigationLinks: [
        " ",
        {
            control: "CatalogNavigationLinks"
        },
        " "
    ],
    content: [
        " ",
        " ",
        "<p>\n    The QuickUI Catalog shows live examples of QuickUI controls, many\n    designed to be ready-to-use base classes for new controls.\n    (Note: Many controls depend on other controls, either for base classes,\n    or as contained elements within a given control. Because QuickUI does\n    not yet offer a dependency-management, for now it's necessary to download\n    all dependencies by hand; automating that process is a task on the QuickUI\n    roadmap.)\n    </p>",
        " ",
        {
            html: "<p />",
            content: [
                " For information on quickly trying out these controls or building them from the open source, see ",
                {
                    control: "Link",
                    href: "usingCatalog.html",
                    content: "How to use the catalog"
                },
                ". "
            ]
        },
        " ",
        {
            html: "<div />",
            id: "table",
            content: [
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "AutoSizeTextBox"
                                }
                            ]
                        },
                        " ",
                        "<div>A text area that expands to contain its text.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "BrowserSpecific"
                                }
                            ]
                        },
                        " ",
                        "<div>Conditionally shows contents for specific browsers.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "BasicButton"
                                }
                            ]
                        },
                        " ",
                        "<div>Base class for buttons which handles tracking of button states.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "ColorSwatch"
                                }
                            ]
                        },
                        " ",
                        "<div>Shows a block of a CSS color.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "ColorSwatchButton"
                                }
                            ]
                        },
                        " ",
                        "<div>A button showing a color swatch.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "ColorSwatchComboBox"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                Demonstration of a ListComboBox subclass with a custom text box\n                and custom list presentation.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "ColorSwatchTextBox"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                Lets the user type a CSS color value, and renders the typed\n                value as a color swatch.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "ComboBox"
                                }
                            ]
                        },
                        " ",
                        "<div>Base class for a combo box: a text input area with a dropdown set of choices.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "DeviceSpecific"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                Conditionally loads different content, control class, or styles\n                depending on the type of device.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "Dialog"
                                }
                            ]
                        },
                        " ",
                        "<div>Base class for modal dialogs.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "Fader"
                                }
                            ]
                        },
                        " ",
                        "<div>Fades out content on the right or bottom instead of clipping it.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "CatalogPage"
                                }
                            ]
                        },
                        " ",
                        "<div>The template for all pages in this QuickUI Catalog.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "Gradient"
                                }
                            ]
                        },
                        " ",
                        "<div>A browser-agnostic gradient representation.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "HasPopup"
                                }
                            ]
                        },
                        " ",
                        "<div>A control that has an associated popup that will appear above or below the control.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "HintTextBox"
                                }
                            ]
                        },
                        " ",
                        "<div>A text box that displays a hint (instructions) when the text box is empty.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "HorizontalPanels"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                A layout control that arranges left and/or right side panels.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "List"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                An abstract control that represents each element of a JavaScript\n                array as a QuickUI control.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "ListComboBox"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                A combo box that presents its choices as a list.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "LoremIpsum"
                                }
                            ]
                        },
                        " ",
                        "<div>Generates placeholder text.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "Page"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                Base class for creating top-level pages.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "Popup"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                Base class for popups, menus, dialogs — things that temporarily appear over other things.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "RotatingPagesWithDots"
                                }
                            ]
                        },
                        " ",
                        "<div>Rotates once through a sequence of horizontally-arranged pages, and also allows navigation to an individual page.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "SampleSpriteButton"
                                }
                            ]
                        },
                        " ",
                        "<div>An example of creating a sprite button through subclassing.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "SearchBox"
                                }
                            ]
                        },
                        " ",
                        "<div>A typical web search box.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "SlidingPages"
                                }
                            ]
                        },
                        " ",
                        "<div>Arranges its children as page on a horizontally sliding strip; only one child can be seen at a time.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "SlidingPagesWithDots"
                                }
                            ]
                        },
                        " ",
                        "<div>Lets the user navigate a horizontally sliding strip of pages</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "Sprite"
                                }
                            ]
                        },
                        " ",
                        "<div>A basic CSS sprite.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "SpriteButton"
                                }
                            ]
                        },
                        " ",
                        "<div>A button that uses a sprite for its background.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "Switch"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                Something like a JavaScript switch statement, this shows exactly\n                one child at any given time (e.g., to reflect an UI mode).\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "Tag"
                                }
                            ]
                        },
                        " ",
                        "<div>A simple HTML macro that includes both content and styling.</div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "TextBoxWithButton"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                A control with a text box and an associated button, where clicking\n                the button does something with the text box's content.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "TextCondenser"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                Switches to a condensed font when necessary to squeeze in more text.\n            </div>",
                        " "
                    ]
                },
                " ",
                {
                    html: "<div />",
                    content: [
                        " ",
                        {
                            html: "<div />",
                            content: [
                                {
                                    control: "CatalogLink",
                                    content: "VerticalPanels"
                                }
                            ]
                        },
                        " ",
                        "<div>\n                A layout control that arranges top and/or bottom panels.\n            </div>",
                        " "
                    ]
                },
                " "
            ]
        },
        " "
    ]
});

//
// CatalogIndexPage
//
var CatalogIndexPage = SitePage.subclass({
    className: "CatalogIndexPage",
    title: "QuickUI Catalog",
    area: "Catalog",
    navigationLinks: [
        " ",
        {
            control: "CatalogNavigationLinks"
        },
        " "
    ],
    content: [
        " ",
        " ",
        {
            html: "<p />",
            id: "intro",
            content: [
                " These are open, ready-to-use controls, including base classes and samples. ",
                {
                    control: "Link",
                    href: "usingCatalog.html",
                    content: "How to use these"
                },
                " "
            ]
        },
        " ",
        {
            control: "List",
            id: "tileList",
            itemClass: "DemoTile",
            mapFunction: "controlRecord"
        },
        " "
    ]
});
CatalogIndexPage.prototype.extend({
    controlRecords: Control.chain( "$tileList", "items" )
});

//
// CatalogLink
//
var CatalogLink = Link.subclass({
    className: "CatalogLink"
});
CatalogLink.prototype.extend({
    content: function( content ) {
        if ( content !== undefined ) {
            this.href( href="/catalog/" + content + "/" );
        }
        return this._super( content );
    }
});

//
// CatalogPage
//
var CatalogPage = SitePage.subclass({
    className: "CatalogPage",
    area: "Catalog",
    navigationLinks: [
        " ",
        {
            control: "CatalogNavigationLinks"
        },
        " "
    ],
    content: [
        " ",
        {
            html: "<div />",
            id: "CatalogPage_summary"
        },
        " ",
        "<h2>Live demo</h2>",
        " ",
        {
            html: "<div />",
            id: "CatalogPage_demo"
        },
        " ",
        {
            html: "<div />",
            id: "sampleMarkup",
            content: [
                " ",
                "<h2>Sample QuickUI markup to instantiate this control</h2>",
                " ",
                {
                    control: "SourceCode",
                    id: "sampleCodeMarkup"
                },
                " "
            ]
        },
        " ",
        {
            html: "<div />",
            id: "demoMarkup",
            content: [
                " ",
                "<h2>QuickUI Markup for the demo above</h2>",
                " ",
                {
                    control: "SourceFileContents",
                    id: "demoFileMarkup"
                },
                " "
            ]
        },
        " ",
        {
            html: "<div />",
            id: "sampleJavaScript",
            content: [
                " ",
                "<h2>Sample JavaScript to instantiate this control</h2>",
                " ",
                {
                    control: "SourceCode",
                    id: "sampleCodeJavaScript"
                },
                " "
            ]
        },
        " ",
        {
            html: "<div />",
            id: "demoJavaScript",
            content: [
                " ",
                "<h2>JavaScript for the demo above</h2>",
                " ",
                {
                    control: "SourceFileContents",
                    id: "demoFileJavaScript"
                },
                " "
            ]
        },
        " ",
        "<h2>Class hierarchy</h2>",
        " ",
        {
            control: "ControlClassHierarchy",
            id: "controlClassHierarchy"
        },
        " ",
        {
            html: "<div />",
            id: "sectionContent",
            content: [
                " ",
                "<h2>Notes</h2>",
                " ",
                {
                    html: "<div />",
                    id: "CatalogPage_content"
                },
                " "
            ]
        },
        " ",
        {
            html: "<p />",
            content: [
                " View the ",
                {
                    control: "Link",
                    id: "linkSourceCodeControl"
                },
                " on GitHub. "
            ]
        },
        " "
    ]
});
CatalogPage.prototype.extend({
    
    autoFocus: Control.property.bool( null, true ),
    demo: Control.chain( "$CatalogPage_demo", "content" ),
    summary: Control.chain( "$CatalogPage_summary", "content" ),
    
    initialize: function() {
        this._super();
        this.inDocument( function( $control ) {
            if ( $control.autoFocus() ) {
                // Give the input to first text box or text area in the demo. 
                $control.$CatalogPage_demo()
                    .find( "input[type='text']" )
                    .add( "textarea" )
                    .eq(0)
                    .focus();
            }
        });
    },
    
    content: Control.chain( "$CatalogPage_content", "content", function( content ) {
        this.$sectionContent().toggle( content != null );
    }),

    demoClass: Control.property[ "class" ]( function( demoClass ) {
         this.$CatalogPage_demo().transmute( demoClass );
    }),

    // Demo in markup hides stock "instantiate this control" markup.
    demoFileMarkup: Control.chain( "$demoFileMarkup", "path",
       function( demoFileMarkup ) {
           this.$sampleMarkup().toggle( demoFileMarkup == null );
           this.$demoMarkup().toggle( demoFileMarkup != null );
       }
    ),

    // Demo in JavaScript hides stock "instantiate this control" JavaScript.
    demoFileJavaScript: Control.chain( "$demoFileJavaScript", "path",
       function( demoFileJavaScript ) {
           this.$sampleJavaScript().toggle( demoFileJavaScript == null );
           this.$demoJavaScript().toggle( demoFileJavaScript != null );
       }
    ),
    
    title: function( title ) {
        var result = this._super( title );
        if ( title !== undefined ) {
            
            // Grab control class name from title, use it to populate
            // the fields with standard values.
            var className = title;
            
            if ( !this.demo() || this.demo().length === 0 ) {
                // As a default demo, instantiate the control.
                this.$CatalogPage_demo().transmute( className );
            }
            
            this.$sampleCodeMarkup().content(
                "<" + className + "/>"
            );
            this.$sampleCodeJavaScript().content(
                className + ".create();"
            );
            
            this.$controlClassHierarchy().controlClass( className );

            var sourceUrlTemplate = "https://github.com/JanMiksovsky/quickui-catalog/blob/master/quickui.catalog/{0}.qui";
            var sourceUrl = sourceUrlTemplate.replace( /\{0\}/g, className );
            var sourceLinkText = "full source for " + className;
            this.$linkSourceCodeControl()
                .text( sourceLinkText )
                .href( sourceUrl );
        }
        return result;
    }
    
});

//
// CatalogPage2
//
var CatalogPage2 = SitePage.subclass({
    className: "CatalogPage2",
    area: "Catalog",
    navigationLinks: [
        " ",
        {
            control: "CatalogNavigationLinks"
        },
        " "
    ],
    content: [
        " ",
        {
            html: "<p />",
            id: "CatalogPage2_summary"
        },
        " ",
        {
            control: "CodeEditor",
            id: "editor",
            heading: "Live demo"
        },
        " ",
        "<h2>Class hierarchy</h2>",
        " ",
        {
            control: "ControlClassHierarchy",
            id: "controlClassHierarchy"
        },
        " ",
        {
            html: "<div />",
            id: "sectionContent",
            content: [
                " ",
                "<h2>Notes</h2>",
                " ",
                {
                    html: "<div />",
                    id: "CatalogPage2_content"
                },
                " "
            ]
        },
        " ",
        {
            html: "<p />",
            content: [
                " View the ",
                {
                    control: "Link",
                    id: "linkSourceCodeControl"
                },
                " on GitHub. "
            ]
        },
        " "
    ]
});
CatalogPage2.prototype.extend({
    
    autoFocus: Control.property.bool( null, true ),
    
    autoRun: Control.chain( "$editor", "autoRun" ),
    
    summary: Control.chain( "$CatalogPage2_summary", "content" ),
    
    initialize: function() {
        this._super();
        this.$editor().code( this._demo() );
    },
    
    content: Control.chain( "$CatalogPage2_content", "content", function( content ) {
        this.$sectionContent().toggle( content != null );
    }),

    demoClass: Control.property[ "class" ]( function( demoClass ) {
         this.$CatalogPage2_demo().transmute( demoClass );
    }),

    title: function( title ) {
        var result = this._super( title );
        if ( title !== undefined ) {
            
            // Grab control class name from title, use it to populate
            // the fields with standard values.
            var className = title;
            
            /*
            if ( !this.demo() || this.demo().length === 0 ) {
                // As a default demo, instantiate the control.
                this.$CatalogPage2_demo().transmute( className );
            }
            */
           
            this.$controlClassHierarchy().controlClass( className );

            var sourceUrlTemplate = "https://github.com/JanMiksovsky/quickui-catalog/blob/master/quickui.catalog/{0}.qui";
            var sourceUrl = sourceUrlTemplate.replace( /\{0\}/g, className );
            var sourceLinkText = "full source for " + className;
            this.$linkSourceCodeControl()
                .text( sourceLinkText )
                .href( sourceUrl );
        }
        return result;
    },
    
    // Return the code from the page's script tag.
    _demo: function() {
        var code = $.trim( $( "script#demo" ).html() );
        if ( code.length > 0 ) {
            // Remove the first and last lines: the demo function wrapper.
            lines = code.split( "\n" );
            lines = lines.slice( 1, lines.length - 2 );
            code = $.trim( lines.join( "\n" ) );
        }
        return code;
    }    
});

//
// MarkupAreaPage
//
var MarkupAreaPage = SitePage.subclass({
    className: "MarkupAreaPage",
    area: "Markup",
    navigationLinks: [
        " ",
        {
            control: "Link",
            href: "/markup/",
            content: "Introduction"
        },
        " ",
        "<h2>Markup tools</h2>",
        " ",
        {
            control: "Link",
            href: "/downloads/",
            content: "Download"
        },
        " ",
        "<h2>Markup tutorial</h2>",
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section01/",
            content: "Hello, world"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section02/",
            content: "How QuickUI works"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section03/",
            content: "Composing controls"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section04/",
            content: "Referencing control elements"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section05/",
            content: "Defining control properties"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section06/",
            content: "Setting control properties"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section07/",
            content: "Property bindings"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section08/",
            content: "Markup within properties"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section09/",
            content: "Control content"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section10/",
            content: "Styling controls"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section11/",
            content: "More on styling"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section12/",
            content: "Defining interactivity"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section13/",
            content: "Controlling behavior"
        },
        " ",
        {
            control: "Link",
            href: "/markup/tutorial/section14/",
            content: "Subclassing controls"
        },
        " "
    ]
});


