rb-scpt 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +497 -0
  3. data/doc/aem-manual/01_introduction.html +60 -0
  4. data/doc/aem-manual/02_apioverview.html +107 -0
  5. data/doc/aem-manual/03_packingandunpackingdata.html +135 -0
  6. data/doc/aem-manual/04_references.html +409 -0
  7. data/doc/aem-manual/05_targetingapplications.html +164 -0
  8. data/doc/aem-manual/06_buildingandsendingevents.html +229 -0
  9. data/doc/aem-manual/07_findapp.html +63 -0
  10. data/doc/aem-manual/08_examples.html +94 -0
  11. data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
  12. data/doc/aem-manual/index.html +56 -0
  13. data/doc/appscript-manual/01_introduction.html +94 -0
  14. data/doc/appscript-manual/02_aboutappscripting.html +247 -0
  15. data/doc/appscript-manual/03_quicktutorial.html +167 -0
  16. data/doc/appscript-manual/04_gettinghelp.html +188 -0
  17. data/doc/appscript-manual/05_keywordconversion.html +106 -0
  18. data/doc/appscript-manual/06_classesandenums.html +192 -0
  19. data/doc/appscript-manual/07_applicationobjects.html +211 -0
  20. data/doc/appscript-manual/08_realvsgenericreferences.html +96 -0
  21. data/doc/appscript-manual/09_referenceforms.html +241 -0
  22. data/doc/appscript-manual/10_referenceexamples.html +154 -0
  23. data/doc/appscript-manual/11_applicationcommands.html +245 -0
  24. data/doc/appscript-manual/12_commandexamples.html +138 -0
  25. data/doc/appscript-manual/13_performanceissues.html +142 -0
  26. data/doc/appscript-manual/14_notes.html +80 -0
  27. data/doc/appscript-manual/application_architecture.gif +0 -0
  28. data/doc/appscript-manual/application_architecture2.gif +0 -0
  29. data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
  30. data/doc/appscript-manual/index.html +62 -0
  31. data/doc/appscript-manual/relationships_example.gif +0 -0
  32. data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
  33. data/doc/full.css +106 -0
  34. data/doc/index.html +45 -0
  35. data/doc/mactypes-manual/01_introduction.html +54 -0
  36. data/doc/mactypes-manual/02_aliasclass.html +124 -0
  37. data/doc/mactypes-manual/03_fileurlclass.html +126 -0
  38. data/doc/mactypes-manual/04_unitsclass.html +100 -0
  39. data/doc/mactypes-manual/index.html +53 -0
  40. data/doc/osax-manual/01_introduction.html +67 -0
  41. data/doc/osax-manual/02_interface.html +147 -0
  42. data/doc/osax-manual/03_examples.html +73 -0
  43. data/doc/osax-manual/04_notes.html +61 -0
  44. data/doc/osax-manual/index.html +53 -0
  45. data/doc/rb-appscript-logo.png +0 -0
  46. data/extconf.rb +65 -0
  47. data/rb-scpt.gemspec +14 -0
  48. data/sample/AB_export_vcard.rb +31 -0
  49. data/sample/AB_list_people_with_emails.rb +13 -0
  50. data/sample/Add_iCal_event.rb +21 -0
  51. data/sample/Create_daily_iCal_todos.rb +75 -0
  52. data/sample/Export_Address_Book_phone_numbers.rb +59 -0
  53. data/sample/Hello_world.rb +21 -0
  54. data/sample/List_iTunes_playlist_names.rb +11 -0
  55. data/sample/Make_Mail_message.rb +33 -0
  56. data/sample/Open_file_in_TextEdit.rb +13 -0
  57. data/sample/Organize_Mail_messages.rb +61 -0
  58. data/sample/Print_folder_tree.rb +16 -0
  59. data/sample/Select_all_HTML_files.rb +14 -0
  60. data/sample/Set_iChat_status.rb +24 -0
  61. data/sample/Simple_Finder_GUI_Scripting.rb +18 -0
  62. data/sample/Stagger_Finder_windows.rb +25 -0
  63. data/sample/TextEdit_demo.rb +130 -0
  64. data/sample/iTunes_top40_to_html.rb +71 -0
  65. data/src/SendThreadSafe.c +380 -0
  66. data/src/SendThreadSafe.h +139 -0
  67. data/src/lib/_aem/aemreference.rb +1022 -0
  68. data/src/lib/_aem/codecs.rb +662 -0
  69. data/src/lib/_aem/connect.rb +205 -0
  70. data/src/lib/_aem/encodingsupport.rb +77 -0
  71. data/src/lib/_aem/findapp.rb +85 -0
  72. data/src/lib/_aem/mactypes.rb +251 -0
  73. data/src/lib/_aem/send.rb +279 -0
  74. data/src/lib/_aem/typewrappers.rb +59 -0
  75. data/src/lib/_appscript/defaultterminology.rb +277 -0
  76. data/src/lib/_appscript/referencerenderer.rb +245 -0
  77. data/src/lib/_appscript/reservedkeywords.rb +116 -0
  78. data/src/lib/_appscript/safeobject.rb +249 -0
  79. data/src/lib/_appscript/terminology.rb +471 -0
  80. data/src/lib/aem.rb +253 -0
  81. data/src/lib/appscript.rb +1075 -0
  82. data/src/lib/kae.rb +1489 -0
  83. data/src/lib/osax.rb +659 -0
  84. data/src/rbae.c +979 -0
  85. data/test/README +3 -0
  86. data/test/test_aemreference.rb +118 -0
  87. data/test/test_appscriptcommands.rb +152 -0
  88. data/test/test_appscriptreference.rb +106 -0
  89. data/test/test_codecs.rb +186 -0
  90. data/test/test_findapp.rb +26 -0
  91. data/test/test_mactypes.rb +79 -0
  92. data/test/test_osax.rb +54 -0
  93. data/test/testall.sh +10 -0
  94. metadata +145 -0
