From e717f40f118a2617e65aaa9bb7c0f9b9987e3821 Mon Sep 17 00:00:00 2001 From: Joseph Hager Date: Tue, 31 Mar 2015 16:44:57 -0400 Subject: [PATCH] Initial port to gitbook --- .gitignore | 1 + Guardfile | 25 - LANGS.md | 1 + README.md | 32 +- book.json | 13 + en/SUMMARY.md | 17 + en/advanced-topics/bro.md | 699 ++++++++++++++ en/advanced-topics/commandline.md | 88 ++ en/advanced-topics/compilation.md | 23 + en/advanced-topics/introduction.md | 3 + .../advanced-topics/nightlies.md | 60 +- en/advanced-topics/ramdisks.md | 15 + en/configuration.md | 611 +++++++++++++ en/getting-started/eclipse.md | 93 ++ en/getting-started/gradle.md | 5 + en/getting-started/intellij.md | 5 + en/getting-started/introduction.md | 17 + en/getting-started/maven.md | 3 + en/getting-started/structure.md | 121 +++ .../images/eclipse-create-project.png | Bin .../images/eclipse-debug-sim.png | Bin .../images/eclipse-demo-app.png | Bin .../asciidoc => en}/images/eclipse-deploy.png | Bin .../images/eclipse-install-new-software.png | Bin .../eclipse-install-new-software@2x.png | Bin .../images/eclipse-ios-project-wizard.png | Bin .../images/eclipse-marketplace.png | Bin .../images/eclipse-project-wizard.png | Bin .../images/eclipse-project.png | Bin .../images/eclipse-run-debug.png | Bin .../images/eclipse-unit-test.png | Bin .../images/license-manager.png | Bin {src/main/asciidoc => en}/images/logo.png | Bin .../main/asciidoc => en}/images/simulator.png | Bin .../images/using-ram-disks-unmount.png | Bin en/introduction.md | 40 + en/samples.md | 5 + pom.xml | 48 - src/main/asciidoc/advanced-bro.adoc | 865 ------------------ .../asciidoc/advanced-command-line-usage.adoc | 133 --- src/main/asciidoc/advanced-topics.adoc | 12 - .../asciidoc/advanced-under-the-hood.adoc | 74 -- .../asciidoc/advanced-using-ram-disks.adoc | 27 - .../asciidoc/configuration-reference.adoc | 680 -------------- .../asciidoc/getting-started-eclipse.adoc | 151 --- src/main/asciidoc/getting-started-gradle.adoc | 5 - src/main/asciidoc/getting-started-idea.adoc | 5 - src/main/asciidoc/getting-started-maven.adoc | 3 - src/main/asciidoc/getting-started.adoc | 183 ---- src/main/asciidoc/index.adoc | 48 - src/main/asciidoc/introduction.adoc | 63 -- src/main/asciidoc/samples.adoc | 12 - stylesheets/foundation.css | 670 -------------- theme/assets/app.js | 1 + .../assets/fonts/fontawesome/FontAwesome.otf | Bin 0 -> 75188 bytes .../fonts/fontawesome/fontawesome-webfont.eot | Bin 0 -> 72449 bytes .../fonts/fontawesome/fontawesome-webfont.svg | 504 ++++++++++ .../fonts/fontawesome/fontawesome-webfont.ttf | Bin 0 -> 141564 bytes .../fontawesome/fontawesome-webfont.woff | Bin 0 -> 83760 bytes theme/assets/fonts/merriweather/250.woff | Bin 0 -> 54988 bytes theme/assets/fonts/merriweather/250i.woff | Bin 0 -> 42416 bytes theme/assets/fonts/merriweather/400.woff | Bin 0 -> 51268 bytes theme/assets/fonts/merriweather/400i.woff | Bin 0 -> 41140 bytes theme/assets/fonts/merriweather/700.woff | Bin 0 -> 55768 bytes theme/assets/fonts/merriweather/700i.woff | Bin 0 -> 61848 bytes theme/assets/fonts/merriweather/900.woff | Bin 0 -> 54064 bytes theme/assets/fonts/merriweather/900i.woff | Bin 0 -> 40696 bytes theme/assets/fonts/opensans/300.woff | Bin 0 -> 69392 bytes theme/assets/fonts/opensans/300i.woff | Bin 0 -> 65124 bytes theme/assets/fonts/opensans/400.woff | Bin 0 -> 67524 bytes theme/assets/fonts/opensans/400i.woff | Bin 0 -> 65184 bytes theme/assets/fonts/opensans/600.woff | Bin 0 -> 69884 bytes theme/assets/fonts/opensans/600i.woff | Bin 0 -> 65888 bytes theme/assets/fonts/opensans/700.woff | Bin 0 -> 70188 bytes theme/assets/fonts/opensans/700i.woff | Bin 0 -> 65060 bytes .../apple-touch-icon-precomposed-152.png | Bin 0 -> 92815 bytes theme/assets/images/favicon.ico | Bin 0 -> 4286 bytes theme/assets/print.css | 1 + theme/assets/style.css | 1 + theme/i18n/ar.json | 21 + theme/i18n/bn.json | 20 + theme/i18n/de.json | 20 + theme/i18n/en.json | 20 + theme/i18n/es.json | 20 + theme/i18n/fa.json | 21 + theme/i18n/fr.json | 20 + theme/i18n/it.json | 20 + theme/i18n/no.json | 20 + theme/i18n/pl.json | 20 + theme/i18n/pt.json | 20 + theme/i18n/ru.json | 20 + theme/i18n/zh-cn.json | 20 + theme/i18n/zh-tw.json | 20 + theme/javascript/core/events.js | 7 + theme/javascript/core/font-settings.js | 103 +++ theme/javascript/core/keyboard.js | 38 + theme/javascript/core/loading.js | 16 + theme/javascript/core/navigation.js | 150 +++ theme/javascript/core/progress.js | 73 ++ theme/javascript/core/search.js | 114 +++ theme/javascript/core/sidebar.js | 56 ++ theme/javascript/core/state.js | 18 + theme/javascript/gitbook.js | 49 + theme/javascript/utils/dropdown.js | 27 + theme/javascript/utils/platform.js | 5 + theme/javascript/utils/sharing.js | 36 + theme/javascript/utils/storage.js | 31 + theme/javascript/utils/url.js | 33 + theme/stylesheets/base/markdown.less | 388 ++++++++ theme/stylesheets/base/normalize.less | 396 ++++++++ theme/stylesheets/base/preboot.less | 406 ++++++++ theme/stylesheets/ebook.less | 44 + theme/stylesheets/ebook/highlight.less | 90 ++ theme/stylesheets/ebook/variables.less | 1 + theme/stylesheets/mixins.less | 20 + theme/stylesheets/website.less | 47 + theme/stylesheets/website/alerts.less | 31 + theme/stylesheets/website/body.less | 146 +++ theme/stylesheets/website/buttons.less | 32 + theme/stylesheets/website/dropdown.less | 159 ++++ theme/stylesheets/website/font-settings.less | 15 + theme/stylesheets/website/fonts.less | 96 ++ theme/stylesheets/website/glossary.less | 22 + theme/stylesheets/website/header.less | 120 +++ .../stylesheets/website/highlight/night.less | 92 ++ .../stylesheets/website/highlight/sepia.less | 107 +++ .../stylesheets/website/highlight/white.less | 90 ++ theme/stylesheets/website/languages.less | 51 ++ theme/stylesheets/website/markdown.less | 138 +++ theme/stylesheets/website/navigation.less | 68 ++ theme/stylesheets/website/summary.less | 242 +++++ theme/stylesheets/website/variables.less | 242 +++++ theme/templates/ebook/glossary.html | 21 + theme/templates/ebook/layout.html | 24 + theme/templates/ebook/page.html | 31 + theme/templates/ebook/summary.html | 38 + theme/templates/website/glossary.html | 17 + .../website/includes/font-settings.html | 22 + theme/templates/website/includes/header.html | 53 ++ theme/templates/website/includes/summary.html | 55 ++ theme/templates/website/langs.html | 25 + theme/templates/website/layout.html | 31 + theme/templates/website/page.html | 76 ++ 143 files changed, 6789 insertions(+), 3048 deletions(-) delete mode 100644 Guardfile create mode 100644 LANGS.md create mode 100644 book.json create mode 100644 en/SUMMARY.md create mode 100644 en/advanced-topics/bro.md create mode 100644 en/advanced-topics/commandline.md create mode 100644 en/advanced-topics/compilation.md create mode 100644 en/advanced-topics/introduction.md rename src/main/asciidoc/advanced-using-nightly-builds.adoc => en/advanced-topics/nightlies.md (65%) create mode 100644 en/advanced-topics/ramdisks.md create mode 100644 en/configuration.md create mode 100644 en/getting-started/eclipse.md create mode 100644 en/getting-started/gradle.md create mode 100644 en/getting-started/intellij.md create mode 100644 en/getting-started/introduction.md create mode 100644 en/getting-started/maven.md create mode 100644 en/getting-started/structure.md rename {src/main/asciidoc => en}/images/eclipse-create-project.png (100%) rename {src/main/asciidoc => en}/images/eclipse-debug-sim.png (100%) rename {src/main/asciidoc => en}/images/eclipse-demo-app.png (100%) rename {src/main/asciidoc => en}/images/eclipse-deploy.png (100%) rename {src/main/asciidoc => en}/images/eclipse-install-new-software.png (100%) rename {src/main/asciidoc => en}/images/eclipse-install-new-software@2x.png (100%) rename {src/main/asciidoc => en}/images/eclipse-ios-project-wizard.png (100%) rename {src/main/asciidoc => en}/images/eclipse-marketplace.png (100%) rename {src/main/asciidoc => en}/images/eclipse-project-wizard.png (100%) rename {src/main/asciidoc => en}/images/eclipse-project.png (100%) rename {src/main/asciidoc => en}/images/eclipse-run-debug.png (100%) rename {src/main/asciidoc => en}/images/eclipse-unit-test.png (100%) rename {src/main/asciidoc => en}/images/license-manager.png (100%) rename {src/main/asciidoc => en}/images/logo.png (100%) rename {src/main/asciidoc => en}/images/simulator.png (100%) rename {src/main/asciidoc => en}/images/using-ram-disks-unmount.png (100%) create mode 100644 en/introduction.md create mode 100644 en/samples.md delete mode 100644 pom.xml delete mode 100644 src/main/asciidoc/advanced-bro.adoc delete mode 100644 src/main/asciidoc/advanced-command-line-usage.adoc delete mode 100644 src/main/asciidoc/advanced-topics.adoc delete mode 100644 src/main/asciidoc/advanced-under-the-hood.adoc delete mode 100644 src/main/asciidoc/advanced-using-ram-disks.adoc delete mode 100644 src/main/asciidoc/configuration-reference.adoc delete mode 100644 src/main/asciidoc/getting-started-eclipse.adoc delete mode 100644 src/main/asciidoc/getting-started-gradle.adoc delete mode 100644 src/main/asciidoc/getting-started-idea.adoc delete mode 100644 src/main/asciidoc/getting-started-maven.adoc delete mode 100644 src/main/asciidoc/getting-started.adoc delete mode 100644 src/main/asciidoc/index.adoc delete mode 100644 src/main/asciidoc/introduction.adoc delete mode 100644 src/main/asciidoc/samples.adoc delete mode 100644 stylesheets/foundation.css create mode 100644 theme/assets/app.js create mode 100755 theme/assets/fonts/fontawesome/FontAwesome.otf create mode 100755 theme/assets/fonts/fontawesome/fontawesome-webfont.eot create mode 100755 theme/assets/fonts/fontawesome/fontawesome-webfont.svg create mode 100755 theme/assets/fonts/fontawesome/fontawesome-webfont.ttf create mode 100755 theme/assets/fonts/fontawesome/fontawesome-webfont.woff create mode 100644 theme/assets/fonts/merriweather/250.woff create mode 100644 theme/assets/fonts/merriweather/250i.woff create mode 100644 theme/assets/fonts/merriweather/400.woff create mode 100644 theme/assets/fonts/merriweather/400i.woff create mode 100644 theme/assets/fonts/merriweather/700.woff create mode 100644 theme/assets/fonts/merriweather/700i.woff create mode 100644 theme/assets/fonts/merriweather/900.woff create mode 100644 theme/assets/fonts/merriweather/900i.woff create mode 100644 theme/assets/fonts/opensans/300.woff create mode 100644 theme/assets/fonts/opensans/300i.woff create mode 100644 theme/assets/fonts/opensans/400.woff create mode 100644 theme/assets/fonts/opensans/400i.woff create mode 100644 theme/assets/fonts/opensans/600.woff create mode 100644 theme/assets/fonts/opensans/600i.woff create mode 100644 theme/assets/fonts/opensans/700.woff create mode 100644 theme/assets/fonts/opensans/700i.woff create mode 100644 theme/assets/images/apple-touch-icon-precomposed-152.png create mode 100644 theme/assets/images/favicon.ico create mode 100755 theme/assets/print.css create mode 100755 theme/assets/style.css create mode 100644 theme/i18n/ar.json create mode 100644 theme/i18n/bn.json create mode 100644 theme/i18n/de.json create mode 100644 theme/i18n/en.json create mode 100644 theme/i18n/es.json create mode 100644 theme/i18n/fa.json create mode 100644 theme/i18n/fr.json create mode 100644 theme/i18n/it.json create mode 100644 theme/i18n/no.json create mode 100644 theme/i18n/pl.json create mode 100644 theme/i18n/pt.json create mode 100644 theme/i18n/ru.json create mode 100644 theme/i18n/zh-cn.json create mode 100644 theme/i18n/zh-tw.json create mode 100644 theme/javascript/core/events.js create mode 100644 theme/javascript/core/font-settings.js create mode 100755 theme/javascript/core/keyboard.js create mode 100644 theme/javascript/core/loading.js create mode 100755 theme/javascript/core/navigation.js create mode 100755 theme/javascript/core/progress.js create mode 100755 theme/javascript/core/search.js create mode 100755 theme/javascript/core/sidebar.js create mode 100755 theme/javascript/core/state.js create mode 100755 theme/javascript/gitbook.js create mode 100644 theme/javascript/utils/dropdown.js create mode 100755 theme/javascript/utils/platform.js create mode 100755 theme/javascript/utils/sharing.js create mode 100755 theme/javascript/utils/storage.js create mode 100644 theme/javascript/utils/url.js create mode 100644 theme/stylesheets/base/markdown.less create mode 100644 theme/stylesheets/base/normalize.less create mode 100644 theme/stylesheets/base/preboot.less create mode 100755 theme/stylesheets/ebook.less create mode 100644 theme/stylesheets/ebook/highlight.less create mode 100644 theme/stylesheets/ebook/variables.less create mode 100755 theme/stylesheets/mixins.less create mode 100755 theme/stylesheets/website.less create mode 100644 theme/stylesheets/website/alerts.less create mode 100755 theme/stylesheets/website/body.less create mode 100644 theme/stylesheets/website/buttons.less create mode 100644 theme/stylesheets/website/dropdown.less create mode 100644 theme/stylesheets/website/font-settings.less create mode 100644 theme/stylesheets/website/fonts.less create mode 100644 theme/stylesheets/website/glossary.less create mode 100755 theme/stylesheets/website/header.less create mode 100644 theme/stylesheets/website/highlight/night.less create mode 100644 theme/stylesheets/website/highlight/sepia.less create mode 100644 theme/stylesheets/website/highlight/white.less create mode 100755 theme/stylesheets/website/languages.less create mode 100755 theme/stylesheets/website/markdown.less create mode 100755 theme/stylesheets/website/navigation.less create mode 100755 theme/stylesheets/website/summary.less create mode 100644 theme/stylesheets/website/variables.less create mode 100644 theme/templates/ebook/glossary.html create mode 100644 theme/templates/ebook/layout.html create mode 100644 theme/templates/ebook/page.html create mode 100644 theme/templates/ebook/summary.html create mode 100644 theme/templates/website/glossary.html create mode 100644 theme/templates/website/includes/font-settings.html create mode 100644 theme/templates/website/includes/header.html create mode 100644 theme/templates/website/includes/summary.html create mode 100755 theme/templates/website/langs.html create mode 100644 theme/templates/website/layout.html create mode 100644 theme/templates/website/page.html diff --git a/.gitignore b/.gitignore index f0a58c0..25f82af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_STORE target/ +_book pom.xml.tag pom.xml.releaseBackup pom.xml.versionsBackup diff --git a/Guardfile b/Guardfile deleted file mode 100644 index 2532171..0000000 --- a/Guardfile +++ /dev/null @@ -1,25 +0,0 @@ -require 'asciidoctor' -require 'erb' -require 'fileutils' - -src_folder = 'src/main/asciidoc' - -guard 'shell' do - watch(/^#{src_folder}\/.*\.adoc$/) {|m| - path = m[0][src_folder.length+1..-1] - path = path.sub(/\.adoc$/, '.html') - - Asciidoctor.render_file("#{src_folder}/index.adoc", - { - :to_file => "target/live/index.html", - :mkdirs => true, - :safe => 0, - :attributes => { "stylesheet" => "../../../stylesheets/foundation.css" } - }) - } - watch(/^#{src_folder}\/.*\.png$/) {|m| - path = m[0][src_folder.length+1..-1] - FileUtils.mkdir_p(File.dirname("target/live/#{path}")) - FileUtils.cp(m[0], "target/live/#{path}") - } -end diff --git a/LANGS.md b/LANGS.md new file mode 100644 index 0000000..8a7f1f5 --- /dev/null +++ b/LANGS.md @@ -0,0 +1 @@ +* [English](en) diff --git a/README.md b/README.md index a8622dd..a95bef6 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,32 @@ -RoboVM Documentation Project -=========== +# RoboVM Documentation Project -To generate the docs run +## Development +Docs are written in [markdown](http://daringfireball.net/projects/markdown/syntax), and rendered using [gitbook](https://github.com/GitbookIO/gitbook). + +Make sure you have [npm](https://www.npmjs.com/) installed and run + +```bash +npm install gitbook -g +gitbook serve . ``` -mvn package + +This will start a server, watch for changes to files, and automatically refresh the browser when the build completes. + +## Deployment + +The book can be built for deployment using + +```bash +gitbook build . ``` -This project also comes with a `guard` file which can be used to get a live preview when editing the asciidoc source files. For instructions see: http://asciidoctor.org/docs/editing-asciidoc-with-live-preview/. +There are options for rendering to pdf and epub, but the default is to output a website in the _book directory. + +## Contributing + +This book has been written by various RoboVM contributors. + +If you notice any errors or would like to help out, please use Github issues to discuss any changes so that work will not be duplicated. + +All content is licensed under the [Creative Commons Attribution Non Commercial Share Alike 4.0 license](http://creativecommons.org/licenses/by-nc-sa/4.0/). diff --git a/book.json b/book.json new file mode 100644 index 0000000..57aeee4 --- /dev/null +++ b/book.json @@ -0,0 +1,13 @@ +{ + "gitbook": ">=2.0.0", + "theme": "./theme", + "title": "RoboVM User Guide", + "structure": { + "readme": "introduction.md" + }, + "variables": { + "appVersion": "1.0.0", + "osxVersion": "10.9", + "xcodeVersion": "6.x" + } +} diff --git a/en/SUMMARY.md b/en/SUMMARY.md new file mode 100644 index 0000000..5805e35 --- /dev/null +++ b/en/SUMMARY.md @@ -0,0 +1,17 @@ +# Summary + +* [Getting Started](getting-started/introduction.md) + * [Getting Started with Eclipse](getting-started/eclipse.md) + * [Getting Started with IntelliJ](getting-started/intellij.md) + * [Getting Started with Maven](getting-started/maven.md) + * [Getting Started with Gradle](getting-started/gradle.md) + * [Project and Code Structure](getting-started/structure.md) +* [Samples](samples.md) +* [Configuration Reference](configuration.md) +* [Advanced Topics](advanced-topics/introduction.md) + * [Under the Hood](advanced-topics/compilation.md) + * [Using RAM Disks](advanced-topics/ramdisks.md) + * [Using the Latest Nightly Build](advanced-topics/nightlies.md) + * [Using the Latest Nightly Build](advanced-topics/nightlies.md) + * [The Bro Java to Native Bridge](advanced-topics/bro.md) + * [Command Line Usage](advanced-topics/commandline.md) diff --git a/en/advanced-topics/bro.md b/en/advanced-topics/bro.md new file mode 100644 index 0000000..6875d21 --- /dev/null +++ b/en/advanced-topics/bro.md @@ -0,0 +1,699 @@ +# The Bro Java to Native Bridge + +Bro is a RoboVM specific API that enables Java code to call directly into native code without using JNI. It has been inspired by [JNA](https://github.com/twall/jna), [BridJ](http://code.google.com/p/bridj/) and [.NET's P/Invoke](http://en.wikipedia.org/wiki/Platform_Invocation_Services). + +Bro is the Swedish word for bridge and is pronounced broo. + +We'll introduce bro with a simple example: + +```java +import org.robovm.rt.bro.*; +import org.robovm.rt.bro.annotation.*; + +@Library("c") // [1] +public class Abs { + static { + Bro.bind(); // [3] + } + @Bridge private static native int abs(int i); // [2] + public static void main(String[] args) { + System.out.println(abs(-100)); + } +} +``` + +1. The `@Library` annotation tells Bro to look for symbols in the `libc` system library. Bro will prepend `lib` and append `.so` to the specified library name when searching for a matching library + +2. The `@Bridge` annotated `Abs.abs()` method will bind to the native [`abs()`](http://pubs.opengroup.org/onlinepubs/009695399/functions/abs.html) function in `libc`. + +3. The `Bro.bind()` call initiates the lookup of native functions and binds them to the corresponding `@Bridge` annotated methods. This process relies on [`dlopen()`](http://pubs.opengroup.org/onlinepubs/009695399/functions/dlopen.html) and [`dlsym()`](http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html) to find matching symbols. + +## Primitive type marshaling + +### Primitive Java types + +Native integer types (e.g. `char`, `int32_t`, `float`) are mapped to Java integer types of the same size: + +| Java | Bits | Example C type * | +|--------|------|--------------------| +| byte | 8 | char, uint8_t | +| short | 16 | short | +| char | 16 | uint16_t | +| int | 32 | int, int32_t | +| long | 64 | long long, int64_t | +| float | 32 | float | +| double | 64 | double | + +\* Depends on compiler and platform + +> NOTE: Unsigned types (e.g. `uint32_t`) are mapped to the signed Java type of the same bit size. + +#### Platform dependent primitive types + +Some native types have varying bit sizes depending on the target platform. E.g. the C `long` type is usually a 32-bit integer on 32-bit platforms but a 64-bit integer on 64-bit platforms. To support such types Bro provides three different annotations: + +##### @MachineSizedFloat + +`@MachineSizedFloat` is used to bind floating point types which are 32-bit on 32-bit platforms and 64-bit on 64-bit platforms. The `CGFloat` type in Apple's Cocoa and CocoaTouch APIs is an example of such a type. `CGFloat` is bound using `@MachineSizedFloat double` in RoboVM's CocoaTouch bindings. On the Java side the value is kept in a `float` or `double` and Bro will take care of the native<-->Java conversion. + +###### Example usage: + +The C function which returns x^y^ of a `CGFloat` value + +```c +CGFloat pow(CGFloat x, CGFloat y); +``` + +would be bound like this using Bro: + +```java +@Bridge +public native @MachineSizedFloat double pow( + @MachineSizedFloat double x, + @MachineSizedFloat double y); +``` + +> NOTE: The method parameter or return type annotated with `@MachineSizedFloat` must either have the Java type `float` or `double`. + +> CAUTION: When using `@MachineSizedFloat float` on 64-bit platforms Bro will cast the native value from a 64-bit `double` to a 32-bit `float` value when converting a native value to a Java value. This operation may result in loss of precision. The same situation occurs when using `@MachineSizedFloat double` on 32-bit platforms and passing a Java value to native code. + +##### @MachineSizedSInt + +`@MachineSizedSInt` is used to bind signed integer types which are 32-bit on 32-bit platforms and 64-bit on 64-bit platforms. The `NSInteger` type in Apple's Cocoa and CocoaTouch APIs is an example of such a type. `NSInteger` is bound using `@MachineSizedSInt long` in RoboVM's CocoaTouch bindings. On the Java side the value is always kept in a `long` and Bro will take care of the native<-->Java conversion. + +###### Example usage: + +The C function which returns the asbolute of an `NSInteger` value + +```c +NSInteger abs(NSInteger v); +``` + +would be bound like this using Bro: + +```java +@Bridge +public native @MachineSizedSInt long abs( + @MachineSizedSInt long v); +``` + +> NOTE: The method parameter or return type annotated with `@MachineSizedSInt` must have the Java type `long`. + +##### @MachineSizedUInt + +`@MachineSizedUInt` is used to bind signed integer types which are 32-bit on 32-bit platforms and 64-bit on 64-bit platforms. The `NSUInteger` type in Apple's Cocoa and CocoaTouch APIs is an example of such a type. `NSUInteger` is bound using `@MachineSizedUInt long` in RoboVM's CocoaTouch bindings. On the Java side the value is always kept in a `long` and Bro will take care of the native<-->Java conversion. + +###### Example usage: + +The C function which returns the max of two `NSUInteger` values + +```c +NSUInteger max(NSUInteger a, NSUInteger b); +``` + +would be bound like this using Bro: + +```java +@Bridge +public native @MachineSizedUInt long max( + @MachineSizedUInt long a, + @MachineSizedUInt long b); +``` + +> NOTE: The method parameter or return type annotated with `@MachineSizedUInt` must have the Java type `long`. + +##### Pointers + +Pointers are passed as Java `long` values annotated with the Bro `@Pointer` annotation. The Bro compiler will handle the 64-bit <--> 32-bit conversions on 32-bit platforms. + +###### Example usage: + +The C `malloc()` function + +```c +void *malloc(size_t size); +``` + +could be bound like this using Bro: + +```java +@Bridge +public native @Pointer long malloc( + @MachineSizedUInt long size); +``` + +#### Primitive type pointer classes + +Bro provides special pointer classes for each of the Java primitive types which makes it easier to work with pointers to primitive types. Using these classes facilitates converting between Java arrays of primitives and native memory, converting pointers to direct `java.nio.Buffer` instances and more. These classes are located in the [`org.robovm.rt.bro.ptr`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/package-summary.html) package. + +###### Example of using the `BytePtr` class: + +The C `getenv()` function + +```c +char *getenv(const char *name); +``` + +can be bound like this using Bro in RoboVM: + +```java +@Bridge +public native BytePtr getenv(BytePtr name); +``` + +And used like this to print out the value of `$HOME`: + +```java +public static void main(String[] args) { + BytePtr value = getenv(BytePtr.toBytePtrAsciiZ("HOME")); + System.out.println(value.toStringAsciiZ()); +} +``` + +## Structs + +C `struct` types are mapped to Java by extending the bro [`Struct`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/Struct.html) class. Each member of the C `struct` is bound using a getter method and a setter method that must be `native` and annotated with the bro `@StructMember` annotation. The `@StructMember` annotation specifies the index of the member in the `struct`. The getter method must take 0 parameters and return some value while the setter method must take 1 parameter of the same type as the getter returns. The return type for the setter must either be `void` or the `Struct` class it belongs to. + +> TIP: The names of the getter and setter methods don't have to follow the Java Beans style convention for Java Beans properties. + +> TIP: If the setter method is declared as returning an instance of the `Struct` class it belongs to the Bro compiler will make it return `this` making it possible to chain setter method calls. + +###### Example struct: + +The C `struct timeval` + +```c +struct timeval { + time_t tv_sec; /* seconds since Jan. 1, 1970 */ + suseconds_t tv_usec; /* and microseconds */ +}; +``` + +can be bound like this using Bro in RoboVM: + +```java +public class Timeval extends Struct { + @StructMember(0) public native int tv_sec(); + @StructMember(0) public native Timeval tv_sec(int i); + @StructMember(1) public native int tv_usec(); + @StructMember(1) public native Timeval tv_usec(int i); +} +``` + +And used like this to call [`gettimeofday()`](http://pubs.opengroup.org/onlinepubs/009695399/functions/gettimeofday.html): + +```java +@Bridge static native int gettimeofday(Timeval tp, VoidPtr tzp); +public static void main(String[] args) { + Timeval t = new Timeval(); + gettimeofday(t, null); + System.out.format("Seconds since epoch: %d\n", t.tv_sec()); +} +``` + +### sizeof(struct) + +The size in bytes of a `Struct` can easily be queried by calling the static `sizeOf()` method on the `Struct` sub-class: + +```java +public class CGRect extends Struct { ... } +System.out.format("sizeof(CGRect) = %d\n", CGRect.sizeOf()); +``` + +### @ByRef and @ByVal + +The `@ByRef` and `@ByVal` annotations can be used to control how a `Struct` object is returned from a method or passed as a parameter to a method. `@ByRef` means pass as pointer and is the default. `@ByVal` means pass by value. The default can be changed to `@ByVal` for a particular `Struct` class by annotating the class with `@ByVal`: + +```java +@ByVal +public class Person extends Struct { ... } +``` + +### Nested structs + +`Struct` classes can contain other `Struct` objects as members, either by value or by reference (i.e. by pointer). The default is `@ByRef` with the same possibilities to override the default as for methods. + +Below is an example of how the CocoaTouch `struct CGRect` type is mapped to Java in the RoboVM Cocoa Touch bindings. A `CGRect` has two members: the `origin` is a `CGPoint` `struct` and the `size` is a `CGSize` struct. + +###### C: + +```c +struct CGRect { + CGPoint origin; + CGSize size; +}; +``` + +###### Java: + +```java +public class CGRect extends Struct { + public CGRect() {} + public CGRect(float x, float y, float width, float height) { + origin().x(x).y(y); + size().width(width).height(height); + } + public CGRect(CGPoint origin, CGSize size) { + origin(origin); + size(size); + } + @StructMember(0) public native @ByVal CGPoint origin(); + @StructMember(0) public native CGRect origin(@ByVal CGPoint origin); + @StructMember(1) public native @ByVal CGSize size(); + @StructMember(1) public native CGRect size(@ByVal CGSize size); +} +``` + +## Unions + +A C `union` is bound just like a C `struct` but has overlapping `@StructMember` indexes: + +###### C: + +```c +union TestUnion { + int i; + short s1; + short s2; +}; +``` + +###### Java: + +```java +public class TestUnion extends Struct { + @StructMember(0) public native int i(); + @StructMember(0) public native TestUnion i(int i); + @StructMember(0) public native short s1(); + @StructMember(0) public native TestUnion s1(short s1); + @StructMember(0) public native short s2(); + @StructMember(0) public native TestUnion s2(short s2); +} +``` + +## Native array members + +Bro provides the `@Array` annotation which is used to bind array struct members. The `@Array` annotation specifies the dimensions of the member's type. Space large enough to hold a native array of the specified type and dimensions will be reserved inside the struct. + +Single-dimensional array: + +###### C: + +```c +struct Vector { + int values[3]; +}; +``` + +###### Java: + +```java +public class Vector extends Struct { + @StructMember(0) + public native @Array(3) int[] values(); + @StructMember(0) + public native Vector values(@Array(3) int[] values); +} +``` + +Multi-dimensional array: + +###### C: + +```c +struct Matrix { + int values[1, 2, 3]; +}; +``` + +###### Java: + +```java +public class Matrix extends Struct { + @StructMember(0) + public native @Array({1, 2, 3}) int[][][] values(); + @StructMember(0) + public native Matrix values(@Array({1, 2, 3}) int[][][] values); +} +``` + +> NOTE: The native data will be copied to and from the `int[]` and `int[][][]` arrays in these examples. Changes in the Java arrays will not be directly reflected in the native data. The setter has to be called to update the native data. + +An alternative to using Java arrays is to use a sub-class of `java.nio.Buffer` instead: + +Single-dimensional array: + +###### C: + +```c +struct Vector { + int values[3]; +}; +``` + +###### Java: + +```java +public class Vector extends Struct { + @StructMember(0) + public native @Array(3) IntBuffer values(); + @StructMember(0) + public native Vector values(@Array(3) IntBuffer values); +} +``` + +Multi-dimensional array: + +###### C: + +```c +struct Matrix { + int values[1, 2, 3]; +}; +``` + +###### Java: + +```java +public class Matrix extends Struct { + @StructMember(0) + public native @Array({1, 2, 3}) IntBuffer values(); + @StructMember(0) + public native Matrix values(@Array({1, 2, 3}) IntBuffer values); +} +``` + +> NOTE: The buffer's `capacity()` will be restricted to the dimension of the array. For multi-dimensional arrays this is the product of the dimensions, 1*2*3=6 for the `Matrix` example. + +A third option is to use one of the pointer classes in the [`org.robovm.rt.bro.ptr`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/package-summary.html) package: + +Single-dimensional array: + +###### C: + +```c +struct Vector { + int values[3]; +}; +``` + +###### Java: + +```java +public class Vector extends Struct { + @StructMember(0) + public native @Array(3) IntPtr values(); + @StructMember(0) + public native Vector values(@Array(3) IntPtr values); +} +``` + +Multi-dimensional array: + +###### C: + +```c +struct Matrix { + int values[1, 2, 3]; +}; +``` + +###### Java: + +```java +public class Matrix extends Struct { + @StructMember(0) + public native @Array({1, 2, 3}) IntPtr values(); + @StructMember(0) + public native Matrix values(@Array({1, 2, 3}) IntPtr values); +} +``` + +It's also possible to have arrays of structs in a `Struct`: + +###### C: + +```c +struct Color { + char r; char g; char b; +}; +struct Gradient { + Color stops[3]; +}; +``` + +###### Java: + +```java +public class Color extends Struct { ... } +public class Gradient extends Struct { + @StructMember(0) public native @Array(3) Color[] stops(); + @StructMember(0) public native Gradient stops(@Array(3) Color[] stops); +} +``` + +## Unbounded native array members + +For unbounded native array members one should use one of the pointer classes in the [`org.robovm.rt.bro.ptr`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/package-summary.html) package combined with the `@ByVal` annotation: + +###### C: + +```c +struct PascalString { + int length; + char chars[]; +}; +``` + +###### Java: + +```java +public class PascalString extends Struct { + @StructMember(0) public native int length(); + @StructMember(0) public native PascalString length(int length); + @StructMember(0) public native @ByVal BytePtr chars(); +} +``` + +> NOTE: There's no setter for the `chars` member as that would have required the length to be known at compile time. Setting the individual bytes of `chars` has to be done through the `BytePtr` returned by the getter. + +## Struct memory handling + +When creating an instance of a `Struct` class Bro actually allocates two memory regions: one for the Java object and one for the actual struct data. The default is to allocate the struct data on the Java heap. There are two way to make sure that the underlying struct data is allocated on the GCed heap: + +```java +CGRect r = new CGRect(); +CGRect r = Struct.allocate(CGRect.class); +``` + +This means that the data will be garbage collected when the garbage collector determines that the struct data isn't referenced from any other memory allocated on the garbage collected heap. + +Allocating struct data on the GCed heap won't work for native code that holds on to a pointer to the struct data beyond a Java call into a native function since the native heap is not searched by the garbage collector. If the native side assumes ownership of the data and later frees it by a call to `free()` the Java side has to use `malloc()` to allocate it on the native heap: + +```java +CGRect r = Struct.malloc(CGRect.class); +``` + +> CAUTION: If the native side holds on to a memory region allocated on the GCed heap care must be taken on the Java side to make sure that the memory isn't collected until the native side is done with it. As long as the Java `Struct` instance is referenced on the Java side the struct data can't be collected. + +> TIP: The memory region allocated to hold a struct's data will always be zeroed out regardless of whether using the Java heap or the native heap. + +## Native arrays + +This allocates an array of 10 `CGRect` instances: + +```java +public class CGRect extends Struct { ... } +CGRect l = Struct.allocate(CGRect.class, 10); +``` + +This allocates a contiguous memory region big enough to hold 10 `CGRect` instances. The `Struct` class defines a number of methods that can be used to iterate over these, e.g. [`next()`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/Struct.html#next()) and [`previous()`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/Struct.html#previous()). + +`Struct` also implements the `Iterable` interface: + +```java +for (CGRect r : l) { + ... + if () { + break; + } +} +``` + +> CAUTION: The `Iterator` used when `for`-looping like this is unbounded so a `break` is required to finish the loop. + +The [`BytePtr`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/BytePtr.html) class and the other pointer classes in [`org.robovm.rt.bro.ptr`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/package-summary.html) are in fact `Struct` classes so to allocate a native array of 100 `int` values one could do: + +```java +IntPtr myInts = Struct.allocate(IntPtr.class, 100); +``` + +## Enums + +Simple C `enum` constants are mapped using Java `Enum` types which implement the bro [`ValuedEnum`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/ValuedEnum.html) interface. Here's an example: + +###### C: + +```c +enum { + NSTextAlignmentLeft, + NSTextAlignmentCenter, + NSTextAlignmentRight, + NSTextAlignmentJustified, + NSTextAlignmentNatural +}; +``` + +###### Java: + +```java +public enum NSTextAlignment implements ValuedEnum { + Left(0), Center(1), Right(2), + Justified(3), Natural(4); + + private final long n; + + private NSTextAlignment(long n) { this.n = n; } + public long value() { return n; } + public static NSTextAlignment valueOf(long n) { + for (NSTextAlignment v : values()) { + if (v.n == n) { + return v; + } + } + throw new IllegalArgumentException( + "No constant with value " + n + " found in " + + NSTextAlignment.class.getName()); + } +} +``` + +By default Bro marshals a `ValuedEnum` as a signed 32-bit value. The default can be changed by specifying an explicit `@Marshaler` on the enum type. Here's how to marshal `NSTextAlignment` values as platform dependent (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) signed integer values: + +###### Overriding the default marshaler for a `ValuedEnum`: + +```java +@Marshaler(ValuedEnum.AsMachineSizedSIntMarshaler.class) +public enum NSTextAlignment implements ValuedEnum { + ... +} +``` + +There are `ValuedEnum` marshalers for marshaling signed and unsigned 8-, 16-, 32- and 64-bit integer values. They are all available as [inner classes in the `ValuedEnum` interface](http://apidocs.robovm.com/latest/org/robovm/rt/bro/ValuedEnum.html). + +> TIP: The `@Marshaler` annotation can also be placed on a particular method return type or parameter type to only change the marshaler for that specific value. + +## Bits + +Bro provides a class called [`Bits`](http://apidocs.robovm.com/1.0.0-SNAPSHOT/org/robovm/rt/bro/Bits.html) that can be used to bind bitmask constants: + +###### C: + +```c +enum { + UIPopoverArrowDirectionUp = 1UL << 0, + UIPopoverArrowDirectionDown = 1UL << 1, + UIPopoverArrowDirectionLeft = 1UL << 2, + UIPopoverArrowDirectionRight = 1UL << 3, + ... +}; +``` + +###### Java: + +```java +public final class UIPopoverArrowDirection + extends Bits { + + public static final UIPopoverArrowDirection None = + new UIPopoverArrowDirection(0L); + public static final UIPopoverArrowDirection Up = + new UIPopoverArrowDirection(1L); + public static final UIPopoverArrowDirection Down = + new UIPopoverArrowDirection(2L); + public static final UIPopoverArrowDirection Left = + new UIPopoverArrowDirection(4L); + public static final UIPopoverArrowDirection Right = + new UIPopoverArrowDirection(8L); + ... + + private static final UIPopoverArrowDirection[] values = + _values(UIPopoverArrowDirection.class); + + public UIPopoverArrowDirection(long value) { super(value); } + private UIPopoverArrowDirection(long value, long mask) { + super(value, mask); + } + protected UIPopoverArrowDirection wrap(long value, long mask) { + return new UIPopoverArrowDirection(value, mask); + } + protected UIPopoverArrowDirection[] _values() { + return values; + } + public static UIPopoverArrowDirection[] values() { + return values.clone(); + } +} +``` + +`Bits` values can be ORed using the `Bits.with(...)` methods in a manner very similar to how `java.util.EnumSet.of(...)` works: + +###### C: + +```c +int upDown = UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown; +``` + +###### Java: + +```java +UIPopoverArrowDirection upDown = UIPopoverArrowDirection.with( + UIPopoverArrowDirection.Up, UIPopoverArrowDirection.Down); +``` + +> TIP: `Bits` types is the preferred way to bind bitmasks since it provides some degree of type-safety and an easier to understand API. It does however impose a performance penalty compared to using `public static final` constants. + +By default Bro marshals a `Bits` instance as an unsigned 32-bit value. The default can be changed by specifying an explicit `@Marshaler` on the class. Here's how to marshal `UIPopoverArrowDirection` values as platform dependent (32-bit on 32-bit platforms, 64-bit on 64-bit platforms) unsigned integer values: + +###### Overriding the default marshaler for a `Bits`: + +```java +@Marshaler(Bits.AsMachineSizedIntMarshaler.class) +public final class UIPopoverArrowDirection + extends Bits { + ... +} +``` + +There are `Bits` marshalers for marshaling unsigned 8-, 16-, 32- and 64-bit integer values. They are all available as [inner classes in the `Bits` interface](http://apidocs.robovm.com/latest/org/robovm/rt/bro/Bits.html). + +> TIP: The `@Marshaler` annotation can also be placed on a particular method return type or parameter type to only change the marshaler for that specific value. + +## Type marshalers + +Type marshalers are used by Bro to convert from native types into Java types and vice versa. + +#### Pointer marshalers + +Pointer marshalers marshal pointers to native objects to/from some Java object that wraps that pointer. The general contract for a pointer marshaler class looks like this: + +```java +public class MyTypeMarshaler { + @MarshalsPointer + public static MyType toObject(Class cls, long handle, long flags) { + ... + } + @MarshalsPointer + public static long toNative(MyType o, long flags) { + ... + } +} +``` + +This marshaler marshals `MyType` instances to/from native pointers (`handle`). Bro uses the signatures of the `@MarshalsPointer` methods to determine whether it is a method which marshals Java->native or native->Java. The Java type it can handle is determined by the signature (`MyType` in this case). + +The `cls` parameter specifies the actual `Class` used at the marshaling site. The passed in `Class` is assignment compatible with the `MyType` class or interface. + +The `flags` parameter gives some information on the call site. The possible values are defined by [`MarshalerFlags`](http://apidocs.robovm.com/latest/org/robovm/rt/bro/MarshalerFlags.html) class. + +> TIP: Marshaler method names are unimportant, the signatures are what matters. diff --git a/en/advanced-topics/commandline.md b/en/advanced-topics/commandline.md new file mode 100644 index 0000000..738881b --- /dev/null +++ b/en/advanced-topics/commandline.md @@ -0,0 +1,88 @@ +# Command Line Usage + +This section describes how to carry out some of the most common actions using the `robovm` command line tool. For a complete usage reference for the options supported by the `robovm` tool run + +```bash +$ robovm -help +``` + +## Working with robovm.xml files + +Almost everything can be done directly from the command line using the options of the `robovm` command but it is still recommended to use an [XML configuration file](../configuration.md) called `robovm.xml` to configure the compiler. + +The `-dumpconfig` option can be used to create a `robovm.xml` file. This creates a `robovm.xml` file for the demo app in [demo-app]: + +```bash +$ robovm -arch thumbv7 -os ios -cp "$ROBOVM_HOME/lib/robovm-objc.jar:$ROBOVM_HOME/lib/robovm-cocoatouch.jar:bin/" -dumpconfig robovm.xml IOSDemo +``` + +Once we have the `robovm.xml` file we only have to specify it on the command line to launch the app. This would launch the app on a connected device since the `robovm.xml` file specifies the `thumbv7` architecture: + +```bash +$ robovm -config robovm.xml -run +``` + +> TIP: You can load multiple configurations by specifying `-config` multiple times. The latter ones take precedence. + +We can override the configuration read from a `robovm.xml` file by specifying the options we want to override after the `robovm.xml` file has been read in. To launch on the iOS simulator we need to build for the `x86` architecture so we use the `-arch` option *after* the configuration file has been specified: + +```bash +$ robovm -config robovm.xml -arch x86 -run +``` + +We can even "edit" the `robovm.xml` file by combining `-config` and `-dumpconfig`. This adds a new classpath entry: + +```bash +$ robovm -config robovm.xml -cp foo.jar -dumpconfig robovm-new.xml +$ mv robovm-new.xml robovm.xml +``` + +## Expanding properties in robovm.xml files + +XML configuration files (and also `Info.plist` files) will be searched for `${...}` patterns. Such patterns will be replaced with properties loaded using the `-properties` command line option which reads in `.properties` file. Individual properties can also be specified directly on the command line using the `-Pname=value` option. + +## Launching apps + +To launch an app using the command line tool you simply specify the `-run` command line option. RoboVM will use the configured target OS (`-os`) and architecture (`-arch`) to determine how to launch the app. + +To launch in the iOS simulator use `-os ios` `-arch x86`: + +```bash +$ robovm -cp ... -os ios -arch x86 -run com.example.MainClass +``` + +To launch on an iOS device in 32-bit mode use `-os ios` `-arch thumbv7`: + +```bash +$ robovm -cp ... -os ios -arch thumbv7 -run com.example.MainClass +``` + +To launch on an iOS device in 64-bit mode use `-os ios` `-arch arm64`: + +```bash +$ robovm -cp ... -os ios -arch arm64 -run com.example.MainClass +``` + +RoboVM also supports building Mac OS X console apps. This is what you get if you don't specify any `-os` or `-arch` (or use `-os macosx` `-arch x86`): + +```bash +$ robovm -cp ... -run com.example.MainClass +``` + +## Packaging for App Store/Ad-Hoc distribution + +The `-createipa` option is used to create an [IPA file](http://en.wikipedia.org/wiki/.ipa_(file_extension)) which can be submitted to the App Store or distributed to beta tester or throughout an enterprise. + +> NOTE: Before you can do this you will have to have your signing certificates and provisioning profiles in order. Apple has some [great resources](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40012582-CH1-SW1) that describe how to enroll in the iOS developers program and create the certificates and provisioning profiles required for App Store distribution. + +This will create an IPA file signed with the code signing certificate matching _iPhone Distribution_ and using the provisioning profile named __My Distribution Profile__. The IPA will be stored in `~/Desktop/IPA/`: + +```bash +$ robovm -config robovm.xml -signidentity 'iPhone Distribution' -provisioningprofile 'My Distribution Profile' -d ~/Desktop/IPA/ -createipa +``` + +> TIP: The `-signingidentiy` option matches against the start of the certificate name. Alternatively you can use a certificate fingerprint. If the `-signingidentiy` value is enclosed in `/` a regexp search will be done against the certificate name instead. Run the command `security find-identity -v -p codesigning` or use the _KeyChain Access_ OS X app to view your installed certificates. + +> CAUTION: The IPA creation also creates a `.dSYM` folder in the folder you specify with `-d`. The `.dSYM` contains the debug symbols of your app. It is required if you want to symbolicate a crash report generated by your app. To symbolicate you need the exact `.dSYM` so *make sure you back this up*. + +The IPA is now ready to be distributed. To submit the IPA file to the App Store you would use the _Application Loader_ application that comes with Xcode. The _Application Loader_ application can easily be located using _Spotlight_. diff --git a/en/advanced-topics/compilation.md b/en/advanced-topics/compilation.md new file mode 100644 index 0000000..a8ebc75 --- /dev/null +++ b/en/advanced-topics/compilation.md @@ -0,0 +1,23 @@ +# Under the Hood + +## The Bytecode Compiler + +At the heart of RoboVM is its [ahead-of-time compiler](http://en.wikipedia.org/wiki/Ahead-of-time_compilation). This is a tool that can be invoked either from the command line, from build tools such as Maven or Gradle, or from an IDE such as Eclipse or IntelliJ. It takes Java bytecode and translates it into machine code for a specific operating system and CPU type. Usually this means iOS and the ARM processor type but RoboVM is also capable of generating code for Mac OS X and Linux running on x86 CPUs. + +The ahead-of-time approach is very different from how traditional JVMs, like [Oracle’s Hotspot](http://en.wikipedia.org/wiki/HotSpot), usually work. Such JVMs typically read in Java bytecode at runtime and somehow execute the virtual machine instructions contained in the bytecode. To speed up this process the JVM employs a technique called [just-in-time compilation](http://en.wikipedia.org/wiki/Just-in-time_compilation). In simple terms this process translates the virtual machine instructions of a method to native machine code for the current physical CPU the first time the method is invoked by the program. + +Due to technical restrictions that Apple has built into iOS just-in-time compilation of any kind is impossible in an iOS app. The only alternatives are to use an interpreter, which is too slow and power consuming, or use ahead-of-time compilation like in RoboVM. The ahead-of-time compilation process takes place at compile time on the developer machine so at runtime, on an iOS device, the generated machine code runs at full speed, comparable to or even faster than code compiled from Objective-C. + +By consuming Java bytecode rather than Java source code the RoboVM ahead-of-time compiler can, at least in theory, be used with any JVM language that compiles down to bytecode. Scala, Clojure and Kotlin are JVM languages already known to work. Another benefit with this approach is that RoboVM can be used with 3rd party libraries in standard JAR files without any need for the original source code enabling the use of proprietary and closed-source libraries. + +## Incremental compilation + +The first launch of a RoboVM app, even an app as simple as the `IOSDemo` app we saw in the demo app, takes some time. When compiling an app the RoboVM compiler starts with the app’s main class. It will then compile all classes needed by the main class and then the classes needed by those classes and so on until all classes needed by the app have been compiled. This process also compiles the standard runtime classes such as `java.lang.Object` and `java.lang.String`. This is a one-time thing only. RoboVM keeps a cache of compiled classes and only recompiles a class when it or any of its direct dependencies have changed. + +> TIP: By default RoboVM uses `$HOME/.robovm/cache/` as the cache folder. By deleting this folder you can force RoboVM to recompile all classes from scratch. + +The benefit of incremental compilation and caching of the object files is that it keeps down compile times. By only including the classes reachable from the main class it also keeps down the size of the produced executable. In some situations (e.g. when loading classes using reflection) the RoboVM compiler is unable to determine that a class should be compiled. Fortunately the compiler can be instructed to always include a particular class or even all classes matching a pattern. + +## Android-based runtime class library + +Any JVM needs a runtime class library. This is the library which provides the standard packages and classes needed by any Java program such as `java.lang.Object` and `java.lang.String`. RoboVM takes its runtime class library from the Android open-source project and all non-Android specific packages have been ported over to RoboVM. This means that any Java or JVM language code that only uses classes in the standard packages provided on Android should work the same under RoboVM. diff --git a/en/advanced-topics/introduction.md b/en/advanced-topics/introduction.md new file mode 100644 index 0000000..cd77a9f --- /dev/null +++ b/en/advanced-topics/introduction.md @@ -0,0 +1,3 @@ +# Advanced Topics + +This section covers advanced topics. diff --git a/src/main/asciidoc/advanced-using-nightly-builds.adoc b/en/advanced-topics/nightlies.md similarity index 65% rename from src/main/asciidoc/advanced-using-nightly-builds.adoc rename to en/advanced-topics/nightlies.md index 5c076a1..65018bb 100644 --- a/src/main/asciidoc/advanced-using-nightly-builds.adoc +++ b/en/advanced-topics/nightlies.md @@ -1,36 +1,26 @@ -[id="nightly-builds"] -=== Using the latest nightly build +# Using the Latest Nightly Build -WARNING: Nightly builds can be unstable. Use at your own risk! +> WARNING: Nightly builds can be unstable. Use at your own risk! -Every night (Central European Time) development builds of RoboVM are built. -The builds are uploaded to http://download.robovm.org and `SNAPSHOT` versions -of all Maven artifacts are pushed to Maven Central's snapshots repository as -well as `SNAPSHOT` builds of the Maven and Gradle plugins. +Every night (Central European Time) development builds of RoboVM are built. The builds are uploaded to http://download.robovm.org and `SNAPSHOT` versions of all Maven artifacts are pushed to Maven Central's snapshots repository as well as `SNAPSHOT` builds of the Maven and Gradle plugins. -==== Command line tools +## Command line tools -Download the latest `nightlies/robovm--SNAPSHOT-.tar.gz` from -http://download.robovm.org and then follow the instructions in -<> to install and use it. +Download the latest `nightlies/robovm--SNAPSHOT-.tar.gz` from http://download.robovm.org and then follow the instructions in [install-cli-tools] to install and use it. -==== Eclipse plugin +## Eclipse Plugin -Follow the instructions in <> but use the following -update site: +Follow the instructions in [getting-started-eclipse](../getting-started/eclipse.md) but use the following update site: ----- +``` http://download.robovm.org/nightlies/eclipse/ ----- +``` -==== Maven +## Maven -Use `SNAPSHOT` version dependencies for the RoboVM dependencies in your -`pom.xml`. Also make sure you use the corresponding `SNAPSHOT` version of the -`robovm-maven-plugin`: +Use `SNAPSHOT` version dependencies for the RoboVM dependencies in your `pom.xml`. Also make sure you use the corresponding `SNAPSHOT` version of the `robovm-maven-plugin`: -[source,xml] ----- +```xml x.y.z-SNAPSHOT x.y.z-SNAPSHOT @@ -60,14 +50,11 @@ Use `SNAPSHOT` version dependencies for the RoboVM dependencies in your ----- +``` -You also have to add the -https://oss.sonatype.org/content/repositories/snapshots snapshot repository to -your `pom.xml`: +You also have to add the https://oss.sonatype.org/content/repositories/snapshots snapshot repository to your `pom.xml`: -[source,xml] ----- +```xml sonatype-snapshots @@ -86,20 +73,15 @@ your `pom.xml`: ----- +``` -==== Gradle +## Gradle -Use `SNAPSHOT` version dependencies for the RoboVM dependencies in your -`build.gradle`. Also make sure you use the corresponding `SNAPSHOT` version of -the `robovm-gradle-plugin`: +Use `SNAPSHOT` version dependencies for the RoboVM dependencies in your `build.gradle`. Also make sure you use the corresponding `SNAPSHOT` version of the `robovm-gradle-plugin`: -NOTE: Gradle caches `SNAPSHOT` dependencies and will not always download new -ones as expected. Please clear your Gradle cache (`$HOME/.gradle`, -`/.gradle`) to make sure you get the latest `SNAPSHOT` builds. +> NOTE: Gradle caches `SNAPSHOT` dependencies and will not always download new ones as expected. Please clear your Gradle cache (`$HOME/.gradle`, `/.gradle`) to make sure you get the latest `SNAPSHOT` builds. -[source,groovy] ----- +```groovy buildscript { project.ext.roboVMVersion = "x.y.x-SNAPSHOT" project.ext.roboVMGradleVersion = "x.y.z-SNAPSHOT" @@ -145,4 +127,4 @@ robovm { task wrapper(type: Wrapper) { gradleVersion = '2.0' } ----- \ No newline at end of file +``` diff --git a/en/advanced-topics/ramdisks.md b/en/advanced-topics/ramdisks.md new file mode 100644 index 0000000..21ba392 --- /dev/null +++ b/en/advanced-topics/ramdisks.md @@ -0,0 +1,15 @@ +# Using RAM disks + +RoboVM can be taxing for slow HDDs in old Mac Minis and MacBooks. You can speed up the compilation and linking process by creating a RAM disk as follows: + +```bash +SIZE=2048 ; diskutil erasevolume HFS+ 'RoboVM RAM Disk' `hdiutil attach -nomount ram://$((SIZE * 2048))` +``` + +This will mount a RAM disk using 2GB of memory under `/Volumes/RoboVM RAM Disk`. RoboVM will then use this RAM disk for its cache, which normally lives under `~/.robovm`. + +The RAM disk feature will ensure that at least 400MB are available on the RAM disk by deleting those files that are least likely to contribute to the current build, e.g. files for a different architecture and OS. If your build requires more than 400MB, you can either increase the RAM disk size, or delete files under `/Volume/RoboVM RAM Disk` manually. + +To remove your RAM disk, open Finder, then click the unmount button next to `RoboVM RAM Disk`. + +![Unmounting a RAM disk](/images/using-ram-disks-unmount.png) diff --git a/en/configuration.md b/en/configuration.md new file mode 100644 index 0000000..a555b86 --- /dev/null +++ b/en/configuration.md @@ -0,0 +1,611 @@ +# Configuration Reference + +The recommended way to build RoboVM apps is to use a `robovm.xml` file to configure the compiler. This section lists the supported elements and also the corresponding command line options (if any.) + +The `robovm.xml` file is usually accompanied by a `robovm.properties` file. The `robovm.xml` file will be searched for these properties and any matches will be replaced with the actual value from the properties file. Properties are referenced using the same `${...}` syntax as used by Maven, Gradle and Ant. Here's and example: + +###### robovm.properties: + +``` +app.executable=IOSDemo +app.name=IOSDemo +``` + +###### robovm.xml: + +```xml + + ${app.executable} + ${app.mainclass} + ios + thumbv7 + + + resources + + + ios + Info.plist.xml + +``` + +> NOTE: All relative paths specified in a `robovm.xml` file will be resolved relative to the file itself. + +## <installDir> + +Specifies where to install the generated executable and other files. The default is `/`. For iOS apps the app will always be created in a sub-folder in the specified `` folder named like the `CFBundleExecutable` value in the app´s `Info.plist.xml` file and with `.app` appended. + +###### Example: + +```xml +target/MyApp +``` + +###### Command line usage: + +`-d ` + +## <executableName> + +Specifies the name of the executable to be generated. + +###### Example: + +```xml +MyAppExe +``` + +###### Command line usage: + +`-o ` + +## <useDynamicJni> + +Specifies whether to use dynamic JNI. With this enabled native methods will be dynamically linked at runtime. Native methods in classes in the boot classpath will always use static JNI. On iOS only static JNI is supported and this option is ignored. The default is `false`. + +###### Example: + +```xml +true +``` + +###### Command line usage: + +`-dynamic-jni` + +## <skipRuntimeLib> + +Specifies whether the default `robovm-rt.jar` should be automatically added to the bootclasspath. The default is `true` + +###### Example: + +```xml +false +``` + +###### Command line usage: + +`-skiprt` + +## <mainJar> + +This is the equivalent of the `-jar` command line option to the `java` command. The jar file will be added to the classpath and RoboVM will use the `Main-Class` set in the `META-INF/MANIFEST.MF` file in the jar file as `` value. Either this or `` must be specified. + +###### Example: + +```xml +lib/my-app.jar +``` + +###### Command line usage: + +`-jar ` + +## <mainClass> + +Specifies the fully-qualified name of the class containing the `main(String[])` method that will be called when starting the app. Either this or `` must be specified. + +###### Example: + +```xml +com.example.MyApp +``` + +###### Command line usage: + +Specified after all RoboVM compiler options but before any program options. + +## <cacerts> + +Specifies the cacerts file to be included in the app. RoboVM includes the same CA cerificates as included in Android 4.4.3. Allowed values are `none` and `full`. Default is `full` but no cacerts will be included unless the code actually needs them. + +###### Example: + +```xml +none +``` + +###### Command line usage: + +`-cacerts ` + +## <os> + +Specifies the name of the OS to build for. Allowed values are `auto`, `linux`, `macosx` and `ios`. Default is `auto` which normally means to build for the current host OS. + +###### Example: + +```xml +ios +``` + +###### Command line usage: + +`-os ` + +## <arch> + +Specifies the name of the CPU architecture to compile for. Allowed values are `auto`, `x86`, `x86_64`, `thumbv7`, `arm64`. Default is `auto` which normally means to build for the current host's CPU architecture. + +###### Example: + +```xml +thumbv7 +``` + +###### Command line usage: + +`-arch ` + +## <forceLinkClasses> + +Contains `` elements listing class patterns matching classes that must be linked in even if not referenced (directly or indirectly) from the main class. If no main class is specified all classes will be linked in unless this option has been given. Patterns are specified using an ANT style path syntax with the following rules: + +* `?` matches one character. +* `*` matches zero or more characters. +* `**` matches zero or more packages in a fully-qualified class name. + +An alternative syntax using `#` is also supported. This is useful when +specifying patterns on the command line as it prevents the shall from +expanding `*` characters. + +###### Example: + +```xml + + com.android.okhttp.HttpHandler + com.android.okhttp.HttpsHandler + com.android.org.conscrypt.** + +``` + +###### Command line usage: + +`-forcelinkclasses ` + +> NOTE: `-forcelinkclasses` can either be specified multiple times on the command line, each specifying a single pattern or specified once with multiple `:` separated patterns. E.g. `-forcelinkclasses 'com.example.Foo:com.example.bar.**'`. + +## <libs> + +Specifies, in nested `` elements, static libraries (with extension `.a`), object files (with extension `.o`) and system libraries that should be included when linking the final executable. + +If `force="true"` has been specified for a `` poining at a static library the entire static library will be linked in regardless of whether the symbols in it are referenced by the rest of the app's code or not. This uses the `-force_load` command line linker option when building for Mac OS X and iOS and `--whole-archive` when building for Linux. The default is `force="true"`. + +###### Example: + +```xml + + lib/libfoo.a + lib/myobjectfile.o + curl + +``` + +###### Command line usage: + +`-libs ` + +> NOTE: `-libs` can either be specified multiple times on the command line, each specifying a single value or specified once with multiple `:` separated values. E.g. `-libs 'lib/libfoo.a:curl'`. + +> CAUTION: There's no way to specify `force="false"` when using `-libs` from the command line. Use a `robovm.xml` file instead. + +## <exportedSymbols> + +Specifies, in nested `` elements, symbols that should be exported when linking the executable. This can be used when linking in functions which will be called using Bro. Wildcards can be used to match symbols: + +* `*` matches zero or more characters, +* `?` matches one character. +* `[abc]`, `[a-z]` matches one character from the specified set of characters. + +###### Example: + +```xml + + CB* + sin + +``` + +###### Command line usage: + +`-exportedsymbols ` + +> NOTE: `-exportedsymbols` can either be specified multiple times on the command line, each specifying a single value or specified once with multiple `:` separated values. E.g. `-exportedsymbols 'CB*:sin'`. + +## <frameworks> + +Specifies, in nested `` elements, Mac OS X or iOS frameworks that should be linked against when linking the final executable. + +###### Example: + +```xml + + CoreImage + UIKit + +``` + +###### Command line usage: + +`-frameworks ` + +> NOTE: `-frameworks` can either be specified multiple times on the command line, each specifying a single value or specified once with multiple `:` separated values. E.g. `-frameworks 'CoreImage:UIKit'`. + +## <weakFrameworks> + +Specifies, in nested `` elements, Mac OS X or iOS frameworks that should be weakly linked against when linking the final executable. Weakly linking against a framework means that all symbols in the framework will be marked as weakly linked. This allows apps to be built against one version of a framework which defines a particular symbol and later run against a different version of that framework which doesn't have that symbol defined. If that symbol had been strongly linked the app would immediately crash at launch. + +###### Example: + +```xml + + AdSupport + StoreKit + +``` + +###### Command line usage: + +`-weakframeworks ` + +> NOTE: `-weakframeworks` can either be specified multiple times on the command line, each specifying a single value or specified once with multiple `:` separated values. E.g. `-weakframeworks 'CoreImage:UIKit'`. + +## <frameworkPaths> + +Specifies, in nested `` elements, framework search paths used when searching for custom frameworks. + +###### Example: + +```xml + + lib/frameworks + +``` + +###### Command line usage: + +`-frameworkpaths ` + +> NOTE: `-frameworkpaths` can either be specified multiple times on the command line, each specifying a single value or specified once with multiple `:` separated values. E.g. `-frameworkpaths 'lib/frameworks:../frameworks'`. + +## <resources> + +Specifies files and directories that should be copied to the installation directory. A resource can be specified using a single path: + +###### Example: + +```xml + + path/to/the/resource.txt + +``` + +> NOTE: If the path specifies a directory, that directory including its contents (except for the default excludes, see below) will be copied. If the path specifies a file, that file will be copied directly to the installation directory. + +A resource be also be specified with a base directory, a target path and include and exclude filters (similar to Maven's `` element): + +###### Example: + +```xml + + + data + resources + + **/* + + + **/*.bak + + false + false + false + + +``` + +### <targetPath> + +The target path relative to the installation directory (i.e. app bundle directory for iOS apps) where paths matching this `` will be copied. If not specified paths will be copied directly to the installation directory. + +### <directory> + +The base directory containing the files and directories copied by the ``. + +### <includes> + +Specifies one or more Ant-style patterns (using `**`, `*` and `?` as wildcards) matching files which will be included when copying this ``. + +### <excludes> + +Specifies one or more Ant-style patterns (using `**`, `*` and `?` as wildcards) matching files which will be excluded when copying this ``. + +### <flatten> + +Set to `true` if the files matched by this `` should be copied directly into the installation directory without preserving the directory structure of the source directory. The default is `false`. + +### <ignoreDefaultExcludes> + +Set to `true` if the <> should be ignored and copied for this ``. The default is `false`, i.e. don't copy files matching the default excludes. + +### <skipPngCrush> + +Set this to `true` if `pngcrush` should not be called for PNG files matching this `` when targeting iOS. The default is `false`, i.e. `pngcrush` WILL be called for PNG files. + +> NOTE: Depending on the target (iOS, Mac OS X or Linux) resources may be transformed and renamed while being copied (e.g. running `pngcrush` or converting `xib` files to `nib` files). + +### Resource processing + +By default, any resources found in the specified resource paths will be copied to the installation directory. However, there exist several specific files and folders that need to be processed first before they can be used in an iOS application. + +The following sections explain which resources will be automatically processed for you and what they are used for. + +#### .xcassets folders + +`.xcassets` folders, also known as `Asset Catalogs`, contain graphical assets grouped into several subfolders, also known as `Sets`. Each set contains several image files along with a `Contents.json` file that describes the images. + +The following types of sets are supported: + +* __<name>.imageset__: If your app has a deployment target of iOS 7 or higher images in this set will be converted into a runtime binary format to reduce the overall app size. Otherwise they will simply be copied to the install directory. You can access an image by its name with `UIImage.create(String)`. + +* __AppIcon.appiconset__: Images in this set will be used as the app icon of the iOS app. + +* __LaunchImage.launchimage__: Images in this set will be used as the launch image of the iOS app. + +#### .atlas folders + +`.atlas` folders contain several graphic files that will be merged into one or multiple texture atlases. The result is a `.atlasc` folder named after the resource folder that contains the texture atlas image files and a property list file with the coordinates to all texture regions. + +The resulting texture atlas can be used via SpriteKit's `SKTextureAtlas` or manually by reading the files. + +> NOTE: Texture atlas generation can be configured with the <tools> element. + +### Default excludes + +(The same as those used by Ant 1.9) + + +``` +# Miscellaneous typical temporary files + +**/*~ +**/#*# +**/.#* +**/%*% +**/._* + +# CVS + +**/CVS +**/CVS/** +**/.cvsignore + +# SCCS + +**/SCCS +**/SCCS/** + +# Visual SourceSafe + +**/vssver.scc + +# Subversion + +**/.svn +**/.svn/** + +# Git + +**/.git +**/.git/** +**/.gitattributes +**/.gitignore +**/.gitmodules + +# Mercurial + +**/.hg +**/.hg/** +**/.hgignore +**/.hgsub +**/.hgsubstate +**/.hgtags + +# Bazaar + +**/.bzr +**/.bzr/** +**/.bzrignore + +# Mac + +**/.DS_Store +``` + +###### Command line usage: + +`-resources ` + +> NOTE: `-resources` can either be specified multiple times on the command line, each specifying a single value or specified once with multiple `:` separated values. E.g. `-resources '+resources/**:data/*+'`. + +> CAUTION: If a pattern is specified on the command line using `-resources` the longest non-pattern path before the first wildcard will be used as base directory and will not be recreated in the installation directory. E.g. with the pattern `+resources/**+` all files and folders in the folder named `resources` will be copied directly to the installation directory. + +## <tools> + +Specifies, in nested elements, additional configuration options for various command line tools that are used to process Cocoa-specific resources. + +### <textureAtlas> + +Specifies configuration options for the `TextureAtlas` tool. This tool is used for processing `.atlas` folders with image files into valid texture atlases. + +###### Example: + +```xml + + + RGBA8888_PNG + 2048x2048 + true + + +``` + +#### <outputFormat> + +Specifies the output format of the resulting texture atlas. + +Can be any of the following: + +* RGBA8888_PNG (default) +* RGBA8888_COMPRESSED +* RGBA4444_COMPRESSED +* RGBA5551_COMPRESSED +* RGB565_COMPRESSED + +#### <maximumTextureDimension> + +Specifies the maximum allowed dimension of the resulting texture atlas. + +Can be any of the following: + +* 2048x2048 (default) +* 4096x4096 + +#### <powerOfTwo> + +Specifies whether the dimensions of the resulting texture atlas should be power of 2. Default is `false`. + +## <bootclasspath> + +Specifies, in nested `` elements, directories, JAR archives, and ZIP archives to search for class files to be compiled by the RoboVM compiler. Classes in these entries will be loaded by the boot classloader at runtime. Used to locate the `+java.*+` and `+javax.*+` classes. Default is `/lib/robovm-rt.jar`. + +###### Example: + +```xml + + path/to/my/robovm-rt.jar + +``` + +###### Command line usage: + +`-bootclasspath ` +`-bootcp ` +`-bcp ` + +> NOTE: `-bootclasspath` can either be specified multiple times on the command line, each specifying a single value or specified once with multiple `:` separated values. + +> CAUTION: When running RoboVM in an IDE like Eclipse or from a build tool such as Maven or Gradle the `` and `` elements in the `robovm.xml` file will be ignored. Instead the classpaths of the IDE or build tool with be used. + +## <classpath> + +Specifies, in nested `` elements, directories, JAR archives, and ZIP archives to search for class files to be compiled by the RoboVM compiler. Classes in these entries will be loaded by the system classloader at runtime. + +###### Example: + +```xml + + target/classes + lib/commons-lang.jar + +``` + +###### Command line usage: + +`-classpath ` +`-cp ` + +> NOTE: `-classpath` can either be specified multiple times on the command line, each specifying a single value or specified once with multiple `:` separated values. + +> CAUTION: When running RoboVM in an IDE like Eclipse or from a build tool such as Maven or Gradle the `` and `` elements in the `robovm.xml` file will be ignored. Instead the classpaths of the IDE or build tool with be used. + +## <targetType> + +Specifies the target to build for. Either `auto`, `console` or `ios`. The default is `auto` which means use `` to decide. + +###### Example: + +```xml +ios +``` + +###### Command line usage: + +`-target ` + +## <iosSdkVersion> + +(*iOS only*) Specifies the version number of the iOS SDK to build against. If not specified the latest SDK that can be found will be used. + +###### Example: + +```xml +8.0 +``` + +.Command line usage: +`-sdk ` + +## <iosInfoPList> + +(*iOS only*) `Info.plist` file to be used by the app. If not specified a simple `Info.plist` will be generated with a `CFBundleIdentifier` based on the `` or ``. + +###### Example: + +```xml +plists/Info.plist +``` + +###### Command line usage: + +`-plist ` + +> TIP: The specified `Info.plist` file will be searched for `${...}` patterns just like `robovm.xml` files are. Such patterns will be replaced by the corresponding property, usually read from a `robovm.properties` file. + +## <iosResourceRulesPList> + +(*iOS only*) Property list (`.plist`) file containing resource rules passed to `codesign` when signing the app. + +###### Example: + +```xml +plists/ResourceRules.plist +``` + +###### Command line usage: + +`-resourcerules ` + +## <iosEntitlementsPList> + +(*iOS only*) Property list (`.plist`) file containing entitlements passed to `codesign` when signing the app. + +###### Example: + +```xml +plists/Entitlements.plist +``` + +###### Command line usage: + +`-entitlements ` diff --git a/en/getting-started/eclipse.md b/en/getting-started/eclipse.md new file mode 100644 index 0000000..5495f17 --- /dev/null +++ b/en/getting-started/eclipse.md @@ -0,0 +1,93 @@ +# Getting Started with Eclipse + +In this section you'll learn how to install Eclipse, install the RoboVM Eclipse plugin, activate your commercial license, and create and run your first iOS application. + +## Installing Eclipse + +With all the prerequisites out of the way, proceed to download a recent Eclipse build from https://www.eclipse.org/downloads/. Eclipse comes in many different flavors, the _Eclipse IDE for Java Developers_ package is sufficient for RoboVM development. Simply download the package, decompress it, and copy the resulting folder int `/Applications/`. + +> IMPORTANT: Eclipse *MUST* be run using Oracle’s Java SE 7 JDK or later. Apple’s Java 6 JVM will not work. Running Eclipse itself in Java 7 is not the same as adding a Java 7 JRE to Eclipe's _Installed JREs_ dialog in _Preferences_. To check which Java version Eclipse is running in go to _Eclipse -> About Eclipse_, then click _Installation Details_ and open the _Configuration_ tab. Find the `java.version` property and make sure it is 1.7 or higher. + +> IMPORTANT: The default max heap setting for Eclipse may be too low. In order to increase it *you need to change the -Xmx setting used when launching Eclipse*. To do this locate your Eclipse installation folder, right-click the Eclipse file and select _Show Package Contents_. Open the `eclipse.ini` file located in `Contents/MacOS` in a text editor and change the -Xmx value to 2G or more. Restart Eclipse. + +## Installing the Plugin + +With Eclipse installed and setup, you can now install the RoboVM Eclipse plugin by selecting _Install New Software_ from the Eclipse _Help_ menu, enter the following update site into the _Work with_ field and click _Next_: + +``` +http://download.robovm.org/eclipse/ +``` + +![Eclipse Install New Software dialog](/images/eclipse-install-new-software.png) + +Follow the on-screen instructions until installation is complete and restart Eclipse. + +## Activating your License + +If you have [purchased a subscription](http://www.robovm.com/pricing/) for one of RoboVM's subscription plans, you have to active the license for use on your computer. Activating the license will enable the features you purchased, such as debugging support or Interface Builder integration. Select _License Manager_ from the Eclipse _RoboVM_ menu and enter your license key. + +![License Manager dialog](/images/license-manager.png) + +> NOTE: A commercial license is not required to create RoboVM applications and deploy them to the App Store. Commercial licenses add additional features and services on top of the free core of RoboVM. For more information, visit our [pricing page](http://www.robovm.com/pricing/). + +## Creating a Project + +You can now create your first RoboVM project! Select __File -> New -> RoboVM iOS Project__. The project wizard will appear: + +![New Project Wizard](/images/eclipse-project-wizard.png) + +Perform these steps to define your project: + +1. Fill in your _Project Name_ +1. Specify the package and name of your _Main Class_, e.g. _com.mycompany.myapp.Main_ +1. Specify the _App Name_. This is the name used when your app is installed to an iOS device or simulator +1. Specify the _App ID_. This must be a unique identifier, usually your package name +1. Click _Finish_ + +## Running & Debugging + +You can run or debug a RoboVM app on either the simulator or a provisioned device connected via USB, directly from within Eclipse. Right click the project in the package or project view, select _Run As_ or _Debug As_, then select which platform you want to run/debug the app on. + +![Running & Debugging from within Eclipse](/images/eclipse-run-debug.png) + +> NOTE: The first time you run your application on the simulator or the device, RoboVM has to compile not only the classes of your app, but also any runtime classes required by your code. This can take some time. The next time you compile your app, RoboVM will only recompile the classes that have changed since the last compilation. You can view RoboVM's progress in the RoboVM console view. + +![Debugging on the simulator in Eclipse](/images/eclipse-debug-sim.png) + +When starting you app in debug mode, you have the full debugging tools of Eclipse at your disposal: you can set breakpoints, step into/out/over source lines, inspect and set variables and even use [Eclipse's display view](http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.docuser%2Freference%2Fviews%2Fdisplay%2Fref-display_view.htm) + +## Unit Testing + +RoboVM supports running and debugging JUnit tests for console and simulator apps. Let's add a new unit test to our project. + +Create a new source folder which will contain all your unit tests by right clicking the project and selecting __File -> New -> Source Folder__. In the dialog, enter `src/test/java`, then click _Finish_. Copy the following source code to your clipboard, then select the `src/test/java` folder in Eclipse and paste the clipboard contents. + +```java +import static org.junit.Assert.*; +import org.junit.Test; + +public class MyIOSUnitTest { + @Test + public void test() { + System.out.println(System.getProperty("os.name")); + System.out.println(System.getProperty("os.arch")); + fail("Not yet implemented"); + } +} +``` + +We have not yet added JUnit as a dependency to our project, so you will see compilation errors. Move your cursor somewhere on the line that reads `@Test` of the `MyIOSUnitTest.java` file, then press `CMD+1` and select _Add JUnit 4 libray to the build path_. + +You can now run this unit test by right clicking the `MyIOSUnitTest.java` file in Eclipse, then select _Run As_ or _Debug As_, followed by _iOS Simulator JUnit Test_. + +![Unit testing in Eclipse](/images/eclipse-unit-test.png) + +## Deployment + +Once your are happy with your app and have tested it on multiple devices, it's time to publish it to the App Store. For this you need to create an [iOSApplication Archive](http://en.wikipedia.org/wiki/.ipa_%28file_extension%29)(IPA). To do so from within Ecipse, right click your project, then select _RoboVM Tools -> Package for Ad-hoc/App Store distribution..._. + +![IPA export for ad-hoc and App Store distribution](/images/eclipse-deploy.png) + +Specify the output directory, your signing identity and provisioning profile and click _Finish_. You will find a file with the extension `.ipa` in the output directory, which is ready to be uploaded to iTunes Connect via the Application Loader. + +> NOTE: Please refer to [Apple's documentation](https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html) on how to submit your application. diff --git a/en/getting-started/gradle.md b/en/getting-started/gradle.md new file mode 100644 index 0000000..e85fcd4 --- /dev/null +++ b/en/getting-started/gradle.md @@ -0,0 +1,5 @@ +# Getting Started with Gradle + +_Coming Soon_! + +> NOTE: Please refer to the plugin's documentation on [Github](https://github.com/robovm/robovm-gradle-plugin). diff --git a/en/getting-started/intellij.md b/en/getting-started/intellij.md new file mode 100644 index 0000000..db78acc --- /dev/null +++ b/en/getting-started/intellij.md @@ -0,0 +1,5 @@ +# Getting Started with IntelliJ + +_Coming Soon_! + +> NOTE: A preliminary IntelliJ IDEA plugin is [available](https://plugins.jetbrains.com/plugin/7588?pr=idea). It is a wrapper around the RoboVM Gradle plugin. ETA for the official Intellij IDEA plugin is Q2 2015. diff --git a/en/getting-started/introduction.md b/en/getting-started/introduction.md new file mode 100644 index 0000000..1b1f492 --- /dev/null +++ b/en/getting-started/introduction.md @@ -0,0 +1,17 @@ +# Getting Started + +In this section you'll learn how to install RoboVM and make sure the toolchain works correctly by creating a very simple demo app. + +> TIP: Want run RoboVM on Linux? You can build Linux console apps using RoboVM at this time. Please see the [RoboVM GitHub wiki](https://github.com/robovm/robovm/wiki/Get-started-on-Linux) for instructions. + +## Prerequisites + +In order to use RoboVM the following is required: + +* A Mac running Mac OS X {{ book.osxVersion }} or later +* [Oracle's Java SE JDK 7](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or later +* [Xcode {{ book.xcodeVersion }} from the Mac App Store](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) + +> NOTE: The first time you install Xcode and every time you update to a new version you have to open it once to agree to the Xcode terms. + +> NOTE: To be able to test and deploy your apps on your devices, you will need an active subscription with the Apple Developer Program. Visit the [Apple Developer Portal](https://developer.apple.com/register/index.action) to sign up. You will also need to provision your device for development. You can find information on device provisioning in the Apple Developer Portal, or follow [this guide](http://www.bignerdranch.com/we-teach/how-to-prepare/ios-device-provisioning/). diff --git a/en/getting-started/maven.md b/en/getting-started/maven.md new file mode 100644 index 0000000..d806988 --- /dev/null +++ b/en/getting-started/maven.md @@ -0,0 +1,3 @@ +# Getting Started with Maven + +_Coming Soon_! diff --git a/en/getting-started/structure.md b/en/getting-started/structure.md new file mode 100644 index 0000000..4c61501 --- /dev/null +++ b/en/getting-started/structure.md @@ -0,0 +1,121 @@ +# Project and Code Structure + +Whatever method you chose to create your first RoboVM app, the project's structure will always resemble this layout, plus or minus the files your IDE or build system generated. + +![Basic iOS project in Eclipse](/images/eclipse-project.png) + +Here's a basic run-down of the project's contents: + +* `src/main/java/` is where your sources live +* `resources/` contains your app's icons, launch screens and any other assets your app requires +* `robovm.properties` let's you quickly set attributes of your app, such as the main class or app id. Values in this file will get replaced in the two files described below. +* `robovm.xml` let's you specify the RoboVM specific configuration of your app +* `Info.plist.xml` let's you specify the [iOS specific configuration](https://developer.apple.com/library/mac/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW1) of your app, such as supported screen orientations + +Let's take a quick look at the code itself! + +## The Main Entry Point + +Every app has a main entry point. We specify the main class in the `robovm.properties` file: + +```java +app.version=1.0 +app.id=com.mycompany.myapp +app.mainclass=com.mycompany.myapp.HelloRoboVM // [1] +app.executable=HelloRoboVM +app.build=1 +app.name=Hello RoboVM +``` + +1. The class is given via its fully qualified class name, including the package it resides in. + +When your app is run on the simulator or on a device, the main class's `main` method will be called on startup. + +```java +public class HelloRoboVM extends UIApplicationDelegateAdapter { // [4] + private UIWindow window; + private MyViewController rootViewController; + + @Override + public boolean didFinishLaunching (UIApplication application, + UIApplicationLaunchOptions launchOptions) { // [3] + rootViewController = new MyViewController(); + + window = new UIWindow(UIScreen.getMainScreen().getBounds()); + window.setRootViewController(rootViewController); + window.makeKeyAndVisible(); + + return true; + } + + public static void main (String[] args) { + try (NSAutoreleasePool pool = new NSAutoreleasePool()) { // [1] + UIApplication.main(args, null, HelloRoboVM.class); // [2] + } + } +} +``` + +1. Upon entering the `main` method, we setup an [`NSAutoreleasePool`](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html). It's responsible for managing the life-time of all native Objective-C objects your app interacts with. The autorelease pool will automatically free the memory of any object that is no longer referenced. + +2. We then call [`UIApplication.main`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/), telling it about our main class, `HelloRoboVM`. This method is responsible for kicking off the user interface, it will never return. Once it is done launching our app, it will call the `didFinishLaunching` method. + +3. In `didFinishLaunching` we setup our basic UI. iOS apps are usually composed of a single `UIWindow` on which we set a root `UIViewController`. The view controller is responsible for setting up user interface elements like labels, buttons and so forth, and reacting to any events on those elements. + +4. Note how `HelloRoboVM` extends from `UIApplicationDelegateAdapter`. We are essentially implementing the Objective-C [`UIApplicationDelegate`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/) protocol, in Java, which defines methods the `UIApplication` calls when application-level events happen. RoboVM let's us easily extend native Objective-C classes or implement Objective-C protocols! + +Let's take a look at the `MyViewController` class, the work horse of our application. + +> NOTE: iOS UIs can be created programmatically, as demonstrated here, or graphically, using XCode's [Interface Builder](https://developer.apple.com/xcode/interface-builder/). RoboVM currently only supports the programmatic creation of user interfaces. We'll provide Interface Builder integration in Q2 2015. + +## The View Controller + +View controllers are a simple way of managing individual screens of your app. A view controller usually sets up the UI controls of a specific screen, registers listeners for events such as button touches, and then reacts to these events. The `UIWindow` has a single root view controller, which itself can manage other view controllers. + +In our simple app, we have only one view controller, which we set as the root view controller on the window in `HelloRoboVM#didFinishLaunching`. + +```java +public class MyViewController extends UIViewController { // [1] + private final UIButton button; + private final UILabel label; + private int clickCount; + + public MyViewController () { // [2] + UIView view = getView(); + + view.setBackgroundColor(UIColor.white()); + + label = new UILabel(new CGRect(20, 250, 280, 44)); // [3] + label.setFont(UIFont.getSystemFont(24)); + label.setTextAlignment(NSTextAlignment.Center); + view.addSubview(label); + + button = UIButton.create(UIButtonType.RoundedRect); // [4] + button.setFrame(new CGRect(110, 150, 100, 40)); + button.setTitle("Click me!", UIControlState.Normal); + button.getTitleLabel().setFont(UIFont.getBoldSystemFont(22)); + + button.addOnTouchUpInsideListener(new UIControl.OnTouchUpInsideListener() { // [5] + @Override + public void onTouchUpInside (UIControl control, UIEvent event) { + label.setText("Click Nr. " + (++clickCount)); + } + }); + view.addSubview(button); + } +} +``` + +1. Our `MyViewController` subclasses the Objective-C [`UIViewController`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/) class. + +2. In its constructor, we setup a label and a button, which we add to the controller's [`UIView`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/). The `UIView` is responsible for rendering any content in its area and also handle interactions with that content. In this case, the `UIView` covers the whole `UIWindow`. + +3. To setup a label, we instantiate a [`UILabel`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UILabel_Class/), another Objective-C class, set its size and content, and add it as a sub view to our controllers view. + +4. We do the same for the button of our screen, with one slight twist! + +5. Since we want to react to button touches, we also register a touch listener with the button. Any time a user lifts her finger from the button, we get called back, informing us about this event. Note that the callback originates from native code. RoboVM transparently manages the transition between Java and native code for us! + +And here's what our resulting app looks like on the simulator after some heavy button clicking. + +![Our marvelous demo app](/images/eclipse-demo-app.png) diff --git a/src/main/asciidoc/images/eclipse-create-project.png b/en/images/eclipse-create-project.png similarity index 100% rename from src/main/asciidoc/images/eclipse-create-project.png rename to en/images/eclipse-create-project.png diff --git a/src/main/asciidoc/images/eclipse-debug-sim.png b/en/images/eclipse-debug-sim.png similarity index 100% rename from src/main/asciidoc/images/eclipse-debug-sim.png rename to en/images/eclipse-debug-sim.png diff --git a/src/main/asciidoc/images/eclipse-demo-app.png b/en/images/eclipse-demo-app.png similarity index 100% rename from src/main/asciidoc/images/eclipse-demo-app.png rename to en/images/eclipse-demo-app.png diff --git a/src/main/asciidoc/images/eclipse-deploy.png b/en/images/eclipse-deploy.png similarity index 100% rename from src/main/asciidoc/images/eclipse-deploy.png rename to en/images/eclipse-deploy.png diff --git a/src/main/asciidoc/images/eclipse-install-new-software.png b/en/images/eclipse-install-new-software.png similarity index 100% rename from src/main/asciidoc/images/eclipse-install-new-software.png rename to en/images/eclipse-install-new-software.png diff --git a/src/main/asciidoc/images/eclipse-install-new-software@2x.png b/en/images/eclipse-install-new-software@2x.png similarity index 100% rename from src/main/asciidoc/images/eclipse-install-new-software@2x.png rename to en/images/eclipse-install-new-software@2x.png diff --git a/src/main/asciidoc/images/eclipse-ios-project-wizard.png b/en/images/eclipse-ios-project-wizard.png similarity index 100% rename from src/main/asciidoc/images/eclipse-ios-project-wizard.png rename to en/images/eclipse-ios-project-wizard.png diff --git a/src/main/asciidoc/images/eclipse-marketplace.png b/en/images/eclipse-marketplace.png similarity index 100% rename from src/main/asciidoc/images/eclipse-marketplace.png rename to en/images/eclipse-marketplace.png diff --git a/src/main/asciidoc/images/eclipse-project-wizard.png b/en/images/eclipse-project-wizard.png similarity index 100% rename from src/main/asciidoc/images/eclipse-project-wizard.png rename to en/images/eclipse-project-wizard.png diff --git a/src/main/asciidoc/images/eclipse-project.png b/en/images/eclipse-project.png similarity index 100% rename from src/main/asciidoc/images/eclipse-project.png rename to en/images/eclipse-project.png diff --git a/src/main/asciidoc/images/eclipse-run-debug.png b/en/images/eclipse-run-debug.png similarity index 100% rename from src/main/asciidoc/images/eclipse-run-debug.png rename to en/images/eclipse-run-debug.png diff --git a/src/main/asciidoc/images/eclipse-unit-test.png b/en/images/eclipse-unit-test.png similarity index 100% rename from src/main/asciidoc/images/eclipse-unit-test.png rename to en/images/eclipse-unit-test.png diff --git a/src/main/asciidoc/images/license-manager.png b/en/images/license-manager.png similarity index 100% rename from src/main/asciidoc/images/license-manager.png rename to en/images/license-manager.png diff --git a/src/main/asciidoc/images/logo.png b/en/images/logo.png similarity index 100% rename from src/main/asciidoc/images/logo.png rename to en/images/logo.png diff --git a/src/main/asciidoc/images/simulator.png b/en/images/simulator.png similarity index 100% rename from src/main/asciidoc/images/simulator.png rename to en/images/simulator.png diff --git a/src/main/asciidoc/images/using-ram-disks-unmount.png b/en/images/using-ram-disks-unmount.png similarity index 100% rename from src/main/asciidoc/images/using-ram-disks-unmount.png rename to en/images/using-ram-disks-unmount.png diff --git a/en/introduction.md b/en/introduction.md new file mode 100644 index 0000000..b0ff84d --- /dev/null +++ b/en/introduction.md @@ -0,0 +1,40 @@ +# Introduction +> Version {{ book.appVersion }}, {{ file.mtime }} + +Mobile app developers targeting both Android and iOS face many challenges. +When comparing the native development environments of these two platforms, +i.e. the toolchains provided by Google and Apple respectively, one quickly +finds that they differ substantially. Android development, as defined by +Google, is based on the Intellij IDEA IDE and the Java programming language. +iOS development, according to Apple, on the other hand is based on the Xcode +IDE and the Objective-C programming language. These differences rule out any +code reuse between the platforms. Also, not many developers are proficient in +both environments. In the end almost every multi-platform app is developed +using separate development teams and separate codebases for each platform. + +The ultimate goal of the RoboVM project is to solve this problem without +compromising on neither developer nor app-user experience. With RoboVM +developing for both iOS and Android becomes less challenging; the same Java +developers can build both versions of the app and a large part of the codebase +can be shared. + +## Features + +* Brings Java and other JVM languages, such as [Scala](http://www.scala-lang.org/), [Clojure](http://clojure.org/), [Groovy](http://groovy.codehaus.org/) and [Kotlin](http://kotlinlang.org/), to iOS devices. +* Translates Java bytecode into machine code [ahead-of-time](http://en.wikipedia.org/wiki/Ahead-of-time_compilation) for fast execution directly on the CPU without any overhead. The main target is iOS and the ARM processor (32-bit and 64-bit) but there is also support for Mac OS X and Linux running on x86 CPUs (both 32-bit and 64-bit). +* Doesn't impose any restrictions on the Java platform features accessible to the developer, such as reflection or file I/O. +* Supports standard JAR files which lets the developer reuse the vast ecosystem of 3rd party Java libraries. +* Provides access to the [full native iOS APIs](https://developer.apple.com/technologies/ios/cocoa-touch.html) through a Java to Objective-C bridge enabling the development of apps with truly native UIs and with full hardware access. +* Integrates with the most popular tools such as + [Eclipse](https://www.eclipse.org/), [Intellij IDEA](https://www.jetbrains.com/idea/), [Maven](http://maven.apache.org/) and [Gradle](http://www.gradle.org/). +* App Store ready, with hundreds of apps already in the store. + +## Limitations + +There are a few limitations in RoboVM, mainly due to restrictions in the iOS +platform: + +* Loading custom bytecode at runtime is not supported. All class files comprising the app have to be available at compile time on the developer machine. +* The [Java Native Interface](http://en.wikipedia.org/wiki/Java_Native_Interface) technology as used on the desktop or on servers usually loads native code from dynamic libraries but Apple does not permit custom dynamic libraries to be shipped with an iOS app. RoboVM supports a variant of JNI based on static libraries. + +> NOTE: RoboVM has *full* support for reflection. diff --git a/en/samples.md b/en/samples.md new file mode 100644 index 0000000..2859067 --- /dev/null +++ b/en/samples.md @@ -0,0 +1,5 @@ +# Samples + +RoboVM comes with an extensive set of samples, available on [Github](https://github.com/robovm/robovm-samples). The samples are composed of ports of Apple's sample apps as well as apps we created ourselves. Most notable is ContractR, a simple task tracker app. The sample shows you how to create a cross-platform iOS & Android app, either using the native UIs of JavaFX, while sharing all its business logic across all platforms. + +The samples can be built and run from Eclipse, Maven, or Gradle. Refer to the repository's `README.md` for up-to-date instructions! diff --git a/pom.xml b/pom.xml deleted file mode 100644 index c57c1f2..0000000 --- a/pom.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - 4.0.0 - - org.robovm - robovm-docs - 1.0.0-SNAPSHOT - RoboVM Documentation Project - pom - - - 1.5.0 - 1.0.0-alpha-04 - - - - - - org.asciidoctor - asciidoctor-maven-plugin - ${asciidoctor.version} - - - output-html - generate-resources - - process-asciidoc - - - - ${maven.build.timestamp} - ${project.version} - ../../../stylesheets/foundation.css - - - html5 - true - prettify - - - - - - - - diff --git a/src/main/asciidoc/advanced-bro.adoc b/src/main/asciidoc/advanced-bro.adoc deleted file mode 100644 index 266d7ad..0000000 --- a/src/main/asciidoc/advanced-bro.adoc +++ /dev/null @@ -1,865 +0,0 @@ -[id=bro] -=== The Bro Java to Native Bridge - -Bro is a RoboVM specific API that enables Java code to call directly into -native code without using JNI. It has been inspired by -https://github.com/twall/jna[JNA], http://code.google.com/p/bridj/[BridJ] and -http://en.wikipedia.org/wiki/Platform_Invocation_Services[.NET's P/Invoke]. -Bro is the Swedish word for bridge and is pronounced broo. - -We'll introduce bro with a simple example: - -[source,java] ----- -import org.robovm.rt.bro.*; -import org.robovm.rt.bro.annotation.*; - -@Library("c") // <1> -public class Abs { - static { - Bro.bind(); // <3> - } - @Bridge private static native int abs(int i); // <2> - public static void main(String[] args) { - System.out.println(abs(-100)); - } -} ----- -<1> The `@Library` annotation tells Bro to look for symbols in the `libc` -system library. Bro will prepend `lib` and append `.so` to the specified -library name when searching for a matching library - -<2> The `@Bridge` annotated `Abs.abs()` method will bind to the native -http://pubs.opengroup.org/onlinepubs/009695399/functions/abs.html[`abs()`] -function in `libc`. - -<3> The `Bro.bind()` call initiates the lookup of native functions and binds -them to the corresponding `@Bridge` annotated methods. This process relies -on -http://pubs.opengroup.org/onlinepubs/009695399/functions/dlopen.html[`dlopen()`] -and -http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html[`dlsym()`] -to find matching symbols. - -==== Primitive type marshaling - -===== Primitive Java types - -Native integer types (e.g. `char`, `int32_t`, `float`) are mapped to Java -integer types of the same size: - -|=== -|Java |Bits |Example C type {asterisk} - -|byte -|8 -|char, uint8_t - -|short -|16 -|short - -|char -|16 -|uint16_t - -|int -|32 -|int, int32_t - -|long -|64 -|long long, int64_t - -|float -|32 -|float - -|double -|64 -|double -|=== - -{asterisk} Depends on compiler and platform - -NOTE: Unsigned types (e.g. `uint32_t`) are mapped to the signed Java type of -the same bit size. - -===== Platform dependent primitive types - -Some native types have varying bit sizes depending on the target platform. -E.g. the C `long` type is usually a 32-bit integer on 32-bit platforms but a -64-bit integer on 64-bit platforms. To support such types Bro provides three -different annotations: - -====== @MachineSizedFloat - -`@MachineSizedFloat` is used to bind floating point types which are 32-bit on -32-bit platforms and 64-bit on 64-bit platforms. The `CGFloat` type in Apple's -Cocoa and CocoaTouch APIs is an example of such a type. `CGFloat` is bound -using `@MachineSizedFloat double` in RoboVM's CocoaTouch bindings. On the Java -side the value is kept in a `float` or `double` and Bro will take care of the -native<-->Java conversion. - -.Example usage: -The C function which returns x^y^ of a `CGFloat` value -[source,c] ----- -CGFloat pow(CGFloat x, CGFloat y); ----- -would be bound like this using Bro: -[source,java] ----- -@Bridge -public native @MachineSizedFloat double pow( - @MachineSizedFloat double x, - @MachineSizedFloat double y); ----- - -NOTE: The method parameter or return type annotated with `@MachineSizedFloat` -must either have the Java type `float` or `double`. - -CAUTION: When using `@MachineSizedFloat float` on 64-bit platforms Bro will -cast the native value from a 64-bit `double` to a 32-bit `float` value when -converting a native value to a Java value. This operation may result in loss -of precision. The same situation occurs when using `@MachineSizedFloat double` -on 32-bit platforms and passing a Java value to native code. - -====== @MachineSizedSInt - -`@MachineSizedSInt` is used to bind signed integer types which are 32-bit on -32-bit platforms and 64-bit on 64-bit platforms. The `NSInteger` type in -Apple's Cocoa and CocoaTouch APIs is an example of such a type. `NSInteger` is -bound using `@MachineSizedSInt long` in RoboVM's CocoaTouch bindings. On the -Java side the value is always kept in a `long` and Bro will take care of the -native<-->Java conversion. - -.Example usage: -The C function which returns the asbolute of an `NSInteger` value -[source,c] ----- -NSInteger abs(NSInteger v); ----- -would be bound like this using Bro: -[source,java] ----- -@Bridge -public native @MachineSizedSInt long abs( - @MachineSizedSInt long v); ----- - -NOTE: The method parameter or return type annotated with `@MachineSizedSInt` -must have the Java type `long`. - -====== @MachineSizedUInt - -`@MachineSizedUInt` is used to bind signed integer types which are 32-bit on -32-bit platforms and 64-bit on 64-bit platforms. The `NSUInteger` type in -Apple's Cocoa and CocoaTouch APIs is an example of such a type. `NSUInteger` -is bound using `@MachineSizedUInt long` in RoboVM's CocoaTouch bindings. On -the Java side the value is always kept in a `long` and Bro will take care of -the native<-->Java conversion. - -.Example usage: -The C function which returns the max of two `NSUInteger` values -[source,c] ----- -NSUInteger max(NSUInteger a, NSUInteger b); ----- -would be bound like this using Bro: -[source,java] ----- -@Bridge -public native @MachineSizedUInt long max( - @MachineSizedUInt long a, - @MachineSizedUInt long b); ----- - -NOTE: The method parameter or return type annotated with `@MachineSizedUInt` -must have the Java type `long`. - -====== Pointers - -Pointers are passed as Java `long` values annotated with the Bro `@Pointer` -annotation. The Bro compiler will handle the 64-bit <--> 32-bit conversions on -32-bit platforms. - -.Example usage: -The C `malloc()` function -[source,c] ----- -void *malloc(size_t size); ----- -could be bound like this using Bro: -[source,java] ----- -@Bridge -public native @Pointer long malloc( - @MachineSizedUInt long size); ----- - -====== Primitive type pointer classes - -Bro provides special pointer classes for each of the Java primitive types -which makes it easier to work with pointers to primitive types. Using these -classes facilitates converting between Java arrays of primitives and native -memory, converting pointers to direct `java.nio.Buffer` instances and more. -These classes are located in the http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/package-summary.html[`org.robovm.rt.bro.ptr`] package. - -.Example of using the `BytePtr` class: -The C `getenv()` function -[source,c] ----- -char *getenv(const char *name); ----- -can be bound like this using Bro in RoboVM: -[source,java] ----- -@Bridge -public native BytePtr getenv(BytePtr name); ----- -And used like this to print out the value of `$HOME`: -[source,java] ----- -public static void main(String[] args) { - BytePtr value = getenv(BytePtr.toBytePtrAsciiZ("HOME")); - System.out.println(value.toStringAsciiZ()); -} ----- - -==== Structs - -C `struct` types are mapped to Java by extending the bro http://apidocs.robovm.com/latest/org/robovm/rt/bro/Struct.html[`Struct`] class. Each -member of the C `struct` is bound using a getter method and a setter method -that must be `native` and annotated with the bro `@StructMember` annotation. -The `@StructMember` annotation specifies the index of the member in the -`struct`. The getter method must take 0 parameters and return some value while -the setter method must take 1 parameter of the same type as the getter -returns. The return type for the setter must either be `void` or the `Struct` -class it belongs to. - -TIP: The names of the getter and setter methods don't have to follow the Java -Beans style convention for Java Beans properties. - -TIP: If the setter method is declared as returning an instance of the `Struct` -class it belongs to the Bro compiler will make it return `this` making it -possible to chain setter method calls. - -.Example struct: -The C `struct timeval` -[source,c] ----- -struct timeval { - time_t tv_sec; /* seconds since Jan. 1, 1970 */ - suseconds_t tv_usec; /* and microseconds */ -}; ----- -can be bound like this using Bro in RoboVM: -[source,java] ----- -public class Timeval extends Struct { - @StructMember(0) public native int tv_sec(); - @StructMember(0) public native Timeval tv_sec(int i); - @StructMember(1) public native int tv_usec(); - @StructMember(1) public native Timeval tv_usec(int i); -} ----- -And used like this to call http://pubs.opengroup.org/onlinepubs/009695399/functions/gettimeofday.html[`gettimeofday()`]: -[source,java] ----- -@Bridge static native int gettimeofday(Timeval tp, VoidPtr tzp); -public static void main(String[] args) { - Timeval t = new Timeval(); - gettimeofday(t, null); - System.out.format("Seconds since epoch: %d\n", t.tv_sec()); -} ----- - -===== sizeof(struct) - -The size in bytes of a `Struct` can easily be queried by calling the static -`sizeOf()` method on the `Struct` sub-class: - -[source,java] ----- -public class CGRect extends Struct { ... } -System.out.format("sizeof(CGRect) = %d\n", CGRect.sizeOf()); ----- - -===== @ByRef and @ByVal - -The `@ByRef` and `@ByVal` annotations can be used to control how a `Struct` -object is returned from a method or passed as a parameter to a method. -`@ByRef` means pass as pointer and is the default. `@ByVal` means pass by -value. The default can be changed to `@ByVal` for a particular `Struct` class -by annotating the class with `@ByVal`: - -[source,java] ----- -@ByVal -public class Person extends Struct { ... } ----- - -===== Nested structs - -`Struct` classes can contain other `Struct` objects as members, either by -value or by reference (i.e. by pointer). The default is `@ByRef` with the same -possibilities to override the default as for methods. - -Below is an example of how the CocoaTouch `struct CGRect` type is mapped to -Java in the RoboVM Cocoa Touch bindings. A `CGRect` has two members: the -`origin` is a `CGPoint` `struct` and the `size` is a `CGSize` struct. - -.C: -[source,c] ----- -struct CGRect { - CGPoint origin; - CGSize size; -}; ----- -.Java: -[source,java] ----- -public class CGRect extends Struct { - public CGRect() {} - public CGRect(float x, float y, float width, float height) { - origin().x(x).y(y); - size().width(width).height(height); - } - public CGRect(CGPoint origin, CGSize size) { - origin(origin); - size(size); - } - @StructMember(0) public native @ByVal CGPoint origin(); - @StructMember(0) public native CGRect origin(@ByVal CGPoint origin); - @StructMember(1) public native @ByVal CGSize size(); - @StructMember(1) public native CGRect size(@ByVal CGSize size); -} ----- - -==== Unions - -A C `union` is bound just like a C `struct` but has overlapping -`@StructMember` indexes: - -.C: -[source,c] ----- -union TestUnion { - int i; - short s1; - short s2; -}; ----- -.Java: -[source,java] ----- -public class TestUnion extends Struct { - @StructMember(0) public native int i(); - @StructMember(0) public native TestUnion i(int i); - @StructMember(0) public native short s1(); - @StructMember(0) public native TestUnion s1(short s1); - @StructMember(0) public native short s2(); - @StructMember(0) public native TestUnion s2(short s2); -} ----- - -===== Native array members - -Bro provides the `@Array` annotation which is used to bind array struct -members. The `@Array` annotation specifies the dimensions of the member's -type. Space large enough to hold a native array of the specified type and -dimensions will be reserved inside the struct. - -Single-dimensional array: - -.C: -[source,c] ----- -struct Vector { - int values[3]; -}; ----- -.Java: -[source,java] ----- -public class Vector extends Struct { - @StructMember(0) - public native @Array(3) int[] values(); - @StructMember(0) - public native Vector values(@Array(3) int[] values); -} ----- - -Multi-dimensional array: - -.C: -[source,c] ----- -struct Matrix { - int values[1, 2, 3]; -}; ----- -.Java: -[source,java] ----- -public class Matrix extends Struct { - @StructMember(0) - public native @Array({1, 2, 3}) int[][][] values(); - @StructMember(0) - public native Matrix values(@Array({1, 2, 3}) int[][][] values); -} ----- - -NOTE: The native data will be copied to and from the `int[]` and `int[][][]` -arrays in these examples. Changes in the Java arrays will not be directly -reflected in the native data. The setter has to be called to update the native -data. - -An alternative to using Java arrays is to use a sub-class of `java.nio.Buffer` -instead: - -Single-dimensional array: - -.C: -[source,c] ----- -struct Vector { - int values[3]; -}; ----- -.Java: -[source,java] ----- -public class Vector extends Struct { - @StructMember(0) - public native @Array(3) IntBuffer values(); - @StructMember(0) - public native Vector values(@Array(3) IntBuffer values); -} ----- - -Multi-dimensional array: - -.C: -[source,c] ----- -struct Matrix { - int values[1, 2, 3]; -}; ----- -.Java: -[source,java] ----- -public class Matrix extends Struct { - @StructMember(0) - public native @Array({1, 2, 3}) IntBuffer values(); - @StructMember(0) - public native Matrix values(@Array({1, 2, 3}) IntBuffer values); -} ----- - -NOTE: The buffer's `capacity()` will be restricted to the dimension of the -array. For multi-dimensional arrays this is the product of the dimensions, -1*2*3=6 for the `Matrix` example. - -A third option is to use one of the pointer classes in the -http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/package-summary.html[`org.robovm.rt.bro.ptr`] -package: - -Single-dimensional array: - -.C: -[source,c] ----- -struct Vector { - int values[3]; -}; ----- -.Java: -[source,java] ----- -public class Vector extends Struct { - @StructMember(0) - public native @Array(3) IntPtr values(); - @StructMember(0) - public native Vector values(@Array(3) IntPtr values); -} ----- - -Multi-dimensional array: - -.C: -[source,c] ----- -struct Matrix { - int values[1, 2, 3]; -}; ----- -.Java: -[source,java] ----- -public class Matrix extends Struct { - @StructMember(0) - public native @Array({1, 2, 3}) IntPtr values(); - @StructMember(0) - public native Matrix values(@Array({1, 2, 3}) IntPtr values); -} ----- - -It's also possible to have arrays of structs in a `Struct`: - -.C: -[source,c] ----- -struct Color { - char r; char g; char b; -}; -struct Gradient { - Color stops[3]; -}; ----- -.Java: -[source,java] ----- -public class Color extends Struct { ... } -public class Gradient extends Struct { - @StructMember(0) public native @Array(3) Color[] stops(); - @StructMember(0) public native Gradient stops(@Array(3) Color[] stops); -} ----- - -===== Unbounded native array members - -For unbounded native array members one should use one of the pointer classes -in the -http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/package-summary.html[`org.robovm.rt.bro.ptr`] -package combined with the `@ByVal` annotation: - -.C: -[source,c] ----- -struct PascalString { - int length; - char chars[]; -}; ----- -.Java: -[source,java] ----- -public class PascalString extends Struct { - @StructMember(0) public native int length(); - @StructMember(0) public native PascalString length(int length); - @StructMember(0) public native @ByVal BytePtr chars(); -} ----- - -NOTE: There's no setter for the `chars` member as that would have required the -length to be known at compile time. Setting the individual bytes of `chars` -has to be done through the `BytePtr` returned by the getter. - -===== Struct memory handling - -When creating an instance of a `Struct` class Bro actually allocates two -memory regions: one for the Java object and one for the actual struct data. -The default is to allocate the struct data on the Java heap. There are two way -to make sure that the underlying struct data is allocated on the GCed heap: - -[source,java] ----- -CGRect r = new CGRect(); -CGRect r = Struct.allocate(CGRect.class); ----- - -This means that the data will be garbage collected when the garbage collector -determines that the struct data isn't referenced from any other memory -allocated on the garbage collected heap. - -Allocating struct data on the GCed heap won't work for native code that holds -on to a pointer to the struct data beyond a Java call into a native function -since the native heap is not searched by the garbage collector. If the native -side assumes ownership of the data and later frees it by a call to `free()` -the Java side has to use `malloc()` to allocate it on the native heap: - -[source,java] ----- -CGRect r = Struct.malloc(CGRect.class); ----- - -CAUTION: If the native side holds on to a memory region allocated on the GCed -heap care must be taken on the Java side to make sure that the memory isn't -collected until the native side is done with it. As long as the Java `Struct` -instance is referenced on the Java side the struct data can't be collected. - -TIP: The memory region allocated to hold a struct's data will always be zeroed -out regardless of whether using the Java heap or the native heap. - -==== Native arrays - -This allocates an array of 10 `CGRect` instances: - -[source,java] ----- -public class CGRect extends Struct { ... } -CGRect l = Struct.allocate(CGRect.class, 10); ----- - -This allocates a contiguous memory region big enough to hold 10 `CGRect` -instances. The `Struct` class defines a number of methods that can be used to -iterate over these, e.g. -http://apidocs.robovm.com/latest/org/robovm/rt/bro/Struct.html#next()[`next()`] -and -http://apidocs.robovm.com/latest/org/robovm/rt/bro/Struct.html#previous()[`previous()`]. -`Struct` also implements the `Iterable` interface: - -[source,java] ----- -for (CGRect r : l) { - ... - if () { - break; - } -} ----- - -CAUTION: The `Iterator` used when `for`-looping like this is unbounded so a -`break` is required to finish the loop. - -The -http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/BytePtr.html[`BytePtr`] -class and the other pointer classes in -http://apidocs.robovm.com/latest/org/robovm/rt/bro/ptr/package-summary.html[`org.robovm.rt.bro.ptr`] -are in fact `Struct` classes so to allocate a native array of 100 `int` values -one could do: - -[source,java] ----- -IntPtr myInts = Struct.allocate(IntPtr.class, 100); ----- - -==== Enums - -Simple C `enum` constants are mapped using Java `Enum` types which implement -the bro -http://apidocs.robovm.com/latest/org/robovm/rt/bro/ValuedEnum.html[`ValuedEnum`] -interface. Here's an example: - -.C: -[source,c] ----- -enum { - NSTextAlignmentLeft, - NSTextAlignmentCenter, - NSTextAlignmentRight, - NSTextAlignmentJustified, - NSTextAlignmentNatural -}; ----- - -.Java: -[source,java] ----- -public enum NSTextAlignment implements ValuedEnum { - Left(0), Center(1), Right(2), - Justified(3), Natural(4); - - private final long n; - - private NSTextAlignment(long n) { this.n = n; } - public long value() { return n; } - public static NSTextAlignment valueOf(long n) { - for (NSTextAlignment v : values()) { - if (v.n == n) { - return v; - } - } - throw new IllegalArgumentException( - "No constant with value " + n + " found in " - + NSTextAlignment.class.getName()); - } -} ----- - -By default Bro marshals a `ValuedEnum` as a signed 32-bit value. The default -can be changed by specifying an explicit `@Marshaler` on the enum type. Here's -how to marshal `NSTextAlignment` values as platform dependent (32-bit on -32-bit platforms, 64-bit on 64-bit platforms) signed integer values: - -.Overriding the default marshaler for a `ValuedEnum`: -[source,java] ----- -@Marshaler(ValuedEnum.AsMachineSizedSIntMarshaler.class) -public enum NSTextAlignment implements ValuedEnum { - ... -} ----- - -There are `ValuedEnum` marshalers for marshaling signed and unsigned 8-, 16-, -32- and 64-bit integer values. They are all available as http://apidocs.robovm.com/latest/org/robovm/rt/bro/ValuedEnum.html[inner classes in the -`ValuedEnum` interface]. - -TIP: The `@Marshaler` annotation can also be placed on a particular method return -type or parameter type to only change the marshaler for that specific value. - -==== Bits - -Bro provides a class called -http://apidocs.robovm.com/1.0.0-SNAPSHOT/org/robovm/rt/bro/Bits.html[`Bits`] -that can be used to bind bitmask constants: - -.C: -[source,c] ----- -enum { - UIPopoverArrowDirectionUp = 1UL << 0, - UIPopoverArrowDirectionDown = 1UL << 1, - UIPopoverArrowDirectionLeft = 1UL << 2, - UIPopoverArrowDirectionRight = 1UL << 3, - ... -}; ----- - -.Java: -[source,java] ----- -public final class UIPopoverArrowDirection - extends Bits { - - public static final UIPopoverArrowDirection None = - new UIPopoverArrowDirection(0L); - public static final UIPopoverArrowDirection Up = - new UIPopoverArrowDirection(1L); - public static final UIPopoverArrowDirection Down = - new UIPopoverArrowDirection(2L); - public static final UIPopoverArrowDirection Left = - new UIPopoverArrowDirection(4L); - public static final UIPopoverArrowDirection Right = - new UIPopoverArrowDirection(8L); - ... - - private static final UIPopoverArrowDirection[] values = - _values(UIPopoverArrowDirection.class); - - public UIPopoverArrowDirection(long value) { super(value); } - private UIPopoverArrowDirection(long value, long mask) { - super(value, mask); - } - protected UIPopoverArrowDirection wrap(long value, long mask) { - return new UIPopoverArrowDirection(value, mask); - } - protected UIPopoverArrowDirection[] _values() { - return values; - } - public static UIPopoverArrowDirection[] values() { - return values.clone(); - } -} ----- - -`Bits` values can be ORed using the `Bits.with(...)` methods in a manner very -similar to how `java.util.EnumSet.of(...)` works: - -.C: -[source,c] ----- -int upDown = UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown; ----- - -.Java: -[source,java] ----- -UIPopoverArrowDirection upDown = UIPopoverArrowDirection.with( - UIPopoverArrowDirection.Up, UIPopoverArrowDirection.Down); ----- - -TIP: `Bits` types is the preferred way to bind bitmasks since it provides some -degree of type-safety and an easier to understand API. It does however impose -a performance penalty compared to using `public static final` constants. - -By default Bro marshals a `Bits` instance as an unsigned 32-bit value. The -default can be changed by specifying an explicit `@Marshaler` on the class. -Here's how to marshal `UIPopoverArrowDirection` values as platform dependent -(32-bit on 32-bit platforms, 64-bit on 64-bit platforms) unsigned integer -values: - -.Overriding the default marshaler for a `Bits`: -[source,java] ----- -@Marshaler(Bits.AsMachineSizedIntMarshaler.class) -public final class UIPopoverArrowDirection - extends Bits { - ... -} ----- - -There are `Bits` marshalers for marshaling unsigned 8-, 16-, 32- and 64-bit -integer values. They are all available as -http://apidocs.robovm.com/latest/org/robovm/rt/bro/Bits.html[inner -classes in the `Bits` interface]. - -TIP: The `@Marshaler` annotation can also be placed on a particular method return -type or parameter type to only change the marshaler for that specific value. - -==== Native functions - -==== Global values - -==== Callback methods - -==== Type marshalers - -Type marshalers are used by Bro to convert from native types into Java types -and vice versa. - -===== Marshaler lookup - -===== Value marshalers - -===== Array marshalers - -===== Pointer marshalers - -Pointer marshalers marshal pointers to native objects to/from some Java object -that wraps that pointer. The general contract for a pointer marshaler class -looks like this: - -[source,java] ----- -public class MyTypeMarshaler { - @MarshalsPointer - public static MyType toObject(Class cls, long handle, long flags) { - ... - } - @MarshalsPointer - public static long toNative(MyType o, long flags) { - ... - } -} ----- - -This marshaler marshals `MyType` instances to/from native pointers (`handle`). -Bro uses the signatures of the `@MarshalsPointer` methods to determine whether -it is a method which marshals Java->native or native->Java. The Java type it -can handle is determined by the signature (`MyType` in this case). - -The `cls` parameter specifies the actual `Class` used at the marshaling site. -The passed in `Class` is assignment compatible with the `MyType` class or -interface. - -The `flags` parameter gives some information on the call site. The possible -values are defined by -http://apidocs.robovm.com/latest/org/robovm/rt/bro/MarshalerFlags.html[`MarshalerFlags`] -class. - -TIP: Marshaler method names are unimportant, the signatures are what matters. - -===== Builtin marshalers - -==== Binding linked in libraries - -==== Binding Objective-C - -==== Objective-C/Java Memory Management - -==== The bro-gen tool \ No newline at end of file diff --git a/src/main/asciidoc/advanced-command-line-usage.adoc b/src/main/asciidoc/advanced-command-line-usage.adoc deleted file mode 100644 index da3567f..0000000 --- a/src/main/asciidoc/advanced-command-line-usage.adoc +++ /dev/null @@ -1,133 +0,0 @@ -[id="command-line-usage"] -=== Command Line Usage - -This section describes how to carry out some of the most common actions using -the `robovm` command line tool. For a complete usage reference for the options -supported by the `robovm` tool run - -[source,bash] ----- -$ robovm -help ----- - -==== Working with robovm.xml files - -Almost everything can be done directly from the command line using the -options of the `robovm` command but it is still recommended to use an -<> called `robovm.xml` to configure -the compiler. - -The `-dumpconfig` option can be used to create a `robovm.xml` file. This -creates a `robovm.xml` file for the demo app in <>: - -[source,bash] ----- -$ robovm -arch thumbv7 -os ios -cp "$ROBOVM_HOME/lib/robovm-objc.jar:$ROBOVM_HOME/lib/robovm-cocoatouch.jar:bin/" -dumpconfig robovm.xml IOSDemo ----- - -Once we have the `robovm.xml` file we only have to specify it on the command -line to launch the app. This would launch the app on a connected device since -the `robovm.xml` file specifies the `thumbv7` architecture: - -[source,bash] ----- -$ robovm -config robovm.xml -run ----- - -TIP: You can load multiple configurations by specifying `-config` multiple -times. The latter ones take precedence. - -We can override the configuration read from a `robovm.xml` file by specifying the options we want to override after the `robovm.xml` file has been read in. To launch on the iOS simulator we need to build for the `x86` architecture so we use the `-arch` option *after* the configuration file has been specified: - -[source,bash] ----- -$ robovm -config robovm.xml -arch x86 -run ----- - -We can even "edit" the `robovm.xml` file by combining `-config` and `-dumpconfig`. This adds a new classpath entry: - -[source,bash] ----- -$ robovm -config robovm.xml -cp foo.jar -dumpconfig robovm-new.xml -$ mv robovm-new.xml robovm.xml ----- - -==== Expanding properties in robovm.xml files - -XML configuration files (and also `Info.plist` files) will be searched for `${...}` patterns. Such patterns will be replaced with properties loaded using the `-properties` command line option which reads in `.properties` file. Individual properties can also be specified directly on the command line using the `-Pname=value` option. - -==== Launching apps - -To launch an app using the command line tool you simply specify the `-run` -command line option. RoboVM will use the configured target OS (`-os`) and -architecture (`-arch`) to determine how to launch the app. - -To launch in the iOS simulator use `-os ios` `-arch x86`: - -[source,bash] ----- -$ robovm -cp ... -os ios -arch x86 -run com.example.MainClass ----- - -To launch on an iOS device in 32-bit mode use `-os ios` `-arch thumbv7`: - -[source,bash] ----- -$ robovm -cp ... -os ios -arch thumbv7 -run com.example.MainClass ----- - -To launch on an iOS device in 64-bit mode use `-os ios` `-arch arm64`: - -[source,bash] ----- -$ robovm -cp ... -os ios -arch arm64 -run com.example.MainClass ----- - -RoboVM also supports building Mac OS X console apps. This is what you get if -you don't specify any `-os` or `-arch` (or use `-os macosx` `-arch x86`): - -[source,bash] ----- -$ robovm -cp ... -run com.example.MainClass ----- - -==== Packaging for App Store/Ad-Hoc distribution - -The `-createipa` option is used to create an -http://en.wikipedia.org/wiki/.ipa_(file_extension)[IPA file] which can be -submitted to the App Store or distributed to beta tester or throughout an -enterprise. - -NOTE: Before you can do this you will have to have your signing certificates -and provisioning profiles in order. Apple has some -https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40012582-CH1-SW1[great -resources] that describe how to enroll in the iOS developers program and -create the certificates and provisioning profiles required for App Store -distribution. - - -This will create an IPA file signed with the code signing certificate matching -_iPhone Distribution_ and using the provisioning profile named __My -Distribution Profile__. The IPA will be stored in `~/Desktop/IPA/`: - -[source,bash] ----- -$ robovm -config robovm.xml -signidentity 'iPhone Distribution' -provisioningprofile 'My Distribution Profile' -d ~/Desktop/IPA/ -createipa ----- - -TIP: The `-signingidentiy` option matches against the start of the certificate -name. Alternatively you can use a certificate fingerprint. If the -`-signingidentiy` value is enclosed in `/` a regexp search will be done -against the certificate name instead. Run the command `security find-identity --v -p codesigning` or use the _KeyChain Access_ OS X app to view your -installed certificates. - -CAUTION: The IPA creation also creates a `.dSYM` folder in the folder you -specify with `-d`. The `.dSYM` contains the debug symbols of your app. It is -required if you want to symbolicate a crash report generated by your app. To -symbolicate you need the exact `.dSYM` so *make sure you back this up*. - -The IPA is now ready to be distributed. To submit the IPA file to the App -Store you would use the _Application Loader_ application that comes with -Xcode. The _Application Loader_ application can easily be located using -_Spotlight_. \ No newline at end of file diff --git a/src/main/asciidoc/advanced-topics.adoc b/src/main/asciidoc/advanced-topics.adoc deleted file mode 100644 index 7df27c8..0000000 --- a/src/main/asciidoc/advanced-topics.adoc +++ /dev/null @@ -1,12 +0,0 @@ -== Avanced Topics -This section covers advanced topics. - -include::advanced-under-the-hood.adoc[] - -include::advanced-using-ram-disks.adoc[] - -include::advanced-using-nightly-builds.adoc[] - -include::advanced-bro.adoc[] - -include::advanced-command-line-usage.adoc[] \ No newline at end of file diff --git a/src/main/asciidoc/advanced-under-the-hood.adoc b/src/main/asciidoc/advanced-under-the-hood.adoc deleted file mode 100644 index dcf7d49..0000000 --- a/src/main/asciidoc/advanced-under-the-hood.adoc +++ /dev/null @@ -1,74 +0,0 @@ -=== Under the hood - - -==== The bytecode compiler - -At the heart of RoboVM is its -http://en.wikipedia.org/wiki/Ahead-of-time_compilation[ahead-of-time -compiler]. This is a tool that can be invoked either from the command line -(see <>), from build tools such as Maven (see -<>) or Gradle or from an IDE (such as -<>). It takes Java bytecode and -translates it into machine code for a specific operating system and CPU type. -Usually this means iOS and the ARM processor type but RoboVM is also capable -of generating code for Mac OS X and Linux running on x86 CPUs. - -The ahead-of-time approach is very different from how traditional JVMs, like -http://en.wikipedia.org/wiki/HotSpot[Oracle’s Hotspot], usually work. Such -JVMs typically read in Java bytecode at runtime and somehow execute the -virtual machine instructions contained in the bytecode. To speed up this -process the JVM employs a technique called -http://en.wikipedia.org/wiki/Just-in-time_compilation[just-in-time -compilation]. In simple terms this process translates the virtual machine -instructions of a method to native machine code for the current physical CPU -the first time the method is invoked by the program. - -Due to technical restrictions that Apple has built into iOS just-in-time -compilation of any kind is impossible in an iOS app. The only alternatives are -to use an interpreter, which is too slow and power consuming, or use -ahead-of-time compilation like in RoboVM. The ahead-of-time compilation -process takes place at compile time on the developer machine so at runtime, on -an iOS device, the generated machine code runs at full speed, comparable to or -even faster than code compiled from Objective-C. - -By consuming Java bytecode rather than Java source code the RoboVM -ahead-of-time compiler can, at least in theory, be used with any JVM language -that compiles down to bytecode. Scala, Clojure and Kotlin are JVM languages -already known to work. Another benefit with this approach is that RoboVM can -be used with 3rd party libraries in standard JAR files without any need for -the original source code enabling the use of proprietary and closed-source -libraries. - -==== Incremental compilation - -The first launch of a RoboVM app, even an app as simple as the `IOSDemo` app we -saw in <>, takes some time. When compiling an app the RoboVM -compiler starts with the app’s main class. It will then compile all classes -needed by the main class and then the classes needed by those classes and so -on until all classes needed by the app have been compiled. This process also -compiles the standard runtime classes such as `java.lang.Object` and -`java.lang.String`. This is a one-time thing only. RoboVM keeps a cache of -compiled classes and only recompiles a class when it or any of its direct -dependencies have changed. - -TIP: By default RoboVM uses `$HOME/.robovm/cache/` as the cache folder. By -deleting this folder you can force RoboVM to recompile all classes from -scratch. - -The benefit of incremental compilation and caching of the object files is that -it keeps down compile times. By only including the classes reachable from the -main class it also keeps down the size of the produced executable. In some -situations (e.g. when loading classes using reflection) the RoboVM compiler is -unable to determine that a class should be compiled. Fortunately the compiler -can be instructed to always <>. - -==== Android-based runtime class library - -Any JVM needs a runtime class library. This is the library which provides the -standard packages and classes needed by any Java program such as -`java.lang.Object` and `java.lang.String`. RoboVM takes its runtime class library -from the Android open-source project and all non-Android specific packages -have been ported over to RoboVM. This means that any Java or JVM language code -that only uses classes in the standard packages provided on Android should -work the same under RoboVM. \ No newline at end of file diff --git a/src/main/asciidoc/advanced-using-ram-disks.adoc b/src/main/asciidoc/advanced-using-ram-disks.adoc deleted file mode 100644 index cc36d68..0000000 --- a/src/main/asciidoc/advanced-using-ram-disks.adoc +++ /dev/null @@ -1,27 +0,0 @@ -[id="ram disks"] -=== Using RAM disks -RoboVM can be taxing for slow HDDs in old Mac Minis and MacBooks. You can -speed up the compilation and linking process by creating a RAM disk as -follows: - -[source,bash] ------- -SIZE=2048 ; diskutil erasevolume HFS+ 'RoboVM RAM Disk' `hdiutil attach -nomount ram://$((SIZE * 2048))` ------- - -This will mount a RAM disk using 2GB of memory under `/Volumes/RoboVM RAM -Disk`. RoboVM will then use this RAM disk for its cache, which normally lives -under `~/.robovm`. - -The RAM disk feature will ensure that at least 400MB are available on the RAM -disk by deleting those files that are least likely to contribute to the -current build, e.g. files for a different architecture and OS. If your build -requires more than 400MB, you can either increase the RAM disk size, or delete -files under `/Volume/RoboVM RAM Disk` manually. - -To remove your RAM disk, open Finder, then click the unmount button next to -`RoboVM RAM Disk`. - -[[img-using-ram-disks-unmount]] -.Unmounting a RAM disk -image::using-ram-disks-unmount.png[] \ No newline at end of file diff --git a/src/main/asciidoc/configuration-reference.adoc b/src/main/asciidoc/configuration-reference.adoc deleted file mode 100644 index b4b9195..0000000 --- a/src/main/asciidoc/configuration-reference.adoc +++ /dev/null @@ -1,680 +0,0 @@ -[id=config-reference] -== Configuration Reference - -The recommended way to build RoboVM apps is to use a `robovm.xml` file to -configure the compiler. This section lists the supported elements and also the -corresponding <> options (if any). - -The `robovm.xml` file is usually accompanied by a `robovm.properties` file. -The `robovm.xml` file will be searched for these properties and any matches -will be replaced with the actual value from the properties file. Properties -are referenced using the same `${...}` syntax as used by Maven, Gradle and -Ant. Here's and example: - -.robovm.properties -[source] -app.executable=IOSDemo -app.name=IOSDemo - -.robovm.xml -[source,xml] - - ${app.executable} - ${app.mainclass} - ios - thumbv7 - - - resources - - - ios - Info.plist.xml - - -NOTE: All relative paths specified in a `robovm.xml` file will be resolved -relative to the file itself. - -=== - -Specifies where to install the generated executable and other files. The -default is `/`. For iOS apps the app will always -be created in a sub-folder in the specified `` folder named like -the `CFBundleExecutable` value in the app´s `Info.plist.xml` file and with -`.app` appended. - -.Example: -[source,xml] -target/MyApp - -.Command line usage: -`-d ` - -=== - -Specifies the name of the executable to be generated. - -.Example: -[source,xml] -MyAppExe - -.Command line usage: --o - -=== - -Specifies whether to use dynamic JNI. With this enabled native methods will be -dynamically linked at runtime. Native methods in classes in the boot classpath -will always use static JNI. On iOS only static JNI is supported and this -option is ignored. The default is `false`. - -.Example: -[source,xml] -true - -.Command line usage: -`-dynamic-jni` - -=== - -Specifies whether the default `robovm-rt.jar` should be automatically added to the bootclasspath. The default is `true` - -.Example: -[source,xml] -false - -.Command line usage: -`-skiprt` - -=== - -This is the equivalent of the `-jar` command line option to the `java` -command. The jar file will be added to the classpath and RoboVM will use the -`Main-Class` set in the `META-INF/MANIFEST.MF` file in the jar file as -`` value. Either this or `` must be specified. - -.Example: -[source,xml] -lib/my-app.jar - -.Command line usage: -`-jar ` - -=== - -Specifies the fully-qualified name of the class containing the -`main(String[])` method that will be called when starting the app. Either -this or `` must be specified. - -.Example: -[source,xml] -com.example.MyApp - -.Command line usage: -Specified after all RoboVM compiler options but before any program options. - -=== - -Specifies the cacerts file to be included in the app. RoboVM includes the same -CA cerificates as included in Android 4.4.3. Allowed values are `none` and -`full`. Default is `full` but no cacerts will be included unless the code -actually needs them. - -.Example: -[source,xml] -none - -.Command line usage: -`-cacerts ` - -=== - -Specifies the name of the OS to build for. Allowed values are `auto`, `linux`, -`macosx` and `ios`. Default is `auto` which normally means to build for the -current host OS. - -.Example: -[source,xml] -ios - -.Command line usage: -`-os ` - -=== - -Specifies the name of the CPU architecture to compile for. Allowed values are -`auto`, `x86`, `x86_64`, `thumbv7`, `arm64`. Default is `auto` which normally -means to build for the current host's CPU architecture. - -.Example: -[source,xml] -thumbv7 - -.Command line usage: -`-arch ` - -=== - -Contains `` elements listing class patterns matching classes that -must be linked in even if not referenced (directly or indirectly) from the -main class. If no main class is specified all classes will be linked in unless -this option has been given. Patterns are specified using an ANT style path -syntax with the following rules: - -* `?` matches one character. -* `*` matches zero or more characters. -* `**` matches zero or more packages in a fully-qualified class name. - -An alternative syntax using `#` is also supported. This is useful when -specifying patterns on the command line as it prevents the shall from -expanding `*` characters. - -.Example: -[source,xml] - - com.android.okhttp.HttpHandler - com.android.okhttp.HttpsHandler - com.android.org.conscrypt.** - - -.Command line usage: -`-forcelinkclasses ` - -NOTE: `-forcelinkclasses` can either be specified multiple times on the -command line, each specifying a single pattern or specified once with multiple -`:` separated patterns. E.g. `-forcelinkclasses -'com.example.Foo:com.example.bar.**'`. - -=== - -Specifies, in nested `` elements, static libraries (with extension `.a`), -object files (with extension `.o`) and system libraries that should be -included when linking the final executable. - -If `force="true"` has been specified for a `` poining at a static library -the entire static library will be linked in regardless of whether the symbols -in it are referenced by the rest of the app's code or not. This uses the -`-force_load` command line linker option when building for Mac OS X and iOS -and `--whole-archive` when building for Linux. The default is `force="true"`. - -.Example: -[source,xml] - - lib/libfoo.a - lib/myobjectfile.o - curl - - -.Command line usage: -`-libs ` - -NOTE: `-libs` can either be specified multiple times on the command line, each -specifying a single value or specified once with multiple `:` separated -values. E.g. `-libs 'lib/libfoo.a:curl'`. - -CAUTION: There's no way to specify `force="false"` when using `-libs` from the -command line. Use a `robovm.xml` file instead. - -=== - -Specifies, in nested `` elements, symbols that should be exported when -linking the executable. This can be used when linking in functions which will -be called using <>. Wildcards can be used to match symbols: - -* `*` matches zero or more characters, -* `?` matches one character. -* `[abc]`, `[a-z]` matches one character from the specified set of characters. - -.Example: -[source,xml] - - CB* - sin - - -.Command line usage: -`-exportedsymbols ` - -NOTE: `-exportedsymbols` can either be specified multiple times on the command line, each -specifying a single value or specified once with multiple `:` separated -values. E.g. `-exportedsymbols 'CB*:sin'`. - -=== - -Specifies, in nested `` elements, Mac OS X or iOS frameworks that -should be linked against when linking the final executable. - -.Example: -[source,xml] - - CoreImage - UIKit - - -.Command line usage: -`-frameworks ` - -NOTE: `-frameworks` can either be specified multiple times on the command -line, each specifying a single value or specified once with multiple `:` -separated values. E.g. `-frameworks 'CoreImage:UIKit'`. - -=== - -Specifies, in nested `` elements, Mac OS X or iOS frameworks that -should be weakly linked against when linking the final executable. Weakly -linking against a framework means that all symbols in the framework will be -marked as weakly linked. This allows apps to be built against one version of a -framework which defines a particular symbol and later run against a different -version of that framework which doesn't have that symbol defined. If that -symbol had been strongly linked the app would immediately crash at launch. - -.Example: -[source,xml] - - AdSupport - StoreKit - - -.Command line usage: -`-weakframeworks ` - -NOTE: `-weakframeworks` can either be specified multiple times on the command -line, each specifying a single value or specified once with multiple `:` -separated values. E.g. `-weakframeworks 'CoreImage:UIKit'`. - -=== - -Specifies, in nested `` elements, framework search paths used when -searching for custom frameworks. - -.Example: -[source,xml] - - lib/frameworks - - -.Command line usage: -`-frameworkpaths ` - -NOTE: `-frameworkpaths` can either be specified multiple times on the command -line, each specifying a single value or specified once with multiple `:` -separated values. E.g. `-frameworkpaths 'lib/frameworks:../frameworks'`. - -=== - -Specifies files and directories that should be copied to the installation -directory. A resource can be specified using a single path: - -.Example: -[source,xml] - - path/to/the/resource.txt - - -NOTE: If the path specifies a directory, that directory including its contents -(except for the default excludes, see below) will be copied. If the path -specifies a file, that file will be copied directly to the installation directory. - -A resource be also be specified with a base directory, a target path and include and exclude -filters (similar to Maven's `` element): - -.Example: -[source,xml] - - - data - resources - - **/* - - - **/*.bak - - false - false - false - - - -==== - -The target path relative to the installation directory (i.e. app bundle -directory for iOS apps) where paths matching this `` will be copied. -If not specified paths will be copied directly to the installation directory. - -==== - -The base directory containing the files and directories copied by the -``. - -==== - -Specifies one or more Ant-style patterns (using `**`, `*` and `?` as -wildcards) matching files which will be included when copying this -``. - -==== - -Specifies one or more Ant-style patterns (using `**`, `*` and `?` as -wildcards) matching files which will be excluded when copying this -``. - -==== - -Set to `true` if the files matched by this `` should be copied -directly into the installation directory without preserving the directory -structure of the source directory. The default is `false`. - -==== - -Set to `true` if the <> should be ignored -and copied for this ``. The default is `false`, i.e. don't copy -files matching the default excludes. - -==== - -Set this to `true` if `pngcrush` should not be called for PNG files matching -this `` when targeting iOS. The default is `false`, -i.e. `pngcrush` WILL be called for PNG files. - -NOTE: Depending on the target (iOS, Mac OS X or Linux) resources may be -transformed and renamed while being copied (e.g. running `pngcrush` or -converting `xib` files to `nib` files). - -[id="resourceprocessing"] -==== Resource processing - -By default, any resources found in the specified resource paths will be copied -to the installation directory. However, there exist several specific files and folders -that need to be processed first before they can be used in an iOS application. + -The following sections explain which resources will be automatically processed -for you and what they are used for. - -===== .xcassets folders - -`.xcassets` folders, also known as `Asset Catalogs`, contain graphical assets grouped -into several subfolders, also known as `Sets`. Each set contains several image files along with a `Contents.json` -file that describes the images. + -The following types of sets are supported: - -.imageset:: If your app has a deployment target of iOS 7 or higher images -in this set will be converted into a runtime binary format to reduce the overall -app size. Otherwise they will simply be copied to the install directory. + -You can access an image by its name with `UIImage.create(String)`. -AppIcon.appiconset:: Images in this set will be used as the app icon of the iOS app. -LaunchImage.launchimage:: Images in this set will be used as the launch image -of the iOS app. - -===== .atlas folders - -`.atlas` folders contain several graphic files that will be merged into one or -multiple texture atlases. The result is a `.atlasc` folder named after the resource -folder that contains the texture atlas image files and a property list file with the -coordinates to all texture regions. + -The resulting texture atlas can be used via SpriteKit's `SKTextureAtlas` or -manually by reading the files. - -NOTE: Texture atlas generation can be configured with the <> element. - -[id="defaultexcludes"] -==== Default excludes - -(The same as those used by Ant 1.9) - -.Miscellaneous typical temporary files -[cols="5"] -|=== -|+**/*~+ -|+**/#*#+ -|+**/.#*+ -|+**/%*%+ -|+**/._*+ -|=== - -.CVS -[cols="3"] -|=== -|+**/CVS+ -|+**/CVS/**+ -|+**/.cvsignore+ -|=== - -.SCCS -[cols="2"] -|=== -|+**/SCCS+ -|+**/SCCS/**+ -|=== - -.Visual SourceSafe -[cols="1"] -|=== -|+**/vssver.scc+ -|=== - -.Subversion -[cols="2"] -|=== -|+**/.svn+ -|+**/.svn/**+ -|=== - -.Git -[cols="5"] -|=== -|+**/.git+ -|+**/.git/**+ -|+**/.gitattributes+ -|+**/.gitignore+ -|+**/.gitmodules+ -|=== - -.Mercurial -[cols="6"] -|=== -|+**/.hg+ -|+**/.hg/**+ -|+**/.hgignore+ -|+**/.hgsub+ -|+**/.hgsubstate+ - -|+**/.hgtags+ -|=== - -.Bazaar -[cols="3"] -|=== -|+**/.bzr+ -|+**/.bzr/**+ -|+**/.bzrignore+ -|=== - -.Mac -[cols="1"] -|=== -|+**/.DS_Store+ -|=== - -.Command line usage: -`-resources ` - -NOTE: `-resources` can either be specified multiple times on the command line, each -specifying a single value or specified once with multiple `:` separated -values. E.g. `-resources '+resources/**:data/*+'`. - -CAUTION: If a pattern is specified on the command line using `-resources` the -longest non-pattern path before the first wildcard will be used as base -directory and will not be recreated in the installation directory. E.g. with -the pattern `+resources/**+` all files and folders in the folder named -`resources` will be copied directly to the installation directory. - -[id="tools"] -=== - -Specifies, in nested elements, additional configuration options for various command -line tools that are used to process Cocoa-specific resources. -For a list of resource types that get processed see <>. - -==== - -Specifies configuration options for the `TextureAtlas` tool. -This tool is used for processing `.atlas` folders with image files into valid -texture atlases. - -.Example: -[source,xml] - - - RGBA8888_PNG - 2048x2048 - true - - - -===== - -Specifies the output format of the resulting texture atlas. + -Can be any of the following: - -* RGBA8888_PNG (default) -* RGBA8888_COMPRESSED -* RGBA4444_COMPRESSED -* RGBA5551_COMPRESSED -* RGB565_COMPRESSED - -===== - -Specifies the maximum allowed dimension of the resulting texture atlas. + -Can be any of the following: - -* 2048x2048 (default) -* 4096x4096 - -===== - -Specifies whether the dimensions of the resulting texture atlas should be power -of 2. Default is `false`. - -=== - -Specifies, in nested `` elements, directories, JAR archives, -and ZIP archives to search for class files to be compiled by the RoboVM -compiler. Classes in these entries will be loaded by the boot classloader at -runtime. Used to locate the `+java.*+` and `+javax.*+` classes. Default is -`/lib/robovm-rt.jar`. - -.Example: -[source,xml] - - path/to/my/robovm-rt.jar - - -.Command line usage: -`-bootclasspath ` -`-bootcp ` -`-bcp ` - -NOTE: `-bootclasspath` can either be specified multiple times on the command -line, each specifying a single value or specified once with multiple `:` -separated values. - -CAUTION: When running RoboVM in an IDE like Eclipse or from a build tool such -as Maven or Gradle the `` and `` elements in the -`robovm.xml` file will be ignored. Instead the classpaths of the IDE or build -tool with be used. - -=== - -Specifies, in nested `` elements, directories, JAR archives, -and ZIP archives to search for class files to be compiled by the RoboVM -compiler. Classes in these entries will be loaded by the system classloader at -runtime. - -.Example: -[source,xml] - - target/classes - lib/commons-lang.jar - - -.Command line usage: -`-classpath ` -`-cp ` - -NOTE: `-classpath` can either be specified multiple times on the command line, -each specifying a single value or specified once with multiple `:` separated -values. - -CAUTION: When running RoboVM in an IDE like Eclipse or from a build tool such -as Maven or Gradle the `` and `` elements in the -`robovm.xml` file will be ignored. Instead the classpaths of the IDE or build -tool with be used. - -//// -=== -//// - -=== - -Specifies the target to build for. Either `auto`, `console` or `ios`. The default is -`auto` which means use `` to decide. - -.Example: -[source,xml] -ios - -.Command line usage: -`-target ` - -=== - -(*iOS only*) Specifies the version number of the iOS SDK to build against. If not specified -the latest SDK that can be found will be used. - -.Example: -[source,xml] -8.0 - -.Command line usage: -`-sdk ` - -=== - -(*iOS only*) `Info.plist` file to be used by the app. If not specified a -simple `Info.plist` will be generated with a `CFBundleIdentifier` based on the -`` or ``. - -.Example: -[source,xml] -plists/Info.plist - -.Command line usage: -`-plist ` - -TIP: The specified `Info.plist` file will be searched for `${...}` patterns -just like `robovm.xml` files are. Such patterns will be replaced by the -corresponding property, usually read from a `robovm.properties` file. - -=== - -(*iOS only*) Property list (`.plist`) file containing resource rules passed to -`codesign` when signing the app. - -.Example: -[source,xml] -plists/ResourceRules.plist - -.Command line usage: -`-resourcerules ` - -=== - -(*iOS only*) Property list (`.plist`) file containing entitlements passed to -`codesign` when signing the app. - -.Example: -[source,xml] -plists/Entitlements.plist - -.Command line usage: -`-entitlements ` diff --git a/src/main/asciidoc/getting-started-eclipse.adoc b/src/main/asciidoc/getting-started-eclipse.adoc deleted file mode 100644 index e9b730b..0000000 --- a/src/main/asciidoc/getting-started-eclipse.adoc +++ /dev/null @@ -1,151 +0,0 @@ -[id="getting-started-eclipse"] -=== Getting Started with Eclipse - -In this section you'll learn how to install Eclipse, install the RoboVM -Eclipse plugin, activate your commercial license, and create and run your -first iOS application. - -[id="install-eclipse"] -==== Installing Eclipse -With all the <> out of the way, proceed to download a recent Eclipse -build from https://www.eclipse.org/downloads/. Eclipse comes in many different -flavors, the _Eclipse IDE for Java Developers_ package is sufficient for -RoboVM development. Simply download the package, decompress it, and copy the -resulting folder int `/Applications/`. - -IMPORTANT: Eclipse *MUST* be run using Oracle’s Java SE 7 JDK or later. Apple’s -Java 6 JVM will not work. Running Eclipse itself in Java 7 is not the same as -adding a Java 7 JRE to Eclipe's _Installed JREs_ dialog in _Preferences_. To -check which Java version Eclipse is running in go to _Eclipse -> About -Eclipse_, then click _Installation Details_ and open the _Configuration_ tab. -Find the `java.version` property and make sure it is 1.7 or higher. - -IMPORTANT: The default max heap setting for Eclipse may be too low. In order -to increase it *you need to change the -Xmx setting used when launching -Eclipse*. To do this locate your Eclipse installation folder, right-click the -Eclipse file and select _Show Package Contents_. Open the `eclipse.ini` file -located in `Contents/MacOS` in a text editor and change the -Xmx value to 2G -or more. Restart Eclipse. - -[id="install-eclipse-plugin"] -==== Installing the Plugin - -With Eclipse <>, you ca now install the -RoboVM Eclipse plugin by selecting _Install New Software_ from the Eclipse -_Help_ menu, enter the following update site into the _Work with_ field and -click _Next_: - ----- -http://download.robovm.org/eclipse/ ----- - -[[img-eclipse-install-new-software]] -.Eclipse _Install New Software_ dialog -image::eclipse-install-new-software.png[] - -Follow the on-screen instructions until installation is complete and restart Eclipse. - -[id="eclipse-activate-license"] -==== Activating your License - -If you have http://www.robovm.com/pricing/[purchased a subscription] for one -of RoboVM's subscription plans, you have to active the license for use on your -computer. Activating the license will enable the features you purchased, such -as debugging support or Interface Builder integration. Select _License -Manager_ from the Eclipse _RoboVM_ menu and enter your license key. - -[[img-eclipse-license-key]] -.License Manager dialog -image::license-manager.png[] - -NOTE: A commercial license is not required to create RoboVM applications and -deploy them to the App Store. Commercial licenses add additional features and -services on top of the free core of RoboVM. For more information, visit our -http://www.robovm.com/pricing/[pricing page]. - -[id="eclipse-creating-a-project"] -==== Creating a Project - -You can now create your first RoboVM project! Select __File -> New -> RoboVM -iOS Project__. The project wizard will appear: - -[[img-eclipse-project-wizard]] -.New Project Wizard -image::eclipse-project-wizard.png[] - -Perform these steps to define your project: - -. Fill in your _Project Name_ -. Specify the package and name of your _Main Class_, e.g. _com.mycompany.myapp.Main_ -. Specify the _App Name_. This is the name used when your app is installed to an iOS device or simulator -. Specify the _App ID_. This must be a unique identifier, usually your package name -. Click _Finish_ - -==== Running & Debugging - -You can run or debug a RoboVM app on either the simulator or a -<> connected via USB, directly from within -Eclipse. Right click the project in the package or project view, select _Run -As_ or _Debug As_, then select which platform you want to run/debug the app -on. - -[[img-eclipse-run-debug]] -.Running & Debugging from within Eclipse -image::eclipse-run-debug.png[] - -NOTE: The first time you run your application on the simulator or the device, -RoboVM has to compile not only the classes of your app, but also any runtime -classes required by your code. This can take some time. The next time you -compile your app, RoboVM will only recompile the classes that have changed -since the last compilation. You can view RoboVM's progress in the RoboVM -console view. - -[[img-eclipse-debug-sim]] -.Debugging on the simulator in Eclipse -image::eclipse-debug-sim.png[] - -When starting you app in debug mode, you have the full debugging tools of -Eclipse at your disposal: you can set breakpoints, step into/out/over source -lines, inspect and set variables and even use http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.docuser%2Freference%2Fviews%2Fdisplay%2Fref-display_view.htm[Eclipse' display view] - -==== Unit Testing - -RoboVM supports running and debugging JUnit tests for console and simulator -apps. Let's add a new unit test to our project. - -Create a new source folder which will contain all your unit tests by right clicking the project and selecting __File -> New -> Source Folder__. In the dialog, enter `src/test/java`, then click _Finish_. Copy the following source code to your clipboard, then select the `src/test/java` folder in Eclipse and paste the clipboard contents. - -[source,java] ------ -import static org.junit.Assert.*; -import org.junit.Test; - -public class MyIOSUnitTest { - @Test - public void test() { - System.out.println(System.getProperty("os.name")); - System.out.println(System.getProperty("os.arch")); - fail("Not yet implemented"); - } -} ------ - -We have not yet added JUnit as a dependency to our project, so you will see compilation errors. Move your cursor somewhere on the line that reads `@Test` of the `MyIOSUnitTest.java` file, then press `CMD+1` and select _Add JUnit 4 libray to the build path_. - -You can now run this unit test by right clicking the `MyIOSUnitTest.java` file in Eclipse, then select _Run As_ or _Debug As_, followed by _iOS Simulator JUnit Test_. - -[[img-eclipse-unit-test]] -.Unit testing in Eclipse -image::eclipse-unit-test.png[] - -==== Deployment - -Once your are happy with your app and have tested it on multiple devices, it's time to publish it to the App Store. For this you need to create an http://en.wikipedia.org/wiki/.ipa_%28file_extension%29[iOSApplication Archive](IPA). To do so from within Ecipse, right click your project, then select _RoboVM Tools -> Package for Ad-hoc/App Store distribution..._. - -[[img-eclipse-deploy]] -.IPA export for ad-hoc and App Store distribution -image::eclipse-deploy.png[] - -Specify the output directory, your signing identiy and provisioning profile and click _Finish_. You will find a file with the extension `.ipa` in the output directory, which is ready to be uploaded to iTunes Connect via the Application Loader. - -NOTE: Please refer to https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html[Apple's documentation] on how to submit your application. diff --git a/src/main/asciidoc/getting-started-gradle.adoc b/src/main/asciidoc/getting-started-gradle.adoc deleted file mode 100644 index 25c2d20..0000000 --- a/src/main/asciidoc/getting-started-gradle.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[id="getting-started-gradle"] -=== Getting Started with Gradle -_Coming Soon_! - -NOTE: Please refer to the plugin's documentation on https://github.com/robovm/robovm-gradle-plugin[Github] \ No newline at end of file diff --git a/src/main/asciidoc/getting-started-idea.adoc b/src/main/asciidoc/getting-started-idea.adoc deleted file mode 100644 index 82fed62..0000000 --- a/src/main/asciidoc/getting-started-idea.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[id="getting-started-idea"] -=== Getting Started with Intellij IDEA/Android Studio -_Coming Soon_! - -NOTE: A preliminary Intellij IDEA plugin is https://plugins.jetbrains.com/plugin/7588?pr=idea[available]. It is a wrapper around the RoboVM Gradle plugin. ETA for the official Intellij IDEA plugin is Q2 2015. \ No newline at end of file diff --git a/src/main/asciidoc/getting-started-maven.adoc b/src/main/asciidoc/getting-started-maven.adoc deleted file mode 100644 index 9e130df..0000000 --- a/src/main/asciidoc/getting-started-maven.adoc +++ /dev/null @@ -1,3 +0,0 @@ -[id="getting-started-maven"] -=== Getting Started with Maven -_Coming Soon_! \ No newline at end of file diff --git a/src/main/asciidoc/getting-started.adoc b/src/main/asciidoc/getting-started.adoc deleted file mode 100644 index 00e1c68..0000000 --- a/src/main/asciidoc/getting-started.adoc +++ /dev/null @@ -1,183 +0,0 @@ -== Getting Started - -In this section you'll learn how to install RoboVM and make sure the toolchain -works correctly by creating a very simple demo app. - -TIP: Wanna run RoboVM on Linux? You can build Linux console apps using RoboVM -at this time. Please see the -https://github.com/robovm/robovm/wiki/Get-started-on-Linux[RoboVM GitHub wiki] -for instructions. - -[id="prerequisits"] -=== Prerequisites - -In order to use RoboVM the following is required: - -* A Mac running Mac OS X {osxversion} or later -* http://www.oracle.com/technetwork/java/javase/downloads/index.html[Oracle's - Java SE JDK 7] or later -* https://itunes.apple.com/us/app/xcode/id497799835?mt=12[Xcode {xcodeversion} from the - Mac App Store] - -NOTE: The first time you install Xcode and every time you update to a new -version you have to open it once to agree to the Xcode terms. - -NOTE: To be able to test and deploy your apps on your devices, you will need -an active subscription with the Apple Developer Program. Visit the -https://developer.apple.com/register/index.action[Apple Developer Portal] to -sign up. You will also need to provision your device for development. You can -find information on device provisioning in the Apple Developer Portal, or -follow http://www.bignerdranch.com/we-teach/how-to-prepare/ios-device-provisioning/[this guide] - -include::getting-started-eclipse.adoc[] - -include::getting-started-idea.adoc[] - -include::getting-started-maven.adoc[] - -include::getting-started-gradle.adoc[] - -=== Project & Code Structure - -Whatever method you chose to create your first RoboVM app, the project's -structure will always resemble this layout, plus or minus the files your IDE -or build system generated. - -[[img-eclipse-project]] -.Basic iOS project in Eclipse -image::eclipse-project.png[] - -Here's a basic run-down of the project's contents: - -* `src/main/java/` is where your sources live -* `resources/` contains your app's icons, launch screens and any other assets your app requires -* `robovm.properties` let's you quickly set attributes of your app, such as the main class or app id. Values in this file will get replaced in the two files described below. -* `robovm.xml` let's you specify the <> of your app -* `Info.plist.xml` let's you specify the https://developer.apple.com/library/mac/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW1[iOS specific configuration] of your app, such as supported screen orientations - -Let's take a quick look at the code itself! - -==== The Main Entry Point - -Every app has a main entry point. We specify the main class in the -`robovm.properties` file: - -[source] ------ -app.version=1.0 -app.id=com.mycompany.myapp -app.mainclass=com.mycompany.myapp.HelloRoboVM // <1> -app.executable=HelloRoboVM -app.build=1 -app.name=Hello RoboVM ------ - -<1> The class is given via its fully qualified class name, including the package it resides in. - -When your app is run on the simulator or on a device, the main class' `main -method will be called on startup. - -[source,java] ------ -public class HelloRoboVM extends UIApplicationDelegateAdapter { // <4> - private UIWindow window; - private MyViewController rootViewController; - - @Override - public boolean didFinishLaunching (UIApplication application, // <3> - UIApplicationLaunchOptions launchOptions) { - rootViewController = new MyViewController(); - - window = new UIWindow(UIScreen.getMainScreen().getBounds()); - window.setRootViewController(rootViewController); - window.makeKeyAndVisible(); - - return true; - } - - public static void main (String[] args) { - try (NSAutoreleasePool pool = new NSAutoreleasePool()) { // <1> - UIApplication.main(args, null, HelloRoboVM.class); // <2> - } - } -} ------ - -<1> Upon entering the `main` method, we setup an https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html[`NSAutoreleasePool`]. It's responsible for managing the life-time of all native Objective-C objects your app interacts with. The autorelease pool will automatically free the memory of any object that is no longer referenced. - -<2> We then call https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/[`UIApplication.main`], telling it about our main class, `HelloRoboVM`. This method is responsible for kicking off the user interface, it will never return. Once it is done launching our app, it will call the `didFinishLaunching` method. - -<3> In `didFinishLaunching` we setup our basic UI. iOS apps are usually composed of a single `UIWindow` on which we set a root `UIViewController`. The view controller is responsible for setting up user interface elements like labels, buttons and so forth, and reacting to any events on those elements. - -<4> Note how `HelloRoboVM` extends from `UIApplicationDelegateAdapter`. We are essentially implementing the Objective-C https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/[`UIApplicationDelegate`] protocol, in Java, which defines methods the `UIApplication` calls when application-level events happen. RoboVM let's us easily extend native Objective-C classes or implement Objective-C protocols! - -Let's take a look at the `MyViewController` class, the work horse of our -application. - -NOTE: iOS UIs can be created programmatically, as demonstrated here, or graphically, using XCode's https://developer.apple.com/xcode/interface-builder/[Interface Builder]. RoboVM currently only supports the programmatic creation of user interfaces. We'll provide Interface Builder integration in Q2 2015. - -==== The View Controller - -View controllers are a simple way of managing individual screens of your app. -A view controller usually sets up the UI controls of a specific screen, -registers listeners for events such as button touches, and then reacts to -these events. The `UIWindow` has a single root view controller, which itself -can manage other view controllers. - -In our simple app, we have only one view controller, which we set as the root -view controller on the window in `HelloRoboVM#didFinishLaunching`. - -[source,java] ------ -public class MyViewController extends UIViewController { // <1> - private final UIButton button; - private final UILabel label; - private int clickCount; - - public MyViewController () { //<2> - UIView view = getView(); - - view.setBackgroundColor(UIColor.white()); - - label = new UILabel(new CGRect(20, 250, 280, 44)); // <3> - label.setFont(UIFont.getSystemFont(24)); - label.setTextAlignment(NSTextAlignment.Center); - view.addSubview(label); - - button = UIButton.create(UIButtonType.RoundedRect); // <4> - button.setFrame(new CGRect(110, 150, 100, 40)); - button.setTitle("Click me!", UIControlState.Normal); - button.getTitleLabel().setFont(UIFont.getBoldSystemFont(22)); - - button.addOnTouchUpInsideListener(new UIControl.OnTouchUpInsideListener() { // <5> - @Override - public void onTouchUpInside (UIControl control, UIEvent event) { - label.setText("Click Nr. " + (++clickCount)); - } - }); - view.addSubview(button); - } -} ------ - -<1> Our `MyViewController` subclasses the Objective-C https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/[`UIViewController`] class. -<2> In its constructor, we setup a label and a button, which we add to the controller's https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/[`UIView`]. The `UIView` is responsible for rendering any content in its area and also handle interactions with that content. In this case, the `UIView` covers the whole `UIWindow`. -<3> To setup a label, we instantiate a https://developer.apple.com/library/ios/documentation/UIKit/Reference/UILabel_Class/[`UILabel`], another Objective-C class, set its size and content, and add it as a sub view to our controllers view. -<4> We do the same for the button of our screen, with one slight twist! -<5> Since we want to react to button touches, we also register a touch listener with the button. Any time a user lifts her finger from the button, we get called back, informing us about this event. Note that the callback originates from native code. RoboVM transparently manages the transition between Java and native code for us! - -And here's what our resulting app looks like on the simulator after some heavy button clicking. - -[[img-eclipse-demo-app]] -.Our marvelous demo app -image::eclipse-demo-app.png[] - -=== Where to go from here? - -Now that you have a basic understanding of how to -use RoboVM with your development environment of choice, it's time to learn -more about writing apps with RoboVM! - -. Read the rest of this user guide -. Check out the <> on https://github.com/robovm/robovm-samples[Github] -. Learn from Apple's https://developer.apple.com/library/ios/navigation/#section=Resource%20Types&topic=Guides[iOS Developer Library] \ No newline at end of file diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc deleted file mode 100644 index 66d22e0..0000000 --- a/src/main/asciidoc/index.adoc +++ /dev/null @@ -1,48 +0,0 @@ -= RoboVM User Guide -:toc: left -:toclevels: 3 -:icons: font -:source-highlighter: prettify -:appversion: 1.0.0 -:osxversion: 10.9 -:xcodeversion: 6.x -:imagesdir: images - -include::introduction.adoc[] - -include::getting-started.adoc[] - -include::samples.adoc[] - -include::configuration-reference.adoc[] - -include::advanced-topics.adoc[] - -+++++ - - -+++++ \ No newline at end of file diff --git a/src/main/asciidoc/introduction.adoc b/src/main/asciidoc/introduction.adoc deleted file mode 100644 index 13cd88c..0000000 --- a/src/main/asciidoc/introduction.adoc +++ /dev/null @@ -1,63 +0,0 @@ -== Introduction - -Mobile app developers targeting both Android and iOS face many challenges. -When comparing the native development environments of these two platforms, -i.e. the toolchains provided by Google and Apple respectively, one quickly -finds that they differ substantially. Android development, as defined by -Google, is based on the Intellij IDEA IDE and the Java programming language. -iOS development, according to Apple, on the other hand is based on the Xcode -IDE and the Objective-C programming language. These differences rule out any -code reuse between the platforms. Also, not many developers are proficient in -both environments. In the end almost every multi-platform app is developed -using separate development teams and separate codebases for each platform. - -The ultimate goal of the RoboVM project is to solve this problem without -compromising on neither developer nor app-user experience. With RoboVM -developing for both iOS and Android becomes less challenging; the same Java -developers can build both versions of the app and a large part of the codebase -can be shared. - -=== Features - -* Brings Java and other JVM languages, such as - http://www.scala-lang.org/[Scala], http://clojure.org/[Clojure], - http://groovy.codehaus.org/[Groovy] and http://kotlinlang.org/[Kotlin], to - iOS devices. -* Translates Java bytecode into machine code - http://en.wikipedia.org/wiki/Ahead-of-time_compilation[ahead-of-time] for - fast execution directly on the CPU without any overhead. The main target is - iOS and the ARM processor (32-bit and 64-bit) but there is also support for - Mac OS X and Linux running on x86 CPUs (both 32-bit and 64-bit). -* Doesn't impose any restrictions on the Java platform features accessible to - the developer, such as reflection or file I/O. -* Supports standard JAR files which lets the developer reuse the vast - ecosystem of 3rd party Java libraries. -* Provides access to the - https://developer.apple.com/technologies/ios/cocoa-touch.html[full native - iOS APIs] through a Java to Objective-C bridge enabling the development of - apps with truly native UIs and with full hardware access. -* Integrates with the most popular tools such as - https://www.eclipse.org/[Eclipse], https://www.eclipse.org/[Intellij IDEA], - http://maven.apache.org/[Maven] and http://www.gradle.org/[Gradle]. -* App Store ready, with hundreds of apps already in the store - -=== Limitations - -There are a few limitations in RoboVM, mainly due to restrictions in the iOS -platform: - -* Loading custom bytecode at runtime is not supported. All class files - comprising the app have to be available at compile time on the developer - machine. -* The http://en.wikipedia.org/wiki/Java_Native_Interface[Java Native - Interface] technology as used on the desktop or on servers usually loads - native code from dynamic libraries but Apple does not permit custom dynamic - libraries to be shipped with an iOS app. RoboVM supports <>. - -NOTE: RoboVM has *full* support for reflection. - -//// -TBW. Describes scope, use cases, how it works, features, limitations, users, -contributing, support options. -//// \ No newline at end of file diff --git a/src/main/asciidoc/samples.adoc b/src/main/asciidoc/samples.adoc deleted file mode 100644 index eb64a68..0000000 --- a/src/main/asciidoc/samples.adoc +++ /dev/null @@ -1,12 +0,0 @@ -[id="samples"] -== Samples - -RoboVM comes with an extensive set of samples, available on -https://github.com/robovm/robovm-samples[Github]. The samples are composed of -ports of Apple's sample apps as well as apps we created ourselves. Most -notable is ContractR, a simple task tracker app. The sample shows you how to -create a cross-platform iOS & Android app, either using the native UIs of -JavaFX, while sharing all its business logic across all platforms. - -The samples can be build and run from Eclipse, Maven or Gradle. Refer to the -repository's `README.md` for up-to-date instructions! diff --git a/stylesheets/foundation.css b/stylesheets/foundation.css deleted file mode 100644 index f413f88..0000000 --- a/stylesheets/foundation.css +++ /dev/null @@ -1,670 +0,0 @@ -/*! normalize.css v2.1.2 | MIT License | git.io/normalize */ -/* ========================================================================== HTML5 display definitions ========================================================================== */ -/** Correct `block` display not defined in IE 8/9. */ -article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; } - -/** Correct `inline-block` display not defined in IE 8/9. */ -audio, canvas, video { display: inline-block; } - -/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */ -audio:not([controls]) { display: none; height: 0; } - -/** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */ -[hidden], template { display: none; } - -script { display: none !important; } - -/* ========================================================================== Base ========================================================================== */ -/** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */ -html { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ } - -/** Remove default margin. */ -body { margin: 0; } - -/* ========================================================================== Links ========================================================================== */ -/** Remove the gray background color from active links in IE 10. */ -a { background: transparent; } - -/** Address `outline` inconsistency between Chrome and other browsers. */ -a:focus { outline: thin dotted; } - -/** Improve readability when focused and also mouse hovered in all browsers. */ -a:active, a:hover { outline: 0; } - -/* ========================================================================== Typography ========================================================================== */ -/** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */ -h1 { font-size: 2em; margin: 0.67em 0; } - -/** Address styling not present in IE 8/9, Safari 5, and Chrome. */ -abbr[title] { border-bottom: 1px dotted; } - -/** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */ -b, strong { font-weight: bold; } - -/** Address styling not present in Safari 5 and Chrome. */ -dfn { font-style: italic; } - -/** Address differences between Firefox and other browsers. */ -hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; } - -/** Address styling not present in IE 8/9. */ -mark { background: #ff0; color: #000; } - -/** Correct font family set oddly in Safari 5 and Chrome. */ -code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; } - -/** Improve readability of pre-formatted text in all browsers. */ -pre { white-space: pre-wrap; } - -/** Set consistent quote types. */ -q { quotes: "\201C" "\201D" "\2018" "\2019"; } - -/** Address inconsistent and variable font size in all browsers. */ -small { font-size: 80%; } - -/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */ -sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } - -sup { top: -0.5em; } - -sub { bottom: -0.25em; } - -/* ========================================================================== Embedded content ========================================================================== */ -/** Remove border when inside `a` element in IE 8/9. */ -img { border: 0; } - -/** Correct overflow displayed oddly in IE 9. */ -svg:not(:root) { overflow: hidden; } - -/* ========================================================================== Figures ========================================================================== */ -/** Address margin not present in IE 8/9 and Safari 5. */ -figure { margin: 0; } - -/* ========================================================================== Forms ========================================================================== */ -/** Define consistent border, margin, and padding. */ -fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; } - -/** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */ -legend { border: 0; /* 1 */ padding: 0; /* 2 */ } - -/** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */ -button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ } - -/** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */ -button, input { line-height: normal; } - -/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */ -button, select { text-transform: none; } - -/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */ -button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ } - -/** Re-set default cursor for disabled elements. */ -button[disabled], html input[disabled] { cursor: default; } - -/** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */ -input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ } - -/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */ -input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; } - -/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */ -input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } - -/** Remove inner padding and border in Firefox 4+. */ -button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; } - -/** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */ -textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ } - -/* ========================================================================== Tables ========================================================================== */ -/** Remove most spacing between table cells. */ -table { border-collapse: collapse; border-spacing: 0; } - -meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; } - -meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; } - -meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; } - -*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } - -html, body { font-size: 100%; } - -body { background: white; color: #222222; padding: 0; margin: 0; font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; } - -a:hover { cursor: pointer; } - -img, object, embed { max-width: 100%; height: auto; } - -object, embed { height: 100%; } - -img { -ms-interpolation-mode: bicubic; } - -#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; } - -.left { float: left !important; } - -.right { float: right !important; } - -.text-left { text-align: left !important; } - -.text-right { text-align: right !important; } - -.text-center { text-align: center !important; } - -.text-justify { text-align: justify !important; } - -.hide { display: none; } - -.antialiased, body { -webkit-font-smoothing: antialiased; } - -img { display: inline-block; vertical-align: middle; } - -textarea { height: auto; min-height: 50px; } - -select { width: 100%; } - -p.lead, .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { font-size: 1.21875em; line-height: 1.6; } - -.subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.4; color: #6f6f6f; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; } - -/* Typography resets */ -div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; } - -/* Default Link Styles */ -a { color: #2ba6cb; text-decoration: none; line-height: inherit; } -a:hover, a:focus { color: #2795b6; } -a img { border: none; } - -/* Default paragraph styles */ -p { font-family: inherit; font-weight: normal; font-size: 1em; line-height: 1.6; margin-bottom: 1.25em; text-rendering: optimizeLegibility; } -p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; } - -/* Default header styles */ -h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; font-weight: bold; font-style: normal; color: #222222; text-rendering: optimizeLegibility; margin-top: 1em; margin-bottom: 0.5em; line-height: 1.2125em; } -h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { font-size: 60%; color: #6f6f6f; line-height: 0; } - -h1 { font-size: 2.125em; } - -h2 { font-size: 1.6875em; } - -h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; } - -h4 { font-size: 1.125em; } - -h5 { font-size: 1.125em; } - -h6 { font-size: 1em; } - -hr { border: solid #dddddd; border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; } - -/* Helpful Typography Defaults */ -em, i { font-style: italic; line-height: inherit; } - -strong, b { font-weight: bold; line-height: inherit; } - -small { font-size: 60%; line-height: inherit; } - -code { font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: bold; color: #7f0a0c; } - -/* Lists */ -ul, ol, dl { font-size: 1em; line-height: 1.6; margin-bottom: 1.25em; list-style-position: outside; font-family: inherit; } - -ul, ol { margin-left: 1.5em; } -ul.no-bullet, ol.no-bullet { margin-left: 1.5em; } - -/* Unordered Lists */ -ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ } -ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; } -ul.square { list-style-type: square; } -ul.circle { list-style-type: circle; } -ul.disc { list-style-type: disc; } -ul.no-bullet { list-style: none; } - -/* Ordered Lists */ -ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; } - -/* Definition Lists */ -dl dt { margin-bottom: 0.3125em; font-weight: bold; } -dl dd { margin-bottom: 1.25em; } - -/* Abbreviations */ -abbr, acronym { text-transform: uppercase; font-size: 90%; color: #222222; border-bottom: 1px dotted #dddddd; cursor: help; } - -abbr { text-transform: none; } - -/* Blockquotes */ -blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; } -blockquote cite { display: block; font-size: 0.8125em; color: #555555; } -blockquote cite:before { content: "\2014 \0020"; } -blockquote cite a, blockquote cite a:visited { color: #555555; } - -blockquote, blockquote p { line-height: 1.6; color: #6f6f6f; } - -/* Microformats */ -.vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #dddddd; padding: 0.625em 0.75em; } -.vcard li { margin: 0; display: block; } -.vcard .fn { font-weight: bold; font-size: 0.9375em; } - -.vevent .summary { font-weight: bold; } -.vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; } - -@media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; } - h1 { font-size: 2.75em; } - h2 { font-size: 2.3125em; } - h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; } - h4 { font-size: 1.4375em; } } -/* Tables */ -table { background: white; margin-bottom: 1.25em; border: solid 1px #dddddd; } -table thead, table tfoot { background: whitesmoke; font-weight: bold; } -table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: #222222; text-align: left; } -table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #222222; } -table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #f9f9f9; } -table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.4; } - -h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; } - -.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; } -.clearfix:after, .float-group:after { clear: both; } - -*:not(pre) > code { font-size: inherit; font-style: normal !important; letter-spacing: 0; padding: 0; line-height: inherit; } - -pre, pre > code { line-height: 1.4; color: black; font-family: monospace, serif; font-weight: normal; } - -.keyseq { color: #555555; } - -kbd { display: inline-block; color: #222222; font-size: 0.75em; line-height: 1.4; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: -0.15em 0.15em 0 0.15em; padding: 0.2em 0.6em 0.2em 0.5em; vertical-align: middle; white-space: nowrap; } - -.keyseq kbd:first-child { margin-left: 0; } - -.keyseq kbd:last-child { margin-right: 0; } - -.menuseq, .menu { color: #090909; } - -b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; } - -b.button:before { content: "["; padding: 0 3px 0 2px; } - -b.button:after { content: "]"; padding: 0 2px 0 3px; } - -#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; } -#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; } -#header:after, #content:after, #footnotes:after, #footer:after { clear: both; } - -#content { margin-top: 1.25em; } - -#content:before { content: none; } - -#header > h1:first-child { color: black; margin-top: 2.25rem; margin-bottom: 0; } -#header > h1:first-child + #toc { margin-top: 8px; border-top: 1px solid #dddddd; } -#header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { border-bottom: 1px solid #dddddd; padding-bottom: 8px; } -#header .details { border-bottom: 1px solid #dddddd; line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: #555555; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; } -#header .details span:first-child { margin-left: -0.125em; } -#header .details span.email a { color: #6f6f6f; } -#header .details br { display: none; } -#header .details br + span:before { content: "\00a0\2013\00a0"; } -#header .details br + span.author:before { content: "\00a0\22c5\00a0"; color: #6f6f6f; } -#header .details br + span#revremark:before { content: "\00a0|\00a0"; } -#header #revnumber { text-transform: capitalize; } -#header #revnumber:after { content: "\00a0"; } - -#content > h1:first-child:not([class]) { color: black; border-bottom: 1px solid #dddddd; padding-bottom: 8px; margin-top: 0; padding-top: 1rem; margin-bottom: 1.25rem; } - -#toc { border-bottom: 1px solid #dddddd; padding-bottom: 0.5em; } -#toc > ul { margin-left: 0.125em; } -#toc ul.sectlevel0 > li > a { font-style: italic; } -#toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; } -#toc ul { font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; list-style-type: none; } -#toc a { text-decoration: none; } -#toc a:active { text-decoration: underline; } - -#toctitle { color: #6f6f6f; font-size: 1.2em; } - -@media only screen and (min-width: 768px) { #toctitle { font-size: 1.375em; } - body.toc2 { padding-left: 15em; padding-right: 0; } - #toc.toc2 { margin-top: 0 !important; background-color: #f2f2f2; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #dddddd; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; } - #toc.toc2 #toctitle { margin-top: 0; font-size: 1.2em; } - #toc.toc2 > ul { font-size: 0.9em; margin-bottom: 0; } - #toc.toc2 ul ul { margin-left: 0; padding-left: 1em; } - #toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; } - body.toc2.toc-right { padding-left: 0; padding-right: 15em; } - body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #dddddd; left: auto; right: 0; } } -@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; } - #toc.toc2 { width: 20em; } - #toc.toc2 #toctitle { font-size: 1.375em; } - #toc.toc2 > ul { font-size: 0.95em; } - #toc.toc2 ul ul { padding-left: 1.25em; } - body.toc2.toc-right { padding-left: 0; padding-right: 20em; } } -#content #toc { border-style: solid; border-width: 1px; border-color: #d9d9d9; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f2; -webkit-border-radius: 0; border-radius: 0; } -#content #toc > :first-child { margin-top: 0; } -#content #toc > :last-child { margin-bottom: 0; } - -#footer { max-width: 100%; background-color: #222222; padding: 1.25em; } - -#footer-text { color: #dddddd; line-height: 1.44; } - -.sect1 { padding-bottom: 0.625em; } - -@media only screen and (min-width: 768px) { .sect1 { padding-bottom: 1.25em; } } -.sect1 + .sect1 { border-top: 1px solid #dddddd; } - -#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { position: absolute; z-index: 1001; width: 1.5ex; margin-left: -1.5ex; display: block; text-decoration: none !important; visibility: hidden; text-align: center; font-weight: normal; } -#content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: "\00A7"; font-size: 0.85em; display: block; padding-top: 0.1em; } -#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; } -#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: #222222; text-decoration: none; } -#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: #151515; } - -.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; } - -.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; } - -table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; } - -.paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { color: black; } - -table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; } - -.admonitionblock > table { border-collapse: separate; border: 0; background: none; width: 100%; } -.admonitionblock > table td.icon { text-align: center; width: 80px; } -.admonitionblock > table td.icon img { max-width: none; } -.admonitionblock > table td.icon .title { font-weight: bold; font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; text-transform: uppercase; } -.admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid #dddddd; color: #555555; } -.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; } - -.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; } -.exampleblock > .content > :first-child { margin-top: 0; } -.exampleblock > .content > :last-child { margin-bottom: 0; } - -.sidebarblock { border-style: solid; border-width: 1px; border-color: #d9d9d9; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f2; -webkit-border-radius: 0; border-radius: 0; } -.sidebarblock > :first-child { margin-top: 0; } -.sidebarblock > :last-child { margin-bottom: 0; } -.sidebarblock > .content > .title { color: #6f6f6f; margin-top: 0; } - -.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; } - -.literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { background: #eeeeee; } -.sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { background: #f2f1f1; } - -.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 1px solid #cccccc; -webkit-border-radius: 0; border-radius: 0; word-wrap: break-word; padding: 0.8em 0.8em 0.65em 0.8em; font-size: 0.8125em; } -.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; } -@media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.90625em; } } -@media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 1em; } } - -.literalblock.output pre { color: #eeeeee; background-color: black; } - -.listingblock pre.highlightjs { padding: 0; } -.listingblock pre.highlightjs > code { padding: 0.8em 0.8em 0.65em 0.8em; -webkit-border-radius: 0; border-radius: 0; } - -.listingblock > .content { position: relative; } - -.listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: #999; } - -.listingblock:hover code[data-lang]:before { display: block; } - -.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; } - -.listingblock.terminal pre .command:not([data-prompt]):before { content: "$"; } - -table.pyhltable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; } - -table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; } - -table.pyhltable td.code { padding-left: .75em; padding-right: 0; } - -pre.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #dddddd; } - -pre.pygments .lineno { display: inline-block; margin-right: .25em; } - -table.pyhltable .linenodiv { background: none !important; padding-right: 0 !important; } - -.quoteblock { margin: 0 1em 1.25em 1.5em; display: table; } -.quoteblock > .title { margin-left: -1.5em; margin-bottom: 0.75em; } -.quoteblock blockquote, .quoteblock blockquote p { color: #6f6f6f; font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; } -.quoteblock blockquote { margin: 0; padding: 0; border: 0; } -.quoteblock blockquote:before { content: "\201c"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: #6f6f6f; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } -.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; } -.quoteblock .attribution { margin-top: 0.5em; margin-right: 0.5ex; text-align: right; } -.quoteblock .quoteblock { margin-left: 0; margin-right: 0; padding: 0.5em 0; border-left: 3px solid #555555; } -.quoteblock .quoteblock blockquote { padding: 0 0 0 0.75em; } -.quoteblock .quoteblock blockquote:before { display: none; } - -.verseblock { margin: 0 1em 1.25em 1em; } -.verseblock pre { font-family: "Open Sans", "DejaVu Sans", sans; font-size: 1.15rem; color: #6f6f6f; font-weight: 300; text-rendering: optimizeLegibility; } -.verseblock pre strong { font-weight: 400; } -.verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; } - -.quoteblock .attribution, .verseblock .attribution { font-size: 0.8125em; line-height: 1.45; font-style: italic; } -.quoteblock .attribution br, .verseblock .attribution br { display: none; } -.quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.05em; color: #555555; } - -.quoteblock.abstract { margin: 0 0 1.25em 0; display: block; } -.quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { text-align: left; word-spacing: 0; } -.quoteblock.abstract blockquote:before, .quoteblock.abstract blockquote p:first-of-type:before { display: none; } - -table.tableblock { max-width: 100%; border-collapse: separate; } -table.tableblock td > .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; } - -table.spread { width: 100%; } - -table.tableblock, th.tableblock, td.tableblock { border: 0 solid #dddddd; } - -table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; } - -table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; } - -table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; } - -table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; } - -table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; } - -table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0; } - -table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; } - -table.frame-all { border-width: 1px; } - -table.frame-sides { border-width: 0 1px; } - -table.frame-topbot { border-width: 1px 0; } - -th.halign-left, td.halign-left { text-align: left; } - -th.halign-right, td.halign-right { text-align: right; } - -th.halign-center, td.halign-center { text-align: center; } - -th.valign-top, td.valign-top { vertical-align: top; } - -th.valign-bottom, td.valign-bottom { vertical-align: bottom; } - -th.valign-middle, td.valign-middle { vertical-align: middle; } - -table thead th, table tfoot th { font-weight: bold; } - -tbody tr th { display: table-cell; line-height: 1.4; background: whitesmoke; } - -tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: #222222; font-weight: bold; } - -p.tableblock > code:only-child { background: none; padding: 0; } - -p.tableblock { font-size: 1em; } - -td > div.verse { white-space: pre; } - -ol { margin-left: 1.75em; } - -ul li ol { margin-left: 1.5em; } - -dl dd { margin-left: 1.125em; } - -dl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; } - -ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.625em; } - -ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; } - -ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; } - -ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { width: 1em; font-size: 0.85em; } - -ul.checklist li > p:first-child > input[type="checkbox"]:first-child { width: 1em; position: relative; top: 1px; } - -ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; } -ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; } -ul.inline > li > * { display: block; } - -.unstyled dl dt { font-weight: normal; font-style: normal; } - -ol.arabic { list-style-type: decimal; } - -ol.decimal { list-style-type: decimal-leading-zero; } - -ol.loweralpha { list-style-type: lower-alpha; } - -ol.upperalpha { list-style-type: upper-alpha; } - -ol.lowerroman { list-style-type: lower-roman; } - -ol.upperroman { list-style-type: upper-roman; } - -ol.lowergreek { list-style-type: lower-greek; } - -.hdlist > table, .colist > table { border: 0; background: none; } -.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; } - -td.hdlist1 { padding-right: .75em; font-weight: bold; } - -td.hdlist1, td.hdlist2 { vertical-align: top; } - -.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; } - -.colist > table tr > td:first-of-type { padding: 0 0.75em; line-height: 1; } -.colist > table tr > td:last-of-type { padding: 0.25em 0; } - -.thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; } - -.imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; } -.imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; } -.imageblock > .title { margin-bottom: 0; } -.imageblock.thumb, .imageblock.th { border-width: 6px; } -.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; } - -.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; } -.image.left { margin-right: 0.625em; } -.image.right { margin-left: 0.625em; } - -a.image { text-decoration: none; } - -span.footnote, span.footnoteref { vertical-align: super; font-size: 0.875em; } -span.footnote a, span.footnoteref a { text-decoration: none; } -span.footnote a:active, span.footnoteref a:active { text-decoration: underline; } - -#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; } -#footnotes hr { width: 20%; min-width: 6.25em; margin: -.25em 0 .75em 0; border-width: 1px 0 0 0; } -#footnotes .footnote { padding: 0 0.375em; line-height: 1.3; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.2em; margin-bottom: .2em; } -#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; } -#footnotes .footnote:last-of-type { margin-bottom: 0; } - -#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; } - -.gist .file-data > table { border: 0; background: #fff; width: 100%; margin-bottom: 0; } -.gist .file-data > table td.line-data { width: 99%; } - -div.unbreakable { page-break-inside: avoid; } - -.big { font-size: larger; } - -.small { font-size: smaller; } - -.underline { text-decoration: underline; } - -.overline { text-decoration: overline; } - -.line-through { text-decoration: line-through; } - -.aqua { color: #00bfbf; } - -.aqua-background { background-color: #00fafa; } - -.black { color: black; } - -.black-background { background-color: black; } - -.blue { color: #0000bf; } - -.blue-background { background-color: #0000fa; } - -.fuchsia { color: #bf00bf; } - -.fuchsia-background { background-color: #fa00fa; } - -.gray { color: #606060; } - -.gray-background { background-color: #7d7d7d; } - -.green { color: #006000; } - -.green-background { background-color: #007d00; } - -.lime { color: #00bf00; } - -.lime-background { background-color: #00fa00; } - -.maroon { color: #600000; } - -.maroon-background { background-color: #7d0000; } - -.navy { color: #000060; } - -.navy-background { background-color: #00007d; } - -.olive { color: #606000; } - -.olive-background { background-color: #7d7d00; } - -.purple { color: #600060; } - -.purple-background { background-color: #7d007d; } - -.red { color: #bf0000; } - -.red-background { background-color: #fa0000; } - -.silver { color: #909090; } - -.silver-background { background-color: #bcbcbc; } - -.teal { color: #006060; } - -.teal-background { background-color: #007d7d; } - -.white { color: #bfbfbf; } - -.white-background { background-color: #fafafa; } - -.yellow { color: #bfbf00; } - -.yellow-background { background-color: #fafa00; } - -span.icon > .fa { cursor: default; } - -.admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); cursor: default; } -.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #207c98; } -.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; } -.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #bf6900; } -.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #bf3400; } -.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #bf0000; } - -.conum[data-value] { display: inline-block; color: #fff !important; background-color: #222222; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family: "Open Sans", "DejaVu Sans", sans-serif; font-style: normal; font-weight: bold; } -.conum[data-value] * { color: #fff !important; } -.conum[data-value] + b { display: none; } -.conum[data-value]:after { content: attr(data-value); } -pre .conum[data-value] { position: relative; top: -0.125em; } - -b.conum * { color: inherit !important; } - -.conum:not([data-value]):empty { display: none; } - -.literalblock pre, .listingblock pre { background: #eeeeee; } diff --git a/theme/assets/app.js b/theme/assets/app.js new file mode 100644 index 0000000..8f82f75 --- /dev/null +++ b/theme/assets/app.js @@ -0,0 +1 @@ +var requirejs,require,define;(function(global){function isFunction(e){return ostring.call(e)==="[object Function]"}function isArray(e){return ostring.call(e)==="[object Array]"}function each(e,t){if(e){var n;for(n=0;n-1;n-=1)if(e[n]&&t(e[n],n,e))break}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var n;for(n in e)if(hasProp(e,n)&&t(e[n],n))break}function mixin(e,t,n,r){return t&&eachProp(t,function(t,i){if(n||!hasProp(e,i))r&&typeof t=="object"&&t&&!isArray(t)&&!isFunction(t)&&!(t instanceof RegExp)?(e[i]||(e[i]={}),mixin(e[i],t,n,r)):e[i]=t}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,n,r){var i=new Error(t+"\nhttp://requirejs.org/docs/errors.html#"+e);return i.requireType=e,i.requireModules=r,n&&(i.originalError=n),i}function newContext(e){function m(e){var t,n,r=e.length;for(t=0;t0&&(e.splice(t-1,2),t-=2)}}}function g(e,t,n){var r,i,s,u,a,f,l,c,h,p,d,v=t&&t.split("/"),g=v,y=o.map,b=y&&y["*"];e&&e.charAt(0)==="."&&(t?(g=v.slice(0,v.length-1),e=e.split("/"),l=e.length-1,o.nodeIdCompat&&jsSuffixRegExp.test(e[l])&&(e[l]=e[l].replace(jsSuffixRegExp,"")),e=g.concat(e),m(e),e=e.join("/")):e.indexOf("./")===0&&(e=e.substring(2)));if(n&&y&&(v||b)){s=e.split("/");e:for(u=s.length;u>0;u-=1){f=s.slice(0,u).join("/");if(v)for(a=v.length;a>0;a-=1){i=getOwn(y,v.slice(0,a).join("/"));if(i){i=getOwn(i,f);if(i){c=i,h=u;break e}}}!p&&b&&getOwn(b,f)&&(p=getOwn(b,f),d=u)}!c&&p&&(c=p,h=d),c&&(s.splice(0,h,c),e=s.join("/"))}return r=getOwn(o.pkgs,e),r?r:e}function y(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute("data-requiremodule")===e&&t.getAttribute("data-requirecontext")===r.contextName)return t.parentNode.removeChild(t),!0})}function b(e){var t=getOwn(o.paths,e);if(t&&isArray(t)&&t.length>1)return t.shift(),r.require.undef(e),r.require([e]),!0}function w(e){var t,n=e?e.indexOf("!"):-1;return n>-1&&(t=e.substring(0,n),e=e.substring(n+1,e.length)),[t,e]}function E(e,t,n,i){var s,o,u,a,f=null,l=t?t.name:null,h=e,p=!0,m="";return e||(p=!1,e="_@r"+(d+=1)),a=w(e),f=a[0],e=a[1],f&&(f=g(f,l,i),o=getOwn(c,f)),e&&(f?o&&o.normalize?m=o.normalize(e,function(e){return g(e,l,i)}):m=g(e,l,i):(m=g(e,l,i),a=w(m),f=a[0],m=a[1],n=!0,s=r.nameToUrl(m))),u=f&&!o&&!n?"_unnormalized"+(v+=1):"",{prefix:f,name:m,parentMap:t,unnormalized:!!u,url:s,originalName:h,isDefine:p,id:(f?f+"!"+m:m)+u}}function S(e){var t=e.id,n=getOwn(u,t);return n||(n=u[t]=new r.Module(e)),n}function x(e,t,n){var r=e.id,i=getOwn(u,r);hasProp(c,r)&&(!i||i.defineEmitComplete)?t==="defined"&&n(c[r]):(i=S(e),i.error&&t==="error"?n(i.error):i.on(t,n))}function T(e,t){var n=e.requireModules,r=!1;t?t(e):(each(n,function(t){var n=getOwn(u,t);n&&(n.error=e,n.events.error&&(r=!0,n.emit("error",e)))}),r||req.onError(e))}function N(){globalDefQueue.length&&(apsp.apply(l,[l.length,0].concat(globalDefQueue)),globalDefQueue=[])}function C(e){delete u[e],delete a[e]}function k(e,t,n){var r=e.map.id;e.error?e.emit("error",e.error):(t[r]=!0,each(e.depMaps,function(r,i){var s=r.id,o=getOwn(u,s);o&&!e.depMatched[i]&&!n[s]&&(getOwn(t,s)?(e.defineDep(i,c[s]),e.check()):k(o,t,n))}),n[r]=!0)}function L(){var e,n,i=o.waitSeconds*1e3,u=i&&r.startTime+i<(new Date).getTime(),f=[],l=[],c=!1,h=!0;if(t)return;t=!0,eachProp(a,function(e){var t=e.map,r=t.id;if(!e.enabled)return;t.isDefine||l.push(e);if(!e.error)if(!e.inited&&u)b(r)?(n=!0,c=!0):(f.push(r),y(r));else if(!e.inited&&e.fetched&&t.isDefine){c=!0;if(!t.prefix)return h=!1}});if(u&&f.length)return e=makeError("timeout","Load timeout for modules: "+f,null,f),e.contextName=r.contextName,T(e);h&&each(l,function(e){k(e,{},{})}),(!u||n)&&c&&(isBrowser||isWebWorker)&&!s&&(s=setTimeout(function(){s=0,L()},50)),t=!1}function A(e){hasProp(c,e[0])||S(E(e[0],null,!0)).init(e[1],e[2])}function O(e,t,n,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(n,t,!1)}function M(e){var t=e.currentTarget||e.srcElement;return O(t,r.onScriptLoad,"load","onreadystatechange"),O(t,r.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function _(){var e;N();while(l.length){e=l.shift();if(e[0]===null)return T(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));A(e)}}var t,n,r,i,s,o={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},u={},a={},f={},l=[],c={},h={},p={},d=1,v=1;return i={require:function(e){return e.require?e.require:e.require=r.makeRequire(e.map)},exports:function(e){e.usingExports=!0;if(e.map.isDefine)return e.exports?c[e.map.id]=e.exports:e.exports=c[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(o.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},n=function(e){this.events=getOwn(f,e.id)||{},this.map=e,this.shim=getOwn(o.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},n.prototype={init:function(e,t,n,r){r=r||{};if(this.inited)return;this.factory=t,n?this.on("error",n):this.events.error&&(n=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=n,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check()},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(this.fetched)return;this.fetched=!0,r.startTime=(new Date).getTime();var e=this.map;if(!this.shim)return e.prefix?this.callPlugin():this.load();r.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()}))},load:function(){var e=this.map.url;h[e]||(h[e]=!0,r.load(this.map.id,e))},check:function(){if(!this.enabled||this.enabling)return;var e,t,n=this.map.id,i=this.depExports,s=this.exports,o=this.factory;if(!this.inited)this.fetch();else if(this.error)this.emit("error",this.error);else if(!this.defining){this.defining=!0;if(this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{s=r.execCb(n,o,i,s)}catch(u){e=u}else s=r.execCb(n,o,i,s);this.map.isDefine&&s===undefined&&(t=this.module,t?s=t.exports:this.usingExports&&(s=this.exports));if(e)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=this.map.isDefine?"define":"require",T(this.error=e)}else s=o;this.exports=s,this.map.isDefine&&!this.ignore&&(c[n]=s,req.onResourceLoad&&req.onResourceLoad(r,this.map,this.depMaps)),C(n),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}},callPlugin:function(){var e=this.map,t=e.id,n=E(e.prefix);this.depMaps.push(n),x(n,"defined",bind(this,function(n){var i,s,a,f=getOwn(p,this.map.id),l=this.map.name,c=this.map.parentMap?this.map.parentMap.name:null,h=r.makeRequire(e.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){n.normalize&&(l=n.normalize(l,function(e){return g(e,c,!0)})||""),s=E(e.prefix+"!"+l,this.map.parentMap),x(s,"defined",bind(this,function(e){this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),a=getOwn(u,s.id),a&&(this.depMaps.push(s),this.events.error&&a.on("error",bind(this,function(e){this.emit("error",e)})),a.enable());return}if(f){this.map.url=r.nameToUrl(f),this.load();return}i=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),i.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(u,function(e){e.map.id.indexOf(t+"_unnormalized")===0&&C(e.map.id)}),T(e)}),i.fromText=bind(this,function(n,s){var u=e.name,a=E(u),f=useInteractive;s&&(n=s),f&&(useInteractive=!1),S(a),hasProp(o.config,t)&&(o.config[u]=o.config[t]);try{req.exec(n)}catch(l){return T(makeError("fromtexteval","fromText eval for "+t+" failed: "+l,l,[t]))}f&&(useInteractive=!0),this.depMaps.push(a),r.completeLoad(u),h([u],i)}),n.load(e.name,h,i,o)})),r.enable(n,this),this.pluginMaps[n.id]=n},enable:function(){a[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var n,s,o;if(typeof e=="string"){e=E(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,o=getOwn(i,e.id);if(o){this.depExports[t]=o(this);return}this.depCount+=1,x(e,"defined",bind(this,function(e){this.defineDep(t,e),this.check()})),this.errback&&x(e,"error",bind(this,this.errback))}n=e.id,s=u[n],!hasProp(i,n)&&s&&!s.enabled&&r.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(u,e.id);t&&!t.enabled&&r.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var n=this.events[e];n||(n=this.events[e]=[]),n.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),e==="error"&&delete this.events[e]}},r={config:o,contextName:e,registry:u,defined:c,urlFetched:h,defQueue:l,Module:n,makeModuleMap:E,nextTick:req.nextTick,onError:T,configure:function(e){e.baseUrl&&e.baseUrl.charAt(e.baseUrl.length-1)!=="/"&&(e.baseUrl+="/");var t=o.shim,n={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){n[t]?(o[t]||(o[t]={}),mixin(o[t],e,!0,!0)):o[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(p[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,n){isArray(e)&&(e={deps:e}),(e.exports||e.init)&&!e.exportsFn&&(e.exportsFn=r.makeShimExports(e)),t[n]=e}),o.shim=t),e.packages&&each(e.packages,function(e){var t,n;e=typeof e=="string"?{name:e}:e,n=e.name,t=e.location,t&&(o.paths[n]=e.location),o.pkgs[n]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(u,function(e,t){!e.inited&&!e.map.unnormalized&&(e.map=E(t))}),(e.deps||e.callback)&&r.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,n){function s(o,a,f){var l,h,p;return n.enableBuildCallback&&a&&isFunction(a)&&(a.__requireJsBuild=!0),typeof o=="string"?isFunction(a)?T(makeError("requireargs","Invalid require call"),f):t&&hasProp(i,o)?i[o](u[t.id]):req.get?req.get(r,o,t,s):(h=E(o,t,!1,!0),l=h.id,hasProp(c,l)?c[l]:T(makeError("notloaded",'Module name "'+l+'" has not been loaded yet for context: '+e+(t?"":". Use require([])")))):(_(),r.nextTick(function(){_(),p=S(E(null,t)),p.skipMap=n.skipMap,p.init(o,a,f,{enabled:!0}),L()}),s)}return n=n||{},mixin(s,{isBrowser:isBrowser,toUrl:function(e){var n,i=e.lastIndexOf("."),s=e.split("/")[0],o=s==="."||s==="..";return i!==-1&&(!o||i>1)&&(n=e.substring(i,e.length),e=e.substring(0,i)),r.nameToUrl(g(e,t&&t.id,!0),n,!0)},defined:function(e){return hasProp(c,E(e,t,!1,!0).id)},specified:function(e){return e=E(e,t,!1,!0).id,hasProp(c,e)||hasProp(u,e)}}),t||(s.undef=function(e){N();var n=E(e,t,!0),r=getOwn(u,e);y(e),delete c[e],delete h[n.url],delete f[e],eachReverse(l,function(t,n){t[0]===e&&l.splice(n,1)}),r&&(r.events.defined&&(f[e]=r.events),C(e))}),s},enable:function(e){var t=getOwn(u,e.id);t&&S(e).enable()},completeLoad:function(e){var t,n,r,i=getOwn(o.shim,e)||{},s=i.exports;N();while(l.length){n=l.shift();if(n[0]===null){n[0]=e;if(t)break;t=!0}else n[0]===e&&(t=!0);A(n)}r=getOwn(u,e);if(!t&&!hasProp(c,e)&&r&&!r.inited){if(o.enforceDefine&&(!s||!getGlobal(s))){if(b(e))return;return T(makeError("nodefine","No define call for "+e,null,[e]))}A([e,i.deps||[],i.exportsFn])}L()},nameToUrl:function(e,t,n){var i,s,u,a,f,l,c,h=getOwn(o.pkgs,e);h&&(e=h),c=getOwn(p,e);if(c)return r.nameToUrl(c,t,n);if(req.jsExtRegExp.test(e))f=e+(t||"");else{i=o.paths,s=e.split("/");for(u=s.length;u>0;u-=1){a=s.slice(0,u).join("/"),l=getOwn(i,a);if(l){isArray(l)&&(l=l[0]),s.splice(0,u,l);break}}f=s.join("/"),f+=t||(/^data\:|\?/.test(f)||n?"":".js"),f=(f.charAt(0)==="/"||f.match(/^[\w\+\.\-]+:/)?"":o.baseUrl)+f}return o.urlArgs?f+((f.indexOf("?")===-1?"?":"&")+o.urlArgs):f},load:function(e,t){req.load(r,e,t)},execCb:function(e,t,n,r){return t.apply(r,n)},onScriptLoad:function(e){if(e.type==="load"||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=M(e);r.completeLoad(t.id)}},onScriptError:function(e){var t=M(e);if(!b(t.id))return T(makeError("scripterror","Script error for: "+t.id,e,[t.id]))}},r.require=r.makeRequire(),r}function getInteractiveScript(){return interactiveScript&&interactiveScript.readyState==="interactive"?interactiveScript:(eachReverse(scripts(),function(e){if(e.readyState==="interactive")return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.1.11",commentRegExp=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,ap=Array.prototype,apsp=ap.splice,isBrowser=typeof window!="undefined"&&typeof navigator!="undefined"&&!!window.document,isWebWorker=!isBrowser&&typeof importScripts!="undefined",readyRegExp=isBrowser&&navigator.platform==="PLAYSTATION 3"?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera=typeof opera!="undefined"&&opera.toString()==="[object Opera]",contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if(typeof define!="undefined")return;if(typeof requirejs!="undefined"){if(isFunction(requirejs))return;cfg=requirejs,requirejs=undefined}typeof require!="undefined"&&!isFunction(require)&&(cfg=require,require=undefined),req=requirejs=function(e,t,n,r){var i,s,o=defContextName;return!isArray(e)&&typeof e!="string"&&(s=e,isArray(t)?(e=t,t=n,n=r):e=[]),s&&s.context&&(o=s.context),i=getOwn(contexts,o),i||(i=contexts[o]=req.s.newContext(o)),s&&i.configure(s),i.require(e,t,n)},req.config=function(e){return req(e)},req.nextTick=typeof setTimeout!="undefined"?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,n){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,n){var r=e&&e.config||{},i;if(isBrowser)return i=req.createNode(r,t,n),i.setAttribute("data-requirecontext",e.contextName),i.setAttribute("data-requiremodule",t),i.attachEvent&&!(i.attachEvent.toString&&i.attachEvent.toString().indexOf("[native code")<0)&&!isOpera?(useInteractive=!0,i.attachEvent("onreadystatechange",e.onScriptLoad)):(i.addEventListener("load",e.onScriptLoad,!1),i.addEventListener("error",e.onScriptError,!1)),i.src=n,currentlyAddingScript=i,baseElement?head.insertBefore(i,baseElement):head.appendChild(i),currentlyAddingScript=null,i;if(isWebWorker)try{importScripts(n),e.completeLoad(t)}catch(s){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+n,s,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){head||(head=e.parentNode),dataMain=e.getAttribute("data-main");if(dataMain)return mainScript=dataMain,cfg.baseUrl||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,n){var r,i;typeof e!="string"&&(n=t,t=e,e=null),isArray(t)||(n=t,t=null),!t&&isFunction(n)&&(t=[],n.length&&(n.toString().replace(commentRegExp,"").replace(cjsRequireRegExp,function(e,n){t.push(n)}),t=(n.length===1?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript(),r&&(e||(e=r.getAttribute("data-requiremodule")),i=contexts[r.getAttribute("data-requirecontext")])),(i?i.defQueue:globalDefQueue).push([e,t,n])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)})(this),define("requireLib",function(){}),function(e,t){typeof module=="object"&&typeof module.exports=="object"?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}(typeof window!="undefined"?window:this,function(window,noGlobal){function isArraylike(e){var t=e.length,n=jQuery.type(e);return n==="function"||jQuery.isWindow(e)?!1:e.nodeType===1&&t?!0:n==="array"||t===0||typeof t=="number"&&t>0&&t-1 in e}function winnow(e,t,n){if(jQuery.isFunction(t))return jQuery.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return jQuery.grep(e,function(e){return e===t!==n});if(typeof t=="string"){if(risSimple.test(t))return jQuery.filter(t,e,n);t=jQuery.filter(t,e)}return jQuery.grep(e,function(e){return indexOf.call(t,e)>=0!==n})}function sibling(e,t){while((e=e[t])&&e.nodeType!==1);return e}function createOptions(e){var t=optionsCache[e]={};return jQuery.each(e.match(rnotwhite)||[],function(e,n){t[n]=!0}),t}function completed(){document.removeEventListener("DOMContentLoaded",completed,!1),window.removeEventListener("load",completed,!1),jQuery.ready()}function Data(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=jQuery.expando+Math.random()}function dataAttr(e,t,n){var r;if(n===undefined&&e.nodeType===1){r="data-"+t.replace(rmultiDash,"-$1").toLowerCase(),n=e.getAttribute(r);if(typeof n=="string"){try{n=n==="true"?!0:n==="false"?!1:n==="null"?null:+n+""===n?+n:rbrace.test(n)?jQuery.parseJSON(n):n}catch(i){}data_user.set(e,t,n)}else n=undefined}return n}function returnTrue(){return!0}function returnFalse(){return!1}function safeActiveElement(){try{return document.activeElement}catch(e){}}function manipulationTarget(e,t){return jQuery.nodeName(e,"table")&&jQuery.nodeName(t.nodeType!==11?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function disableScript(e){return e.type=(e.getAttribute("type")!==null)+"/"+e.type,e}function restoreScript(e){var t=rscriptTypeMasked.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function setGlobalEval(e,t){var n=0,r=e.length;for(;n")).appendTo(t.documentElement),t=iframe[0].contentDocument,t.write(),t.close(),n=actualDisplay(e,t),iframe.detach();elemdisplay[e]=n}return n}function curCSS(e,t,n){var r,i,s,o,u=e.style;return n=n||getStyles(e),n&&(o=n.getPropertyValue(t)||n[t]),n&&(o===""&&!jQuery.contains(e.ownerDocument,e)&&(o=jQuery.style(e,t)),rnumnonpx.test(o)&&rmargin.test(t)&&(r=u.width,i=u.minWidth,s=u.maxWidth,u.minWidth=u.maxWidth=u.width=o,o=n.width,u.width=r,u.minWidth=i,u.maxWidth=s)),o!==undefined?o+"":o}function addGetHookIf(e,t){return{get:function(){if(e()){delete this.get;return}return(this.get=t).apply(this,arguments)}}}function vendorPropName(e,t){if(t in e)return t;var n=t[0].toUpperCase()+t.slice(1),r=t,i=cssPrefixes.length;while(i--){t=cssPrefixes[i]+n;if(t in e)return t}return r}function setPositiveNumber(e,t,n){var r=rnumsplit.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function augmentWidthOrHeight(e,t,n,r,i){var s=n===(r?"border":"content")?4:t==="width"?1:0,o=0;for(;s<4;s+=2)n==="margin"&&(o+=jQuery.css(e,n+cssExpand[s],!0,i)),r?(n==="content"&&(o-=jQuery.css(e,"padding"+cssExpand[s],!0,i)),n!=="margin"&&(o-=jQuery.css(e,"border"+cssExpand[s]+"Width",!0,i))):(o+=jQuery.css(e,"padding"+cssExpand[s],!0,i),n!=="padding"&&(o+=jQuery.css(e,"border"+cssExpand[s]+"Width",!0,i)));return o}function getWidthOrHeight(e,t,n){var r=!0,i=t==="width"?e.offsetWidth:e.offsetHeight,s=getStyles(e),o=jQuery.css(e,"boxSizing",!1,s)==="border-box";if(i<=0||i==null){i=curCSS(e,t,s);if(i<0||i==null)i=e.style[t];if(rnumnonpx.test(i))return i;r=o&&(support.boxSizingReliable()||i===e.style[t]),i=parseFloat(i)||0}return i+augmentWidthOrHeight(e,t,n||(o?"border":"content"),r,s)+"px"}function showHide(e,t){var n,r,i,s=[],o=0,u=e.length;for(;o=0&&n=0},isPlainObject:function(e){return jQuery.type(e)!=="object"||e.nodeType||jQuery.isWindow(e)?!1:e.constructor&&!hasOwn.call(e.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return e==null?e+"":typeof e=="object"||typeof e=="function"?class2type[toString.call(e)]||"object":typeof e},globalEval:function(code){var script,indirect=eval;code=jQuery.trim(code),code&&(code.indexOf("use strict")===1?(script=document.createElement("script"),script.text=code,document.head.appendChild(script).parentNode.removeChild(script)):indirect(code))},camelCase:function(e){return e.replace(rmsPrefix,"ms-").replace(rdashAlpha,fcamelCase)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,s=e.length,o=isArraylike(e);if(n)if(o)for(;ir.cacheLength&&delete t[e.shift()],t[n+" "]=i}var e=[];return t}function ut(e){return e[w]=!0,e}function at(e){var t=p.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ft(e,t){var n=e.split("|"),i=e.length;while(i--)r.attrHandle[n[i]]=t}function lt(e,t){var n=t&&e,r=n&&e.nodeType===1&&t.nodeType===1&&(~t.sourceIndex||A)-(~e.sourceIndex||A);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function ht(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function pt(e){return ut(function(t){return t=+t,ut(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function dt(e){return e&&typeof e.getElementsByTagName!==L&&e}function vt(){}function mt(e){var t=0,n=e.length,r="";for(;t1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function bt(e,t,n){var r=0,i=t.length;for(;r-1&&(s[f]=!(o[f]=c))}}else g=wt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):P.apply(o,g)})}function St(e){var t,n,i,s=e.length,o=r.relative[e[0].type],u=o||r.relative[" "],a=o?1:0,l=gt(function(e){return e===t},u,!0),c=gt(function(e){return B.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==f)||((t=n).nodeType?l(e,n,r):c(e,n,r))}];for(;a1&&yt(h),a>1&&mt(e.slice(0,a-1).concat({value:e[a-2].type===" "?"*":""})).replace(z,"$1"),n,a0,i=e.length>0,s=function(s,o,u,a,l){var c,h,d,v=0,m="0",g=s&&[],y=[],b=f,w=s||i&&r.find.TAG("*",l),E=S+=b==null?1:Math.random()||.1,x=w.length;l&&(f=o!==p&&o);for(;m!==x&&(c=w[m])!=null;m++){if(i&&c){h=0;while(d=e[h++])if(d(c,o,u)){a.push(c);break}l&&(S=E)}n&&((c=!d&&c)&&v--,s&&g.push(c))}v+=m;if(n&&m!==v){h=0;while(d=t[h++])d(g,y,o,u);if(s){if(v>0)while(m--)!g[m]&&!y[m]&&(y[m]=_.call(a));y=wt(y)}P.apply(a,y),l&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(a)}return l&&(S=E,f=b),g};return n?ut(s):s}var t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w="sizzle"+ -(new Date),E=e.document,S=0,x=0,T=ot(),N=ot(),C=ot(),k=function(e,t){return e===t&&(c=!0),0},L=typeof undefined,A=1<<31,O={}.hasOwnProperty,M=[],_=M.pop,D=M.push,P=M.push,H=M.slice,B=M.indexOf||function(e){var t=0,n=this.length;for(;t+~]|"+F+")"+F+"*"),V=new RegExp("="+F+"*([^\\]'\"]*?)"+F+"*\\]","g"),$=new RegExp(U),J=new RegExp("^"+q+"$"),K={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I.replace("w","w*")+")"),ATTR:new RegExp("^"+R),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+F+"*(even|odd|(([+-]|)(\\d*)n|)"+F+"*(?:([+-]|)"+F+"*(\\d+)|))"+F+"*\\)|)","i"),bool:new RegExp("^(?:"+j+")$","i"),needsContext:new RegExp("^"+F+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+F+"*((?:-\\d)?\\d*)"+F+"*\\)|)(?=[^-]|$)","i")},Q=/^(?:input|select|textarea|button)$/i,G=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/[+~]/,tt=/'|\\/g,nt=new RegExp("\\\\([\\da-f]{1,6}"+F+"?|("+F+")|.)","ig"),rt=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,r&1023|56320)};try{P.apply(M=H.call(E.childNodes),E.childNodes),M[E.childNodes.length].nodeType}catch(it){P={apply:M.length?function(e,t){D.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}n=st.support={},s=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},h=st.setDocument=function(e){var t,i=e?e.ownerDocument||e:E,o=i.defaultView;if(i===p||i.nodeType!==9||!i.documentElement)return p;p=i,d=i.documentElement,v=!s(i),o&&o!==o.top&&(o.addEventListener?o.addEventListener("unload",function(){h()},!1):o.attachEvent&&o.attachEvent("onunload",function(){h()})),n.attributes=at(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=at(function(e){return e.appendChild(i.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Y.test(i.getElementsByClassName)&&at(function(e){return e.innerHTML="
",e.firstChild.className="i",e.getElementsByClassName("i").length===2}),n.getById=at(function(e){return d.appendChild(e).id=w,!i.getElementsByName||!i.getElementsByName(w).length}),n.getById?(r.find.ID=function(e,t){if(typeof t.getElementById!==L&&v){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},r.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){return e.getAttribute("id")===t}}):(delete r.find.ID,r.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){var n=typeof e.getAttributeNode!==L&&e.getAttributeNode("id");return n&&n.value===t}}),r.find.TAG=n.getElementsByTagName?function(e,t){if(typeof t.getElementsByTagName!==L)return t.getElementsByTagName(e)}:function(e,t){var n,r=[],i=0,s=t.getElementsByTagName(e);if(e==="*"){while(n=s[i++])n.nodeType===1&&r.push(n);return r}return s},r.find.CLASS=n.getElementsByClassName&&function(e,t){if(typeof t.getElementsByClassName!==L&&v)return t.getElementsByClassName(e)},g=[],m=[];if(n.qsa=Y.test(i.querySelectorAll))at(function(e){e.innerHTML="",e.querySelectorAll("[msallowclip^='']").length&&m.push("[*^$]="+F+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||m.push("\\["+F+"*(?:value|"+j+")"),e.querySelectorAll(":checked").length||m.push(":checked")}),at(function(e){var t=i.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&m.push("name"+F+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||m.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),m.push(",.*:")});return(n.matchesSelector=Y.test(y=d.matches||d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&at(function(e){n.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),g.push("!=",U)}),m=m.length&&new RegExp(m.join("|")),g=g.length&&new RegExp(g.join("|")),t=Y.test(d.compareDocumentPosition),b=t||Y.test(d.contains)?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!r&&r.nodeType===1&&!!(n.contains?n.contains(r):e.compareDocumentPosition&&e.compareDocumentPosition(r)&16)}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},k=t?function(e,t){if(e===t)return c=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r?r:(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,r&1||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===i||e.ownerDocument===E&&b(E,e)?-1:t===i||t.ownerDocument===E&&b(E,t)?1:l?B.call(l,e)-B.call(l,t):0:r&4?-1:1)}:function(e,t){if(e===t)return c=!0,0;var n,r=0,s=e.parentNode,o=t.parentNode,u=[e],a=[t];if(!s||!o)return e===i?-1:t===i?1:s?-1:o?1:l?B.call(l,e)-B.call(l,t):0;if(s===o)return lt(e,t);n=e;while(n=n.parentNode)u.unshift(n);n=t;while(n=n.parentNode)a.unshift(n);while(u[r]===a[r])r++;return r?lt(u[r],a[r]):u[r]===E?-1:a[r]===E?1:0},i},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){(e.ownerDocument||e)!==p&&h(e),t=t.replace(V,"='$1']");if(n.matchesSelector&&v&&(!g||!g.test(t))&&(!m||!m.test(t)))try{var r=y.call(e,t);if(r||n.disconnectedMatch||e.document&&e.document.nodeType!==11)return r}catch(i){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&h(e),b(e,t)},st.attr=function(e,t){(e.ownerDocument||e)!==p&&h(e);var i=r.attrHandle[t.toLowerCase()],s=i&&O.call(r.attrHandle,t.toLowerCase())?i(e,t,!v):undefined;return s!==undefined?s:n.attributes||!v?e.getAttribute(t):(s=e.getAttributeNode(t))&&s.specified?s.value:null},st.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,r=[],i=0,s=0;c=!n.detectDuplicates,l=!n.sortStable&&e.slice(0),e.sort(k);if(c){while(t=e[s++])t===e[s]&&(i=r.push(s));while(i--)e.splice(r[i],1)}return l=null,e},i=st.getText=function(e){var t,n="",r=0,s=e.nodeType;if(!s)while(t=e[r++])n+=i(t);else if(s===1||s===9||s===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(s===3||s===4)return e.nodeValue;return n},r=st.selectors={cacheLength:50,createPseudo:ut,match:K,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(nt,rt),e[3]=(e[3]||e[4]||e[5]||"").replace(nt,rt),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1].slice(0,3)==="nth"?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(e[3]==="even"||e[3]==="odd")),e[5]=+(e[7]+e[8]||e[3]==="odd")):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return K.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&$.test(n)&&(t=o(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(nt,rt).toLowerCase();return e==="*"?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=T[e+" "];return t||(t=new RegExp("(^|"+F+")"+e+"("+F+"|$)"))&&T(e,function(e){return t.test(typeof e.className=="string"&&e.className||typeof e.getAttribute!==L&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return i==null?t==="!=":t?(i+="",t==="="?i===n:t==="!="?i!==n:t==="^="?n&&i.indexOf(n)===0:t==="*="?n&&i.indexOf(n)>-1:t==="$="?n&&i.slice(-n.length)===n:t==="~="?(" "+i+" ").indexOf(n)>-1:t==="|="?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var s=e.slice(0,3)!=="nth",o=e.slice(-4)!=="last",u=t==="of-type";return r===1&&i===0?function(e){return!!e.parentNode}:function(t,n,a){var f,l,c,h,p,d,v=s!==o?"nextSibling":"previousSibling",m=t.parentNode,g=u&&t.nodeName.toLowerCase(),y=!a&&!u;if(m){if(s){while(v){c=t;while(c=c[v])if(u?c.nodeName.toLowerCase()===g:c.nodeType===1)return!1;d=v=e==="only"&&!d&&"nextSibling"}return!0}d=[o?m.firstChild:m.lastChild];if(o&&y){l=m[w]||(m[w]={}),f=l[e]||[],p=f[0]===S&&f[1],h=f[0]===S&&f[2],c=p&&m.childNodes[p];while(c=++p&&c&&c[v]||(h=p=0)||d.pop())if(c.nodeType===1&&++h&&c===t){l[e]=[S,p,h];break}}else if(y&&(f=(t[w]||(t[w]={}))[e])&&f[0]===S)h=f[1];else while(c=++p&&c&&c[v]||(h=p=0)||d.pop())if((u?c.nodeName.toLowerCase()===g:c.nodeType===1)&&++h){y&&((c[w]||(c[w]={}))[e]=[S,h]);if(c===t)break}return h-=i,h===r||h%r===0&&h/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return i[w]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?ut(function(e,n){var r,s=i(e,t),o=s.length;while(o--)r=B.call(e,s[o]),e[r]=!(n[r]=s[o])}):function(e){return i(e,0,n)}):i}},pseudos:{not:ut(function(e){var t=[],n=[],r=u(e.replace(z,"$1"));return r[w]?ut(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:ut(function(e){return function(t){return st(e,t).length>0}}),contains:ut(function(e){return function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:ut(function(e){return J.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(nt,rt).toLowerCase(),function(t){var n;do if(n=v?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||n.indexOf(e+"-")===0;while((t=t.parentNode)&&t.nodeType===1);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return G.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},text:function(e){var t;return e.nodeName.toLowerCase()==="input"&&e.type==="text"&&((t=e.getAttribute("type"))==null||t.toLowerCase()==="text")},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[n<0?n+t:n]}),even:pt(function(e,t){var n=0;for(;n=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=n<0?n+t:n;for(;++r2&&(l=f[0]).type==="ID"&&n.getById&&t.nodeType===9&&v&&r.relative[f[1].type]){t=(r.find.ID(l.matches[0].replace(nt,rt),t)||[])[0];if(!t)return i;p&&(t=t.parentNode),e=e.slice(f.shift().value.length)}a=K.needsContext.test(e)?0:f.length;while(a--){l=f[a];if(r.relative[c=l.type])break;if(h=r.find[c])if(s=h(l.matches[0].replace(nt,rt),et.test(f[0].type)&&dt(t.parentNode)||t)){f.splice(a,1),e=s.length&&mt(f);if(!e)return P.apply(i,s),i;break}}}return(p||u(e,d))(s,t,!v,i,et.test(e)&&dt(t.parentNode)||t),i},n.sortStable=w.split("").sort(k).join("")===w,n.detectDuplicates=!!c,h(),n.sortDetached=at(function(e){return e.compareDocumentPosition(p.createElement("div"))&1}),at(function(e){return e.innerHTML="",e.firstChild.getAttribute("href")==="#"})||ft("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,t.toLowerCase()==="type"?1:2)}),(!n.attributes||!at(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),e.firstChild.getAttribute("value")===""}))&&ft("value",function(e,t,n){if(!n&&e.nodeName.toLowerCase()==="input")return e.defaultValue}),at(function(e){return e.getAttribute("disabled")==null})||ft(j,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),st}(window);jQuery.find=Sizzle,jQuery.expr=Sizzle.selectors,jQuery.expr[":"]=jQuery.expr.pseudos,jQuery.unique=Sizzle.uniqueSort,jQuery.text=Sizzle.getText,jQuery.isXMLDoc=Sizzle.isXML,jQuery.contains=Sizzle.contains;var rneedsContext=jQuery.expr.match.needsContext,rsingleTag=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,risSimple=/^.[^:#\[\.,]*$/;jQuery.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),t.length===1&&r.nodeType===1?jQuery.find.matchesSelector(r,e)?[r]:[]:jQuery.find.matches(e,jQuery.grep(t,function(e){return e.nodeType===1}))},jQuery.fn.extend({find:function(e){var t,n=this.length,r=[],i=this;if(typeof e!="string")return this.pushStack(jQuery(e).filter(function(){for(t=0;t1?jQuery.unique(r):r),r.selector=this.selector?this.selector+" "+e:e,r},filter:function(e){return this.pushStack(winnow(this,e||[],!1))},not:function(e){return this.pushStack(winnow(this,e||[],!0))},is:function(e){return!!winnow(this,typeof e=="string"&&rneedsContext.test(e)?jQuery(e):e||[],!1).length}});var rootjQuery,rquickExpr=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,init=jQuery.fn.init=function(e,t){var n,r;if(!e)return this;if(typeof e=="string"){e[0]==="<"&&e[e.length-1]===">"&&e.length>=3?n=[null,e,null]:n=rquickExpr.exec(e);if(n&&(n[1]||!t)){if(n[1]){t=t instanceof jQuery?t[0]:t,jQuery.merge(this,jQuery.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:document,!0));if(rsingleTag.test(n[1])&&jQuery.isPlainObject(t))for(n in t)jQuery.isFunction(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}return r=document.getElementById(n[2]),r&&r.parentNode&&(this.length=1,this[0]=r),this.context=document,this.selector=e,this}return!t||t.jquery?(t||rootjQuery).find(e):this.constructor(t).find(e)}return e.nodeType?(this.context=this[0]=e,this.length=1,this):jQuery.isFunction(e)?typeof rootjQuery.ready!="undefined"?rootjQuery.ready(e):e(jQuery):(e.selector!==undefined&&(this.selector=e.selector,this.context=e.context),jQuery.makeArray(e,this))};init.prototype=jQuery.fn,rootjQuery=jQuery(document);var rparentsprev=/^(?:parents|prev(?:Until|All))/,guaranteedUnique={children:!0,contents:!0,next:!0,prev:!0};jQuery.extend({dir:function(e,t,n){var r=[],i=n!==undefined;while((e=e[t])&&e.nodeType!==9)if(e.nodeType===1){if(i&&jQuery(e).is(n))break;r.push(e)}return r},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}}),jQuery.fn.extend({has:function(e){var t=jQuery(e,this),n=t.length;return this.filter(function(){var e=0;for(;e-1:n.nodeType===1&&jQuery.find.matchesSelector(n,e))){s.push(n);break}return this.pushStack(s.length>1?jQuery.unique(s):s)},index:function(e){return e?typeof e=="string"?indexOf.call(jQuery(e),this[0]):indexOf.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),jQuery(e,t))))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),jQuery.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return jQuery.dir(e,"parentNode")},parentsUntil:function(e,t,n){return jQuery.dir(e,"parentNode",n)},next:function(e){return sibling(e,"nextSibling")},prev:function(e){return sibling(e,"previousSibling")},nextAll:function(e){return jQuery.dir(e,"nextSibling")},prevAll:function(e){return jQuery.dir(e,"previousSibling")},nextUntil:function(e,t,n){return jQuery.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return jQuery.dir(e,"previousSibling",n)},siblings:function(e){return jQuery.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return jQuery.sibling(e.firstChild)},contents:function(e){return e.contentDocument||jQuery.merge([],e.childNodes)}},function(e,t){jQuery.fn[e]=function(n,r){var i=jQuery.map(this,t,n);return e.slice(-5)!=="Until"&&(r=n),r&&typeof r=="string"&&(i=jQuery.filter(r,i)),this.length>1&&(guaranteedUnique[e]||jQuery.unique(i),rparentsprev.test(e)&&i.reverse()),this.pushStack(i)}});var rnotwhite=/\S+/g,optionsCache={};jQuery.Callbacks=function(e){e=typeof e=="string"?optionsCache[e]||createOptions(e):jQuery.extend({},e);var t,n,r,i,s,o,u=[],a=!e.once&&[],f=function(c){t=e.memory&&c,n=!0,o=i||0,i=0,s=u.length,r=!0;for(;u&&o-1)u.splice(n,1),r&&(n<=s&&s--,n<=o&&o--)}),this},has:function(e){return e?jQuery.inArray(e,u)>-1:!!u&&!!u.length},empty:function(){return u=[],s=0,this},disable:function(){return u=a=t=undefined,this},disabled:function(){return!u},lock:function(){return a=undefined,t||l.disable(),this},locked:function(){return!a},fireWith:function(e,t){return u&&(!n||a)&&(t=t||[],t=[e,t.slice?t.slice():t],r?a.push(t):f(t)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!n}};return l},jQuery.extend({Deferred:function(e){var t=[["resolve","done",jQuery.Callbacks("once memory"),"resolved"],["reject","fail",jQuery.Callbacks("once memory"),"rejected"],["notify","progress",jQuery.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return jQuery.Deferred(function(n){jQuery.each(t,function(t,s){var o=jQuery.isFunction(e[t])&&e[t];i[s[1]](function(){var e=o&&o.apply(this,arguments);e&&jQuery.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s[0]+"With"](this===r?n.promise():this,o?[e]:arguments)})}),e=null}).promise()},promise:function(e){return e!=null?jQuery.extend(e,r):r}},i={};return r.pipe=r.then,jQuery.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=function(){return i[s[0]+"With"](this===i?r:this,arguments),this},i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=slice.call(arguments),r=n.length,i=r!==1||e&&jQuery.isFunction(e.promise)?r:0,s=i===1?e:jQuery.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?slice.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t0)return;readyList.resolveWith(document,[jQuery]),jQuery.fn.triggerHandler&&(jQuery(document).triggerHandler("ready"),jQuery(document).off("ready"))}}),jQuery.ready.promise=function(e){return readyList||(readyList=jQuery.Deferred(),document.readyState==="complete"?setTimeout(jQuery.ready):(document.addEventListener("DOMContentLoaded",completed,!1),window.addEventListener("load",completed,!1))),readyList.promise(e)},jQuery.ready.promise();var access=jQuery.access=function(e,t,n,r,i,s,o){var u=0,a=e.length,f=n==null;if(jQuery.type(n)==="object"){i=!0;for(u in n)jQuery.access(e,t,u,n[u],!0,s,o)}else if(r!==undefined){i=!0,jQuery.isFunction(r)||(o=!0),f&&(o?(t.call(e,r),t=null):(f=t,t=function(e,t,n){return f.call(jQuery(e),n)}));if(t)for(;u1,null,!0)},removeData:function(e){return this.each(function(){data_user.remove(this,e)})}}),jQuery.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=data_priv.get(e,t),n&&(!r||jQuery.isArray(n)?r=data_priv.access(e,t,jQuery.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=jQuery.queue(e,t),r=n.length,i=n.shift(),s=jQuery._queueHooks(e,t),o=function(){jQuery.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return data_priv.get(e,n)||data_priv.access(e,n,{empty:jQuery.Callbacks("once memory").add(function(){data_priv.remove(e,[t+"queue",n])})})}}),jQuery.fn.extend({queue:function(e,t){var n=2;return typeof e!="string"&&(t=e,e="fx",n--),arguments.lengthx",support.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue})();var strundefined=typeof undefined;support.focusinBubbles="onfocusin"in window;var rkeyEvent=/^key/,rmouseEvent=/^(?:mouse|pointer|contextmenu)|click/,rfocusMorph=/^(?:focusinfocus|focusoutblur)$/,rtypenamespace=/^([^.]*)(?:\.(.+)|)$/;jQuery.event={global:{},add:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,v,m=data_priv.get(e);if(!m)return;n.handler&&(s=n,n=s.handler,i=s.selector),n.guid||(n.guid=jQuery.guid++),(a=m.events)||(a=m.events={}),(o=m.handle)||(o=m.handle=function(t){return typeof jQuery!==strundefined&&jQuery.event.triggered!==t.type?jQuery.event.dispatch.apply(e,arguments):undefined}),t=(t||"").match(rnotwhite)||[""],f=t.length;while(f--){u=rtypenamespace.exec(t[f])||[],p=v=u[1],d=(u[2]||"").split(".").sort();if(!p)continue;c=jQuery.event.special[p]||{},p=(i?c.delegateType:c.bindType)||p,c=jQuery.event.special[p]||{},l=jQuery.extend({type:p,origType:v,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&jQuery.expr.match.needsContext.test(i),namespace:d.join(".")},s),(h=a[p])||(h=a[p]=[],h.delegateCount=0,(!c.setup||c.setup.call(e,r,d,o)===!1)&&e.addEventListener&&e.addEventListener(p,o,!1)),c.add&&(c.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),i?h.splice(h.delegateCount++,0,l):h.push(l),jQuery.event.global[p]=!0}},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,v,m=data_priv.hasData(e)&&data_priv.get(e);if(!m||!(a=m.events))return;t=(t||"").match(rnotwhite)||[""],f=t.length;while(f--){u=rtypenamespace.exec(t[f])||[],p=v=u[1],d=(u[2]||"").split(".").sort();if(!p){for(p in a)jQuery.event.remove(e,p+t[f],n,r,!0);continue}c=jQuery.event.special[p]||{},p=(r?c.delegateType:c.bindType)||p,h=a[p]||[],u=u[2]&&new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),o=s=h.length;while(s--)l=h[s],(i||v===l.origType)&&(!n||n.guid===l.guid)&&(!u||u.test(l.namespace))&&(!r||r===l.selector||r==="**"&&l.selector)&&(h.splice(s,1),l.selector&&h.delegateCount--,c.remove&&c.remove.call(e,l));o&&!h.length&&((!c.teardown||c.teardown.call(e,d,m.handle)===!1)&&jQuery.removeEvent(e,p,m.handle),delete a[p])}jQuery.isEmptyObject(a)&&(delete m.handle,data_priv.remove(e,"events"))},trigger:function(e,t,n,r){var i,s,o,u,a,f,l,c=[n||document],h=hasOwn.call(e,"type")?e.type:e,p=hasOwn.call(e,"namespace")?e.namespace.split("."):[];s=o=n=n||document;if(n.nodeType===3||n.nodeType===8)return;if(rfocusMorph.test(h+jQuery.event.triggered))return;h.indexOf(".")>=0&&(p=h.split("."),h=p.shift(),p.sort()),a=h.indexOf(":")<0&&"on"+h,e=e[jQuery.expando]?e:new jQuery.Event(h,typeof e=="object"&&e),e.isTrigger=r?2:3,e.namespace=p.join("."),e.namespace_re=e.namespace?new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=undefined,e.target||(e.target=n),t=t==null?[e]:jQuery.makeArray(t,[e]),l=jQuery.event.special[h]||{};if(!r&&l.trigger&&l.trigger.apply(n,t)===!1)return;if(!r&&!l.noBubble&&!jQuery.isWindow(n)){u=l.delegateType||h,rfocusMorph.test(u+h)||(s=s.parentNode);for(;s;s=s.parentNode)c.push(s),o=s;o===(n.ownerDocument||document)&&c.push(o.defaultView||o.parentWindow||window)}i=0;while((s=c[i++])&&!e.isPropagationStopped())e.type=i>1?u:l.bindType||h,f=(data_priv.get(s,"events")||{})[e.type]&&data_priv.get(s,"handle"),f&&f.apply(s,t),f=a&&s[a],f&&f.apply&&jQuery.acceptData(s)&&(e.result=f.apply(s,t),e.result===!1&&e.preventDefault());return e.type=h,!r&&!e.isDefaultPrevented()&&(!l._default||l._default.apply(c.pop(),t)===!1)&&jQuery.acceptData(n)&&a&&jQuery.isFunction(n[h])&&!jQuery.isWindow(n)&&(o=n[a],o&&(n[a]=null),jQuery.event.triggered=h,n[h](),jQuery.event.triggered=undefined,o&&(n[a]=o)),e.result},dispatch:function(e){e=jQuery.event.fix(e);var t,n,r,i,s,o=[],u=slice.call(arguments),a=(data_priv.get(this,"events")||{})[e.type]||[],f=jQuery.event.special[e.type]||{};u[0]=e,e.delegateTarget=this;if(f.preDispatch&&f.preDispatch.call(this,e)===!1)return;o=jQuery.event.handlers.call(this,e,a),t=0;while((i=o[t++])&&!e.isPropagationStopped()){e.currentTarget=i.elem,n=0;while((s=i.handlers[n++])&&!e.isImmediatePropagationStopped())if(!e.namespace_re||e.namespace_re.test(s.namespace))e.handleObj=s,e.data=s.data,r=((jQuery.event.special[s.origType]||{}).handle||s.handler).apply(i.elem,u),r!==undefined&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation())}return f.postDispatch&&f.postDispatch.call(this,e),e.result},handlers:function(e,t){var n,r,i,s,o=[],u=t.delegateCount,a=e.target;if(u&&a.nodeType&&(!e.button||e.type!=="click"))for(;a!==this;a=a.parentNode||this)if(a.disabled!==!0||e.type!=="click"){r=[];for(n=0;n=0:jQuery.find(i,this,null,[a]).length),r[i]&&r.push(s);r.length&&o.push({elem:a,handlers:r})}return u]*)\/>/gi,rtagName=/<([\w:]+)/,rhtml=/<|&#?\w+;/,rnoInnerhtml=/<(?:script|style|link)/i,rchecked=/checked\s*(?:[^=]|=\s*.checked.)/i,rscriptType=/^$|\/(?:java|ecma)script/i,rscriptTypeMasked=/^true\/(.*)/,rcleanScript=/^\s*\s*$/g,wrapMap={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};wrapMap.optgroup=wrapMap.option,wrapMap.tbody=wrapMap.tfoot=wrapMap.colgroup=wrapMap.caption=wrapMap.thead,wrapMap.th=wrapMap.td,jQuery.extend({clone:function(e,t,n){var r,i,s,o,u=e.cloneNode(!0),a=jQuery.contains(e.ownerDocument,e);if(!support.noCloneChecked&&(e.nodeType===1||e.nodeType===11)&&!jQuery.isXMLDoc(e)){o=getAll(u),s=getAll(e);for(r=0,i=s.length;r0&&setGlobalEval(o,!a&&getAll(e,"script")),u},buildFragment:function(e,t,n,r){var i,s,o,u,a,f,l=t.createDocumentFragment(),c=[],h=0,p=e.length;for(;h")+u[2],f=u[0];while(f--)s=s.lastChild;jQuery.merge(c,s.childNodes),s=l.firstChild,s.textContent=""}}l.textContent="",h=0;while(i=c[h++]){if(r&&jQuery.inArray(i,r)!==-1)continue;a=jQuery.contains(i.ownerDocument,i),s=getAll(l.appendChild(i),"script"),a&&setGlobalEval(s);if(n){f=0;while(i=s[f++])rscriptType.test(i.type||"")&&n.push(i)}}return l},cleanData:function(e){var t,n,r,i,s=jQuery.event.special,o=0;for(;(n=e[o])!==undefined;o++){if(jQuery.acceptData(n)){i=n[data_priv.expando];if(i&&(t=data_priv.cache[i])){if(t.events)for(r in t.events)s[r]?jQuery.event.remove(n,r):jQuery.removeEvent(n,r,t.handle);data_priv.cache[i]&&delete data_priv.cache[i]}}delete data_user.cache[n[data_user.expando]]}}}),jQuery.fn.extend({text:function(e){return access(this,function(e){return e===undefined?jQuery.text(this):this.empty().each(function(){if(this.nodeType===1||this.nodeType===11||this.nodeType===9)this.textContent=e})},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var t=manipulationTarget(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var t=manipulationTarget(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?jQuery.filter(e,this):this,i=0;for(;(n=r[i])!=null;i++)!t&&n.nodeType===1&&jQuery.cleanData(getAll(n)),n.parentNode&&(t&&jQuery.contains(n.ownerDocument,n)&&setGlobalEval(getAll(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++)e.nodeType===1&&(jQuery.cleanData(getAll(e,!1)),e.textContent="");return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return jQuery.clone(this,e,t)})},html:function(e){return access(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&t.nodeType===1)return t.innerHTML;if(typeof e=="string"&&!rnoInnerhtml.test(e)&&!wrapMap[(rtagName.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(rxhtmlTag,"<$1>");try{for(;n1&&typeof h=="string"&&!support.checkClone&&rchecked.test(h))return this.each(function(n){var r=l.eq(n);p&&(e[0]=h.call(this,n,r.html())),r.domManip(e,t)});if(f){n=jQuery.buildFragment(e,this[0].ownerDocument,!1,this),r=n.firstChild,n.childNodes.length===1&&(n=r);if(r){i=jQuery.map(getAll(n,"script"),disableScript),s=i.length;for(;a1)},show:function(){return showHide(this,!0)},hide:function(){return showHide(this)},toggle:function(e){return typeof e=="boolean"?e?this.show():this.hide():this.each(function(){isHidden(this)?jQuery(this).show():jQuery(this).hide()})}}),jQuery.Tween=Tween,Tween.prototype={constructor:Tween,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(jQuery.cssNumber[n]?"":"px")},cur:function(){var e=Tween.propHooks[this.prop];return e&&e.get?e.get(this):Tween.propHooks._default.get(this)},run:function(e){var t,n=Tween.propHooks[this.prop];return this.options.duration?this.pos=t=jQuery.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Tween.propHooks._default.set(this),this}},Tween.prototype.init.prototype=Tween.prototype,Tween.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=jQuery.css(e.elem,e.prop,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){jQuery.fx.step[e.prop]?jQuery.fx.step[e.prop](e):e.elem.style&&(e.elem.style[jQuery.cssProps[e.prop]]!=null||jQuery.cssHooks[e.prop])?jQuery.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Tween.propHooks.scrollTop=Tween.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},jQuery.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},jQuery.fx=Tween.prototype.init,jQuery.fx.step={};var fxNow,timerId,rfxtypes=/^(?:toggle|show|hide)$/,rfxnum=new RegExp("^(?:([+-])=|)("+pnum+")([a-z%]*)$","i"),rrun=/queueHooks$/,animationPrefilters=[defaultPrefilter],tweeners={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=rfxnum.exec(t),s=i&&i[3]||(jQuery.cssNumber[e]?"":"px"),o=(jQuery.cssNumber[e]||s!=="px"&&+r)&&rfxnum.exec(jQuery.css(n.elem,e)),u=1,a=20;if(o&&o[3]!==s){s=s||o[3],i=i||[],o=+r||1;do u=u||".5",o/=u,jQuery.style(n.elem,e,o+s);while(u!==(u=n.cur()/r)&&u!==1&&--a)}return i&&(o=n.start=+o||+r||0,n.unit=s,n.end=i[1]?o+(i[1]+1)*i[2]:+i[2]),n}]};jQuery.Animation=jQuery.extend(Animation,{tweener:function(e,t){jQuery.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r1)},removeAttr:function(e){return this.each(function(){jQuery.removeAttr(this,e)})}}),jQuery.extend({attr:function(e,t,n){var r,i,s=e.nodeType;if(!e||s===3||s===8||s===2)return;if(typeof e.getAttribute===strundefined)return jQuery.prop(e,t,n);if(s!==1||!jQuery.isXMLDoc(e))t=t.toLowerCase(),r=jQuery.attrHooks[t]||(jQuery.expr.match.bool.test(t)?boolHook:nodeHook);if(n===undefined)return r&&"get"in r&&(i=r.get(e,t))!==null?i:(i=jQuery.find.attr(e,t),i==null?undefined:i);if(n!==null)return r&&"set"in r&&(i=r.set(e,n,t))!==undefined?i:(e.setAttribute(t,n+""),n);jQuery.removeAttr(e,t)},removeAttr:function(e,t){var n,r,i=0,s=t&&t.match(rnotwhite);if(s&&e.nodeType===1)while(n=s[i++])r=jQuery.propFix[n]||n,jQuery.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!support.radioValue&&t==="radio"&&jQuery.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}}}),boolHook={set:function(e,t,n){return t===!1?jQuery.removeAttr(e,n):e.setAttribute(n,n),n}},jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g),function(e,t){var n=attrHandle[t]||jQuery.find.attr;attrHandle[t]=function(e,t,r){var i,s;return r||(s=attrHandle[t],attrHandle[t]=i,i=n(e,t,r)!=null?t.toLowerCase():null,attrHandle[t]=s),i}});var rfocusable=/^(?:input|select|textarea|button)$/i;jQuery.fn.extend({prop:function(e,t){return access(this,jQuery.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[jQuery.propFix[e]||e]})}}),jQuery.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(e,t,n){var r,i,s,o=e.nodeType;if(!e||o===3||o===8||o===2)return;return s=o!==1||!jQuery.isXMLDoc(e),s&&(t=jQuery.propFix[t]||t,i=jQuery.propHooks[t]),n!==undefined?i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&"get"in i&&(r=i.get(e,t))!==null?r:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||rfocusable.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),support.optSelected||(jQuery.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),jQuery.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){jQuery.propFix[this.toLowerCase()]=this});var rclass=/[\t\r\n\f]/g;jQuery.fn.extend({addClass:function(e){var t,n,r,i,s,o,u=typeof e=="string"&&e,a=0,f=this.length;if(jQuery.isFunction(e))return this.each(function(t){jQuery(this).addClass(e.call(this,t,this.className))});if(u){t=(e||"").match(rnotwhite)||[];for(;a=0)r=r.replace(" "+i+" "," ");o=e?jQuery.trim(r):"",n.className!==o&&(n.className=o)}}}return this},toggleClass:function(e,t){var n=typeof e;return typeof t=="boolean"&&n==="string"?t?this.addClass(e):this.removeClass(e):jQuery.isFunction(e)?this.each(function(n){jQuery(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var t,r=0,i=jQuery(this),s=e.match(rnotwhite)||[];while(t=s[r++])i.hasClass(t)?i.removeClass(t):i.addClass(t)}else if(n===strundefined||n==="boolean")this.className&&data_priv.set(this,"__className__",this.className),this.className=this.className||e===!1?"":data_priv.get(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1}});var rreturn=/\r/g;jQuery.fn.extend({val:function(e){var t,n,r,i=this[0];if(!arguments.length){if(i)return t=jQuery.valHooks[i.type]||jQuery.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&(n=t.get(i,"value"))!==undefined?n:(n=i.value,typeof n=="string"?n.replace(rreturn,""):n==null?"":n);return}return r=jQuery.isFunction(e),this.each(function(n){var i;if(this.nodeType!==1)return;r?i=e.call(this,n,jQuery(this).val()):i=e,i==null?i="":typeof i=="number"?i+="":jQuery.isArray(i)&&(i=jQuery.map(i,function(e){return e==null?"":e+""})),t=jQuery.valHooks[this.type]||jQuery.valHooks[this.nodeName.toLowerCase()];if(!t||!("set"in t)||t.set(this,i,"value")===undefined)this.value=i})}}),jQuery.extend({valHooks:{option:{get:function(e){var t=jQuery.find.attr(e,"value");return t!=null?t:jQuery.trim(jQuery.text(e))}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0)n=!0}return n||(e.selectedIndex=-1),s}}}}),jQuery.each(["radio","checkbox"],function(){jQuery.valHooks[this]={set:function(e,t){if(jQuery.isArray(t))return e.checked=jQuery.inArray(jQuery(e).val(),t)>=0}},support.checkOn||(jQuery.valHooks[this].get=function(e){return e.getAttribute("value")===null?"on":e.value})}),jQuery.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){jQuery.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),jQuery.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)}});var nonce=jQuery.now(),rquery=/\?/;jQuery.parseJSON=function(e){return JSON.parse(e+"")},jQuery.parseXML=function(e){var t,n;if(!e||typeof e!="string")return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(r){t=undefined}return(!t||t.getElementsByTagName("parsererror").length)&&jQuery.error("Invalid XML: "+e),t};var ajaxLocParts,ajaxLocation,rhash=/#.*$/,rts=/([?&])_=[^&]*/,rheaders=/^(.*?):[ \t]*([^\r\n]*)$/mg,rlocalProtocol=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,rnoContent=/^(?:GET|HEAD)$/,rprotocol=/^\/\//,rurl=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,prefilters={},transports={},allTypes="*/".concat("*");try{ajaxLocation=location.href}catch(e){ajaxLocation=document.createElement("a"),ajaxLocation.href="",ajaxLocation=ajaxLocation.href}ajaxLocParts=rurl.exec(ajaxLocation.toLowerCase())||[],jQuery.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ajaxLocation,type:"GET",isLocal:rlocalProtocol.test(ajaxLocParts[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":allTypes,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":jQuery.parseJSON,"text xml":jQuery.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?ajaxExtend(ajaxExtend(e,jQuery.ajaxSettings),t):ajaxExtend(jQuery.ajaxSettings,e)},ajaxPrefilter:addToPrefiltersOrTransports(prefilters),ajaxTransport:addToPrefiltersOrTransports(transports),ajax:function(e,t){function S(e,t,s,u){var f,m,g,b,E,S=t;if(y===2)return;y=2,o&&clearTimeout(o),n=undefined,i=u||"",w.readyState=e>0?4:0,f=e>=200&&e<300||e===304,s&&(b=ajaxHandleResponses(l,w,s)),b=ajaxConvert(l,b,w,f);if(f)l.ifModified&&(E=w.getResponseHeader("Last-Modified"),E&&(jQuery.lastModified[r]=E),E=w.getResponseHeader("etag"),E&&(jQuery.etag[r]=E)),e===204||l.type==="HEAD"?S="nocontent":e===304?S="notmodified":(S=b.state,m=b.data,g=b.error,f=!g);else{g=S;if(e||!S)S="error",e<0&&(e=0)}w.status=e,w.statusText=(t||S)+"",f?p.resolveWith(c,[m,S,w]):p.rejectWith(c,[w,S,g]),w.statusCode(v),v=undefined,a&&h.trigger(f?"ajaxSuccess":"ajaxError",[w,l,f?m:g]),d.fireWith(c,[w,S]),a&&(h.trigger("ajaxComplete",[w,l]),--jQuery.active||jQuery.event.trigger("ajaxStop"))}typeof e=="object"&&(t=e,e=undefined),t=t||{};var n,r,i,s,o,u,a,f,l=jQuery.ajaxSetup({},t),c=l.context||l,h=l.context&&(c.nodeType||c.jquery)?jQuery(c):jQuery.event,p=jQuery.Deferred(),d=jQuery.Callbacks("once memory"),v=l.statusCode||{},m={},g={},y=0,b="canceled",w={readyState:0,getResponseHeader:function(e){var t;if(y===2){if(!s){s={};while(t=rheaders.exec(i))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return t==null?null:t},getAllResponseHeaders:function(){return y===2?i:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return y||(e=g[n]=g[n]||e,m[e]=t),this},overrideMimeType:function(e){return y||(l.mimeType=e),this},statusCode:function(e){var t;if(e)if(y<2)for(t in e)v[t]=[v[t],e[t]];else w.always(e[w.status]);return this},abort:function(e){var t=e||b;return n&&n.abort(t),S(0,t),this}};p.promise(w).complete=d.add,w.success=w.done,w.error=w.fail,l.url=((e||l.url||ajaxLocation)+"").replace(rhash,"").replace(rprotocol,ajaxLocParts[1]+"//"),l.type=t.method||t.type||l.method||l.type,l.dataTypes=jQuery.trim(l.dataType||"*").toLowerCase().match(rnotwhite)||[""],l.crossDomain==null&&(u=rurl.exec(l.url.toLowerCase()),l.crossDomain=!(!u||u[1]===ajaxLocParts[1]&&u[2]===ajaxLocParts[2]&&(u[3]||(u[1]==="http:"?"80":"443"))===(ajaxLocParts[3]||(ajaxLocParts[1]==="http:"?"80":"443")))),l.data&&l.processData&&typeof l.data!="string"&&(l.data=jQuery.param(l.data,l.traditional)),inspectPrefiltersOrTransports(prefilters,l,t,w);if(y===2)return w;a=l.global,a&&jQuery.active++===0&&jQuery.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!rnoContent.test(l.type),r=l.url,l.hasContent||(l.data&&(r=l.url+=(rquery.test(r)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=rts.test(r)?r.replace(rts,"$1_="+nonce++):r+(rquery.test(r)?"&":"?")+"_="+nonce++)),l.ifModified&&(jQuery.lastModified[r]&&w.setRequestHeader("If-Modified-Since",jQuery.lastModified[r]),jQuery.etag[r]&&w.setRequestHeader("If-None-Match",jQuery.etag[r])),(l.data&&l.hasContent&&l.contentType!==!1||t.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+allTypes+"; q=0.01":""):l.accepts["*"]);for(f in l.headers)w.setRequestHeader(f,l.headers[f]);if(!l.beforeSend||l.beforeSend.call(c,w,l)!==!1&&y!==2){b="abort";for(f in{success:1,error:1,complete:1})w[f](l[f]);n=inspectPrefiltersOrTransports(transports,l,t,w);if(!n)S(-1,"No Transport");else{w.readyState=1,a&&h.trigger("ajaxSend",[w,l]),l.async&&l.timeout>0&&(o=setTimeout(function(){w.abort("timeout")},l.timeout));try{y=1,n.send(m,S)}catch(E){if(!(y<2))throw E;S(-1,E)}}return w}return w.abort()},getJSON:function(e,t,n){return jQuery.get(e,t,n,"json")},getScript:function(e,t){return jQuery.get(e,undefined,t,"script")}}),jQuery.each(["get","post"],function(e,t){jQuery[t]=function(e,n,r,i){return jQuery.isFunction(n)&&(i=i||r,r=n,n=undefined),jQuery.ajax({url:e,type:t,dataType:i,data:n,success:r})}}),jQuery.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){jQuery.fn[t]=function(e){return this.on(t,e)}}),jQuery._evalUrl=function(e){return jQuery.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},jQuery.fn.extend({wrapAll:function(e){var t;return jQuery.isFunction(e)?this.each(function(t){jQuery(this).wrapAll(e.call(this,t))}):(this[0]&&(t=jQuery(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return jQuery.isFunction(e)?this.each(function(t){jQuery(this).wrapInner(e.call(this,t))}):this.each(function(){var t=jQuery(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=jQuery.isFunction(e);return this.each(function(n){jQuery(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){jQuery.nodeName(this,"body")||jQuery(this).replaceWith(this.childNodes)}).end()}}),jQuery.expr.filters.hidden=function(e){return e.offsetWidth<=0&&e.offsetHeight<=0},jQuery.expr.filters.visible=function(e){return!jQuery.expr.filters.hidden(e)};var r20=/%20/g,rbracket=/\[\]$/,rCRLF=/\r?\n/g,rsubmitterTypes=/^(?:submit|button|image|reset|file)$/i,rsubmittable=/^(?:input|select|textarea|keygen)/i;jQuery.param=function(e,t){var n,r=[],i=function(e,t){t=jQuery.isFunction(t)?t():t==null?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};t===undefined&&(t=jQuery.ajaxSettings&&jQuery.ajaxSettings.traditional);if(jQuery.isArray(e)||e.jquery&&!jQuery.isPlainObject(e))jQuery.each(e,function(){i(this.name,this.value)});else for(n in e)buildParams(n,e[n],t,i);return r.join("&").replace(r20,"+")},jQuery.fn.extend({serialize:function(){return jQuery.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=jQuery.prop(this,"elements");return e?jQuery.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!jQuery(this).is(":disabled")&&rsubmittable.test(this.nodeName)&&!rsubmitterTypes.test(e)&&(this.checked||!rcheckableType.test(e))}).map(function(e,t){var n=jQuery(this).val();return n==null?null:jQuery.isArray(n)?jQuery.map(n,function(e){return{name:t.name,value:e.replace(rCRLF,"\r\n")}}):{name:t.name,value:n.replace(rCRLF,"\r\n")}}).get()}}),jQuery.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var xhrId=0,xhrCallbacks={},xhrSuccessStatus={0:200,1223:204},xhrSupported=jQuery.ajaxSettings.xhr();window.ActiveXObject&&jQuery(window).on("unload",function(){for(var e in xhrCallbacks)xhrCallbacks[e]()}),support.cors=!!xhrSupported&&"withCredentials"in xhrSupported,support.ajax=xhrSupported=!!xhrSupported,jQuery.ajaxTransport(function(e){var t;if(support.cors||xhrSupported&&!e.crossDomain)return{send:function(n,r){var i,s=e.xhr(),o=++xhrId;s.open(e.type,e.url,e.async,e.username,e.password);if(e.xhrFields)for(i in e.xhrFields)s[i]=e.xhrFields[i];e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),!e.crossDomain&&!n["X-Requested-With"]&&(n["X-Requested-With"]="XMLHttpRequest");for(i in n)s.setRequestHeader(i,n[i]);t=function(e){return function(){t&&(delete xhrCallbacks[o],t=s.onload=s.onerror=null,e==="abort"?s.abort():e==="error"?r(s.status,s.statusText):r(xhrSuccessStatus[s.status]||s.status,s.statusText,typeof s.responseText=="string"?{text:s.responseText}:undefined,s.getAllResponseHeaders()))}},s.onload=t(),s.onerror=t("error"),t=xhrCallbacks[o]=t("abort");try{s.send(e.hasContent&&e.data||null)}catch(u){if(t)throw u}},abort:function(){t&&t()}}}),jQuery.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return jQuery.globalEval(e),e}}}),jQuery.ajaxPrefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),jQuery.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=jQuery(" +{% for resource in plugins.resources.js %} + {% if resource.url %} + + {% else %} + + {% endif %} +{% endfor %} + +{% endblock %} + +{% block style %} + + {% for resource in plugins.resources.css %} + {% if resource.url %} + + {% else %} + + {% endif %} + {% endfor %} + {% for style in styles %} + + {% endfor %} +{% endblock %}