@@ -0,0 +1,138 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
+ <head>
4
+
5
+ <title>rb-appscript manual | 12. Command Examples</title>
6
+
7
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
8
+ <style type="text/css" media="all"><!--@import url(../full.css);--></style>
9
+
10
+ </head>
11
+ <body>
12
+
13
+ <h1><img src="../rb-appscript-logo.png" alt="rb-appscript" title="rb-appscript" /></h1>
14
+
15
+ <!-- top navigation -->
16
+ <div class="navbar">
17
+ <a href="11_applicationcommands.html">Previous</a> &bull;
18
+ <a href="index.html">Up</a> &bull;
19
+ <a href="13_performanceissues.html">Next</a>
20
+
21
+ <span>
22
+ <strong><a href="../appscript-manual/index.html">appscript</a></strong> /
23
+ <a href="../mactypes-manual/index.html">mactypes</a> /
24
+ <a href="../osax-manual/index.html">osax</a> /
25
+ <a href="../aem-manual/index.html">aem</a>
26
+ </span>
27
+ </div>
28
+
29
+ <!-- content -->
30
+ <div id="content">
31
+
32
+ <h2>12. Command Examples</h2>
33
+
34
+ <h3><code>get</code></h3>
35
+
36
+ <p>Get the name of every folder in the user's home folder:</p>
37
+
38
+ <pre><code># tell application "Finder" to get name of every folder of home
39
+
40
+ app('Finder').get(app.home.folders.name)</code></pre>
41
+
42
+ <p>Note that if the direct parameter is omitted from the argument list, the reference that the command is invoked on is used instead. For example, the above example would normally be written as:</p>
43
+
44
+ <pre><code>app('Finder').home.folders.name.get</code></pre>
45
+
46
+
47
+ <h3><code>set</code></h3>
48
+
49
+ <p>Set the content of a TextEdit document:</p>
50
+
51
+ <pre><code># tell application "TextEdit" to set text of document 1 to "Hello World"
52
+
53
+ app('TextEdit').documents[1].text.set('Hello World')</code></pre>
54
+
55
+
56
+ <h3><code>count</code></h3>
57
+
58
+ <p>Count the words in a TextEdit document:</p>
59
+
60
+ <pre><code># tell application "TextEdit" to count words of document 1
61
+
62
+ app('TextEdit').documents[1].words.count</code></pre>
63
+
64
+ <p>Count the items in the current user's home folder:</p>
65
+
66
+ <pre><code>#tell application "Finder" to count items of home
67
+
68
+ app('Finder').home.count(:each =&gt; :item)</code></pre>
69
+
70
+ <p>(Note that the <code>each</code> parameter is required in Finder's <code>count</code> command.)</p>
71
+
72
+
73
+ <h3><code>make</code></h3>
74
+
75
+ <p>Create a new TextEdit document:</p>
76
+
77
+ <pre><code># tell application "TextEdit" to make new document &not;
78
+ # with properties {text:"Hello World\n"}
79
+
80
+ app('TextEdit').make(
81
+ :new =&gt; :document,
82
+ :with_properties =&gt; {:text =&gt; "Hello World\n"})</code></pre>
83
+
84
+ <p>Append text to a TextEdit document:</p>
85
+
86
+ <pre><code># tell application "TextEdit" to make new paragraph &not;
87
+ # at end of text of document 1 &not;
88
+ # with properties {text:"Yesterday\nToday\nTomorrow\n"}
89
+
90
+ app('TextEdit').make(
91
+ :new =&gt; :paragraph,
92
+ :at =&gt; app.documents[1].text.end,
93
+ :with_data =&gt; "Yesterday\nToday\nTomorrow\n")</code></pre>
94
+
95
+ <p>Note that the <code>make</code> command's <code>at</code> parameter can be omitted for convenience, in which case the reference that the command is invoked on is used instead:</p>
96
+
97
+ <pre><code>app('TextEdit').documents[1].text.end.make(
98
+ :new =&gt; :paragraph,
99
+ :with_data =&gt; "Yesterday\nToday\nTomorrow\n")</code></pre>
100
+
101
+
102
+ <h3><code>duplicate</code></h3>
103
+
104
+ <p>Duplicate a folder to a disk, replacing an existing item if one exists:</p>
105
+
106
+ <pre><code># tell application "Finder" to &not;
107
+ # duplicate folder "Projects" of home to disk "Work" with replacing
108
+
109
+ app('Finder').home.folders['Projects'].duplicate(
110
+ :to =&gt; app.disks['Backup'], :replacing =&gt; true)</code></pre>
111
+
112
+
113
+ <h3><code>add</code></h3>
114
+
115
+ <p>Add every person with a known birthday to a group named "Birthdays":</p>
116
+
117
+ <pre><code># tell application "Address Book" to add &not;
118
+ # every person whose birth date is not missing value &not;
119
+ # to group "Birthdays"
120
+
121
+ app('Address Book').people[
122
+ its.birth_date.ne(:missing_value)
123
+ ].add(:to =&gt; app.groups['Birthdays'])</code></pre>
124
+
125
+
126
+
127
+ </div>
128
+
129
+ <!-- bottom navigation -->
130
+
131
+ <div class="footer">
132
+ <a href="11_applicationcommands.html">Previous</a> &bull;
133
+ <a href="index.html">Up</a> &bull;
134
+ <a href="13_performanceissues.html">Next</a>
135
+ </div>
136
+
137
+ </body>
138
+ </html>
@@ -0,0 +1,142 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
+ <head>
4
+
5
+ <title>rb-appscript manual | 13. Performance Issues</title>
6
+
7
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
8
+ <style type="text/css" media="all"><!--@import url(../full.css);--></style>
9
+
10
+ </head>
11
+ <body>
12
+
13
+ <h1><img src="../rb-appscript-logo.png" alt="rb-appscript" title="rb-appscript" /></h1>
14
+
15
+ <!-- top navigation -->
16
+ <div class="navbar">
17
+ <a href="12_commandexamples.html">Previous</a> &bull;
18
+ <a href="index.html">Up</a> &bull;
19
+ <a href="14_notes.html">Next</a>
20
+
21
+ <span>
22
+ <strong><a href="../appscript-manual/index.html">appscript</a></strong> /
23
+ <a href="../mactypes-manual/index.html">mactypes</a> /
24
+ <a href="../osax-manual/index.html">osax</a> /
25
+ <a href="../aem-manual/index.html">aem</a>
26
+ </span>
27
+ </div>
28
+
29
+ <!-- content -->
30
+ <div id="content">
31
+
32
+ <h2>13. Performance Issues</h2>
33
+
34
+ <h3>About performance</h3>
35
+
36
+ <p>Application scripting is subject to a number of potential performance bottlenecks:</p>
37
+
38
+ <ul>
39
+ <li>Sending Apple events is more expensive than calling local functions.</li>
40
+
41
+ <li>There may be significant overheads in how applications resolve individual object references.</li>
42
+
43
+ <li>Packing and unpacking large and/or complex values (e.g. a long list of object specifiers) can take an appreciable amount of time.</li>
44
+ </ul>
45
+
46
+ <p>Fortunately, it's often possible to minimise performance overheads by using fewer commands to do more work. Let's consider a typical example: obtaining the name of every person in <code>Address Book.app</code> who has a particular email address. There are several possible solutions to this, each with very different performance characteristics:</p>
47
+
48
+ <h3>The iterative OO-style approach</h3>
49
+
50
+
51
+ <p>While iterating over application objects and manipulating each in turn is a common technique, it's also the slowest by far:</p>
52
+
53
+ <pre><code>require "appscript"
54
+ include Appscript
55
+
56
+
57
+ desiredEmail = 'sam.brown@foo.com'
58
+
59
+ foundNames = []
60
+ app('Address Book').people.get.each do |person|
61
+ person.emails.get.each do |email|
62
+ if email.value.get == desiredEmail
63
+ foundNames.push(person.name.get)
64
+ end
65
+ end
66
+ end
67
+ p foundNames</code></pre>
68
+
69
+
70
+ <p>The above script sends one Apple event to get a list of references to all people, then one Apple event for each person to get a list of references to their emails, then one Apple event for each of those emails. Thus the time taken increases directly in proportion to the number of people in Address Book. If there's hundreds of people to search, that's hundreds of Apple events to be built, sent and individually resolved, and performance suffers as a result.</p>
71
+
72
+ <p>The solution, where possible, is to use fewer, more sophisticated commands to do the same job.</p>
73
+
74
+
75
+ <h3>The smart query-oriented approach</h3>
76
+
77
+ <p>While there are some situations where iterating over and manipulating each application object individually is the only option (for example, when setting a property in each object to a different value), in this case there is plenty of room for improvement. Depending on how well an application implements its AEOM support, it's possible to construct queries that identify more than one application object at a time, allowing a single command to manipulate multiple objects in a single operation.</p>
78
+
79
+ <p>In this case, the entire search can be performed using a single complex query sent to Address Book via a single Apple event:</p>
80
+
81
+ <pre><code>require "appscript"
82
+
83
+ include Appscript
84
+
85
+ desiredEmail = 'sam.brown@foo.com'
86
+
87
+ p app('Address Book').people[
88
+ its.emails.value.contains(desiredEmail)
89
+ ].name.get</code></pre>
90
+
91
+ <p>To explain:</p>
92
+
93
+ <ul>
94
+ <li>The query states: find the name of every person object that passes a specific test.</li>
95
+
96
+ <li>The test is: does a given value, 'sam.brown@foo.com', appear in a list that consists of the value of each email object contained by an individual person?</li>
97
+
98
+ <li>The command is: evaluate that query against the AEOM and get (return) the result, which is a list of zero or more strings: the names of the people matched by the query.</li>
99
+ </ul>
100
+
101
+
102
+ <h3>The hybrid solution</h3>
103
+
104
+ <p>While AEOM queries can be surprisingly powerful, there are still many problems too complex for the application to evaluate entirely by itself. For example, let's say that you want to obtain the name of every person who has an email addresses that uses a particular domain name. Unfortunately, this test is too complex to express as a single AEOM query; however, it can still be solved reasonably efficiently by obtaining all the data from the application up-front and processing it locally. For this we need: 1. the name of every person in the Address Book, and 2. each person's email addresses. Fortunately, each of these can be expressed in a single query, allowing all this data to be retrieved using just two <code>get</code> commands.</p>
105
+
106
+ <pre><code>require "appscript"
107
+ include Appscript
108
+
109
+ desiredDomain = 'foo.com'
110
+
111
+ domainPattern = Regexp.new(Regexp.escape('@'+desiredDomain) + '$')
112
+
113
+ # get a list of name strings
114
+ names = app('Address Book').people.name.get
115
+
116
+ # a list of lists of email strings
117
+ emailsOfEveryPerson = app('Address Book').people.emails.value.get
118
+
119
+ result = []
120
+ names.zip(emailsOfEveryPerson).each do |name, emails|
121
+ emails.each do |email|
122
+ if domainPattern.match(email):
123
+ result.push(name)
124
+ break
125
+ end
126
+ end
127
+ end
128
+ p result</code></pre>
129
+
130
+ <p>This solution isn't as fast as the pure-query approach, but is still far more efficient than iterating over and manipulating each of the application objects themselves.</p>
131
+ </div>
132
+
133
+ <!-- bottom navigation -->
134
+
135
+ <div class="footer">
136
+ <a href="12_commandexamples.html">Previous</a> &bull;
137
+ <a href="index.html">Up</a> &bull;
138
+ <a href="14_notes.html">Next</a>
139
+ </div>
140
+
141
+ </body>
142
+ </html>
@@ -0,0 +1,80 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
+ <head>
4
+
5
+ <title>rb-appscript manual | 14. Notes</title>
6
+
7
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
8
+ <style type="text/css" media="all"><!--@import url(../full.css);--></style>
9
+
10
+ </head>
11
+ <body>
12
+
13
+ <h1><img src="../rb-appscript-logo.png" alt="rb-appscript" title="rb-appscript" /></h1>
14
+
15
+ <!-- top navigation -->
16
+ <div class="navbar">
17
+ <a href="13_performanceissues.html">Previous</a> &bull;
18
+ <a href="index.html">Up</a>
19
+
20
+ <span>
21
+ <strong><a href="../appscript-manual/index.html">appscript</a></strong> /
22
+ <a href="../mactypes-manual/index.html">mactypes</a> /
23
+ <a href="../osax-manual/index.html">osax</a> /
24
+ <a href="../aem-manual/index.html">aem</a>
25
+ </span>
26
+ </div>
27
+
28
+ <!-- content -->
29
+ <div id="content">
30
+
31
+ <h2>14. Notes</h2>
32
+
33
+ <h3>Rubygems issues</h3>
34
+
35
+ <p>If using the appscript gem, don't forget to <code>require 'rubygems'</code> <em>before</em> requiring appscript, otherwise the appscript gem won't load. For example:</p>
36
+
37
+ <pre><code>begin
38
+ require 'rubygems'
39
+ rescue LoadError
40
+ end
41
+ require 'appscript'
42
+ ...</code></pre>
43
+
44
+
45
+ <h3>Security issues</h3>
46
+
47
+ <p>If including user names and/or passwords in remote application URLs, please note that appscript retains these URLs in both the <code>Terminology</code> module's internal cache and in the Application and Reference objects subsequently created from those URLs. Security here is the user's responsibility, as it's their code that creates and retains these objects.</p>
48
+
49
+
50
+ <h3>GUI Scripting</h3>
51
+
52
+ <p>Non-scriptable applications may in some cases be controlled from Ruby by using System Events to manipulate their graphical user interface. Note that the &quot;Enable access for assistive devices&quot; checkbox must be selected in the Universal Access system preferences pane for GUI Scripting to work.</p>
53
+
54
+
55
+ <h3>AEDescs</h3>
56
+
57
+ <p>Some applications (e.g. QuarkXpress) may return values which appscript cannot convert to equivalent Ruby types. These values are usually of types which are defined, used and understood only by that particular application, and will be represented in Ruby as raw <code>AE::AEDesc</code> objects (e.g. <code>#&lt;AE::AEDesc:0x33fc40&gt;</code>). While there's not much you can do with raw <code>AEDesc</code> objects within Ruby (it's best just to treat them as opaque types), subsequent commands can pass them back to the application for further use and/or conversion just like any other value.</p>
58
+
59
+
60
+ <h3>Credits</h3>
61
+
62
+ <p>Many thanks to Bill Birkett, Jordan Breeding, Fujimoto Hisakuni, Jordan K Hubbard, Alexander Kellett, Chris Nebel, Matt Neuburg, Laurent Sansonetti, Michelle Steiner, Kevin Van Vechten, and all the appscript users who've provided comments, criticisms and encouragement along the way.</p>
63
+
64
+
65
+ <h3>Website</h3>
66
+
67
+ <p><a href="http://appscript.sourceforge.net">http://appscript.sourceforge.net</a></p>
68
+
69
+
70
+ </div>
71
+
72
+ <!-- bottom navigation -->
73
+
74
+ <div class="footer">
75
+ <a href="13_performanceissues.html">Previous</a> &bull;
76
+ <a href="index.html">Up</a>
77
+ </div>
78
+
79
+ </body>
80
+ </html>
@@ -0,0 +1,62 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
+ <head>
4
+
5
+ <title>rb-appscript manual | Contents</title>
6
+
7
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
8
+ <style type="text/css" media="all"><!--@import url(../full.css);--></style>
9
+
10
+ </head>
11
+ <body>
12
+
13
+ <h1><img src="../rb-appscript-logo.png" alt="rb-appscript" title="rb-appscript" /></h1>
14
+
15
+ <!-- top navigation -->
16
+ <div class="navbar">
17
+ <a href="../index.html">Previous</a> &bull;
18
+ <a href="../index.html">Up</a> &bull;
19
+ <a href="01_introduction.html">Next</a>
20
+
21
+ <span>
22
+ <strong><a href="../appscript-manual/index.html">appscript</a></strong> /
23
+ <a href="../mactypes-manual/index.html">mactypes</a> /
24
+ <a href="../osax-manual/index.html">osax</a> /
25
+ <a href="../aem-manual/index.html">aem</a>
26
+ </span>
27
+ </div>
28
+
29
+ <!-- content -->
30
+ <div id="content">
31
+
32
+ <h2>Contents</h2>
33
+
34
+ <ol>
35
+ <li><a href="01_introduction.html">Introduction</a></li>
36
+ <li><a href="02_aboutappscripting.html">About Application Scripting</a></li>
37
+ <li><a href="03_quicktutorial.html">Quick Tutorial</a></li>
38
+ <li><a href="04_gettinghelp.html">Getting Help</a></li>
39
+ <li><a href="05_keywordconversion.html">Keyword Conversion</a></li>
40
+ <li><a href="06_classesandenums.html">Classes and Enumerated Types</a></li>
41
+ <li><a href="07_applicationobjects.html">Application Objects</a></li>
42
+ <li><a href="08_realvsgenericreferences.html">Real vs Generic References</a></li>
43
+ <li><a href="09_referenceforms.html">Reference Forms</a></li>
44
+ <li><a href="10_referenceexamples.html">Reference Examples</a></li>
45
+ <li><a href="11_applicationcommands.html">Application Commands</a></li>
46
+ <li><a href="12_commandexamples.html">Command Examples</a></li>
47
+ <li><a href="13_performanceissues.html">Performance Issues</a></li>
48
+ <li><a href="14_notes.html">Notes</a></li>
49
+ </ol>
50
+
51
+ </div>
52
+
53
+ <!-- bottom navigation -->
54
+
55
+ <div class="footer">
56
+ <a href="../index.html">Previous</a> &bull;
57
+ <a href="../index.html">Up</a> &bull;
58
+ <a href="01_introduction.html">Next</a>
59
+ </div>
60
+
61
+ </body>
62
+ </html>
@@ -0,0 +1,106 @@
1
+ body {font-family:Arial,sans-serif; line-height:140%; color:#000; background-color:#fff; margin: 0 12% 0 8%;}
2
+
3
+ /*headings*/
4
+
5
+ h2, h3, h4 {font-family: Palatino, Georgia, Serif; color:#00457e; background-color:transparent; font-weight:bold;}
6
+
7
+ h1 {font-family:Arial,sans-serif;color:#00457e; background-color:transparent; font-weight:bold;}
8
+
9
+ h1 {line-height:110%; padding: 0; margin-top:.7em; margin-bottom: .5em;}
10
+ h2 {font-size:1.6em; padding:0 0 1px; border-bottom:solid #f77700 2px; margin:1.4em 0 1em;}
11
+ h3 {font-size:1.3em; padding:0 0 0px; border-bottom:dotted #f77700 1px; margin:2em 0 0.8em 0;}
12
+ h4 {font-size:1.1em; margin:1.8em 0 0.6em 0;}
13
+
14
+
15
+ /*body text*/
16
+
17
+
18
+ p, li {margin: 1em 0;}
19
+ pre {font-size:1em;}
20
+
21
+
22
+ dl, pre {
23
+ line-height:130%; color:#000; background-color:#cedbef;
24
+ padding:1.8em 2em 2em; margin:1.2em 0em; border-bottom:solid #92b4db 6px;
25
+ }
26
+
27
+ dt, code {color:#00457e; background-color:transparent;}
28
+
29
+ dt {font-weight:bold;}
30
+
31
+
32
+ .hilitebox {padding:0.5em 0 0.55em; margin:1.3em 2em 1.4em; border:solid #f77700; border-width: 2px 0 2px; }
33
+
34
+ code {font-family:Courier,Monospace;}
35
+
36
+ pre code {color:#00406e; background-color:transparent;}
37
+
38
+
39
+ dd pre, .hilitebox pre {
40
+ color:#000; background-color:#cedbef;
41
+ padding:1.8em 2em 2em; margin:1.2em 2em 1.2em 0;
42
+ }
43
+
44
+
45
+ dd+dt {margin-top:1em;}
46
+ h3+p {margin-top:-0.3em;}
47
+ h2+h3 {margin-top: 1.2em;}
48
+ h4+p {margin-top:-0.35em;}
49
+
50
+
51
+ .comment {color:#666; background-color:transparent;}
52
+
53
+ hr {height: 1px; background-color: #00457e; border: 0px solid #00457e; margin-top:3em;}
54
+
55
+ dl hr {
56
+ color:#e8e8ff; background-color:transparent; height:1px;
57
+ border:dashed #00457e; border-width: 1px 0 0; margin:0 -2em;
58
+ }
59
+
60
+ table {
61
+ line-height:130%; width:100%; color:#00457e; background-color:#cedbef;
62
+ border-bottom:solid #cedbef 10px; margin:1.2em 0em 2.4em;
63
+ border-collapse:collapse; padding: 0 0 2em;
64
+ }
65
+
66
+ tr, th, td {padding: 0.4em 1.6em; margin: 0; border-width: 0;}
67
+
68
+ th {text-align:left; font-size:0.95em; color:#00457e; background-color:#92b4db;}
69
+
70
+ thead {background-color:#ccd;}
71
+
72
+
73
+ /*links*/
74
+
75
+ /*a {font-style:italic;}*/
76
+
77
+
78
+ a:link {color:#00457e; background-color:transparent;}
79
+ a:visited {color:#445555; background-color:transparent;}
80
+
81
+ a img {border-width:0;}
82
+
83
+ /* navigation*/
84
+
85
+ .navbar {
86
+ font-size:0.9em; font-weight:bold; color:#e06000; background-color: #cedbef;
87
+ padding: 0.45em 13px 0.3em; margin:0 0 0; border-bottom:solid #92b4db 6px;
88
+ }
89
+
90
+ .navbar span {float:right; font-weight:normal;}
91
+
92
+ .navbar span strong a {color: #e06000;}
93
+
94
+
95
+ .navbar a:link, .navbar a:visited, .footer a:link, .footer a:visited {font-style:normal; text-decoration:none;}
96
+ .navbar a:hover, .navbar a:active, .footer a:hover, .footer a:active {text-decoration:underline;}
97
+
98
+ /*footer*/
99
+
100
+ .footer {
101
+ font-size:0.9em; font-weight:bold; color:#e06000; background-color: #cedbef;
102
+ text-align:left; padding: 0.3em 13px 0.5em; margin:3.8em 0 0; border-top:solid #92b4db 6px;
103
+ }
104
+
105
+ .footer span {float:right; font-weight: normal; color:#00457e; background-color:#cedbef;}
106
+