<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity=60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<<importTiddlers>>
@@color(darkred):(2:30pm)@@: Meeting with Eric;

Deadline for abstract submission [[4th Southern California Symposium on Flow Physics (SoCal Fluids IV)|http://mae.eng.uci.edu/scfs2010/symposium.htm]] 
Plots are easy to create in MATLAB. A simple example is a 2D plot of the sine function. We want to plot {{{sin(x}}} for a range of //x// values. First we define the domain by 

{{{>>x=linspace(0,10,20);}}}

This produces a 1x20 set of values from 0 to 10. Note the semicolon will hide the values and not display them. The same set of valuescan be obtained using

{{{>>x=0:1/1.9:10;}}}

Typing

{{{>>y=sin(x);}}}

defines the vector of 20 values of {{{sin(x)}}} and stores them in {{{y}}}. This is not necessary for plotting.

Now we plot {{{y}}} vs {{{x}}}:

{{{>>plot(x,y)}}}

[img[Sine Function|plotsin.jpg]]

You can render the image with other attributes. You can make the plot red:

{{{>>plot(x,y,'r')}}}

[img[Sine Function in red|plotsinred.jpg]]

Other colors are possible using the following:

|b|blue|g|green|r|red|k|black|
|c|cyan|m|magenta|y|yellow| | |

One can also pick different linestyles:

|:|dotted| - | solid| -. | dashdot| --| dashed|

A plot with the dash-dot linestyle:

[img[Sine Function with dash-dot style|plotsindashdot.jpg]]

One can plot the values as data points by using various markers:

| . |point| o|circle| x|x-mark|
|+|plus|* |star|s|square|
|d|diamond|p|pentagram|v|triangle (down)|
|^ |triangle (up)| < |triangle (left)||>|triangle (right)|
|h|hexagram| | | |

Thus, a plot with red circles is obtained with

{{{>>plot(x,y,'ro')}}}

[img[Sine Function with markers|plotsinredcirc.jpg]]

One can also add text to the plots. The common texts needed would be the axis labels and titles. While these can be added to individual figures using the menus on the figure, they can also be put into the script.

For our plot, we can add

{{{>>title('Plot of sin(x)')}}}
{{{>>xlabel('x')}}}
{{{>>xlabel('sin(x)')}}}

[img[Sine Function with labels|plotsinlabels.jpg]]

We can also plot several functions. Let's plot markers for the above data and plot this with a more detailed version of the sine function with 200 points. This can be done using the folowing set of commands:

{{{>>x=linspace(0,10,20);}}}
{{{>>y=sin(x);}}}
{{{>>X=linspace(0,10,200);}}}
{{{>>Y=sin(X);}}}
{{{>>plot(x,y,'ro',X,Y,'b')}}}
{{{>>title('Plot of sin(x)')}}}
{{{>>xlabel('x')}}}
{{{>>xlabel('sin(x)')}}}

[img[Sine Function with labels|plot2funcs.jpg]]
!!Sports
{{alignBullets{
*@@color(darkblue):Hiking@@
*@@color(darkblue):Soccer@@
*@@color(darkblue):Basketball@@
*@@color(darkblue):Ping Pong@@
*@@color(darkblue):Beach Vball@@
/***
|Name|AdvancedOptionsPlugin|
|Source|http://www.TiddlyTools.com/#AdvancedOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#AdvancedOptionsPlugin|
|Version|1.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.3|
|Type|plugin|
|Requires||
|Overrides||
|Options|##Configuration|
|Description|automatically add plugin-defined options to the [[AdvancedOptions]] shadow tiddler|
!!!!!Usage
<<<
At document startup, this plugin examines each tiddler tagged with <<tag systemConfig>> and looks for a tiddler slice named "Options" whose value refers to a tiddler section (or separate tiddler) that contains an 'advanced options control panel' for configuring that plugin's features and behavior.  For each plugin that contains an "Options" slice, a tabbed entry is automatically created in the [[AdvancedOptions]] shadow tiddler to display that plugin's control panel.

As an optional fallback for backward-compatibility with plugin tiddlers that do not define the "Options" slice, this plugin will also look for a section heading named "Configuration" within those tiddlers, so that older plugins that define this section can automatically have their settings added to the [[AdvancedOptions]] tiddler without requiring the "Options" slice to be added.


<<<
!!!!!Configuration
<<<
<<option chkAdvancedOptions>> automatically add plugin-defined options to the [[AdvancedOptions]] shadow tiddler
<<option chkAdvancedOptionsBackstage>> automatically add plugin-defined options to Backstage menu
<<option chkAdvancedOptionsFallback>> use <<option txtAdvancedOptionsFallback>> section as a fallback for plugins that don't define an ~AdvancedOptions slice
//note: these settings only take effect after reloading the document//
<<<
!!!!!Revisions


<<<
2008.05.09 [1.1.0] add "options" panel to backstage
2008.04.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.AdvancedOptionsPlugin= {major: 1, minor: 1, revision: 0, date: new Date(2008,5,9)};

if (config.options.chkAdvancedOptions===undefined)
	config.options.chkAdvancedOptions=true;
if (config.options.chkAdvancedOptionsBackstage===undefined)
	config.options.chkAdvancedOptionsBackstage=true;
if (config.options.chkAdvancedOptionsFallback===undefined)
	config.options.chkAdvancedOptionsFallback=true;
if (config.options.txtAdvancedOptionsFallback===undefined)
	config.options.txtAdvancedOptionsFallback="Configuration";
if (config.optionsDesc) config.optionsDesc.chkAdvancedOptions=
	"automatically add plugin-defined options to [[AdvancedOptions]]";

var items=[];
var fmt="[[%0 ]] [[view options for %0]] [[%1]]\n";
var section=config.options.txtAdvancedOptionsFallback;
var plugins=store.getTaggedTiddlers("systemConfig");
for (var p=0; p<plugins.length; p++) {
	var tid=plugins[p].title;
	var settings=store.getTiddlerSlice(tid,"Options");
	if (!settings && config.options.chkAdvancedOptionsFallback && store.getTiddlerText(tid+"##"+section))
		settings="##"+section; // fallback handling for older plugins
	if (settings&&settings.length) {
		if (settings.substr(0,2)=="##") settings=tid+settings;
		items.push(fmt.format([tid,settings]));
	}
}
if (items.length) config.shadowTiddlers.PluginOptions=
	"!![[Plugin-defined options|PluginManager]]\n>@@text-align:left;<<tabs '' \n"+items.join(' ')+">>@@";

if (config.options.chkAdvancedOptions)
	config.shadowTiddlers.AdvancedOptions+="{{smallform{{{wrap{<<tiddler PluginOptions>>}}}}}}";

// add "options" backstage task
if (config.tasks && config.options.chkAdvancedOptionsBackstage) { // for TW2.2b3 or above
	config.tasks.options = {
		text: "options",
		tooltip: "manage plugin-defined option settings",
		content: "{{smallform{{{groupbox{{{wrap{<<tiddler PluginOptions>>}}}}}}\n{{groupbox small {<<options>>}}}}}}"

	}
	config.backstageTasks.splice(config.backstageTasks.indexOf("plugins")+1,0,"options");
}
//}}}
MATLAB was designed to handle matrices, but one can do simple arithmetical operations:

{{{>>5*3+6^2}}}
{{{>>sin(pi/2)}}}

You can define a row vector by typing

{{{>>[1 2 3]}}}

You can even name it 

{{{>>a=[1 2 3]}}}

or, name it but not display the result

{{{>>a=[1 2 3];}}}

A row vector is obtained by inserting semicolons:

{{{>>b = [1; 2; 3]}}}

Now you can do the same operations on each element. Typing 

{{{>>2*a}}} 

will produce [2 4 6]. But trying to square each element using 

{{{>>a^2}}} 

results in an error. You can avoid this error by using the operator .^:

{{{>>a.^2}}}

Since {{{a}}} is a 1x3 row vector and {{{b}}} is a 3x1 column vector, we can compute 

{{{>>b*a}}} 

to obtain the outer product resulting in a 3x3 matrix or we can compute 

{{{>>a*b}}}

to obtain the inner product.  
[[Getting Started]]
[[Arithmetic Operations]]
[[Built-in Functions]]
[[Matrices]]
[[2D Plotting]]
[[Scripts]]
[[Functions]]
v1 : 28-12-06

/***
|Name|BreadcrumbsPlugin|
|Author|Eric Shulman|
|Source|http://www.TiddlyTools.com/#BreadcrumbsPlugin|
|Documentation|http://www.TiddlyTools.com/#BreadcrumbsPluginInfo|
|Version|2.0.0|
|License|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.displayTiddler,TiddlyWiki.prototype.deleteTiddler|
|Options|##Configuration|
|Description|list/jump to tiddlers viewed during this session plus "back" button/macro|
This plugin provides a list of links to all tiddlers opened during the session, creating a "trail of breadcrumbs" from one tiddler to the next, allowing you to quickly navigate to any previously viewed tiddler, or select 'home' to reset the display to the initial set of tiddlers that were open at the start of the session (i.e., when the document was loaded into the browser).
!!!!!Documentation

<<<

see [[BreadcrumbsPluginInfo]]
<<<
!!!!!Configuration
<<<
<<option chkCreateDefaultBreadcrumbs>> automatically create breadcrumbs display (if needed)
<<option chkShowBreadcrumbs>> show/hide breadcrumbs display
<<option chkReorderBreadcrumbs>> re-order breadcrumbs when visiting a previously viewed tiddler
<<option chkBreadcrumbsHideHomeLink>> omit 'Home' link from breadcrumbs display

<<option chkShowStartupBreadcrumbs>> show breadcrumbs for 'startup' tiddlers

<<option chkBreadcrumbsReverse>> show breadcrumbs in reverse order (most recent first)
<<option chkBreadcrumbsLimit>> limit breadcrumbs display to {{twochar{<<option txtBreadcrumbsLimit>>}}} items
<<option chkBreadcrumbsLimitOpenTiddlers>> limit open tiddlers to {{twochar{<<option txtBreadcrumbsLimitOpenTiddlers>>}}} items

<<<

!!!!!Revisions
<<<
2008.05.01 [2.0.0] added 'limit open tiddlers' feature (with safety check for tiddler in edit mode)
| Please see [[BreadcrumbsPluginInfo]] for previous revision details |












2006.02.01 [1.0.0] initial release

<<<
!!!!!Code
***/
//{{{
version.extensions.BreadcrumbsPlugin= {major: 2, minor: 0, revision: 0, date: new Date("May 1, 2008")};

var co=config.options; // abbreviation

// show/hide display option (default is to SHOW breadcrumbs)
if (co.chkShowBreadcrumbs===undefined) co.chkShowBreadcrumbs=true;

// REORDER breadcrumbs when visiting previously viewed tiddler (default)
if (co.chkReorderBreadcrumbs===undefined) co.chkReorderBreadcrumbs=true;

// create default breadcrumbs display as needed (default is to CREATE)
if (co.chkCreateDefaultBreadcrumbs===undefined) co.chkCreateDefaultBreadcrumbs=true;

// show breadcrumbs for 'startup' tiddlers (default is FALSE = only show crumbs for tiddlers opened after startup)
if (co.chkShowStartupBreadcrumbs===undefined) co.chkShowStartupBreadcrumbs=false;

// show crumbs in reverse order (most recent first)
if (co.chkBreadcrumbsReverse===undefined) co.chkBreadcrumbsReverse=false;

// limit number of crumbs displayed
if (co.chkBreadcrumbsLimit===undefined) co.chkBreadcrumbsLimit=false;
if (co.txtBreadcrumbsLimit===undefined) co.txtBreadcrumbsLimit=5;

// limit number of open tiddlers
if (co.chkBreadcrumbsLimitOpenTiddlers===undefined) co.chkBreadcrumbsLimitOpenTiddlers=false;
if (co.txtBreadcrumbsLimitOpenTiddlers===undefined) co.txtBreadcrumbsLimitOpenTiddlers=3;

// omit home link from breadcrumbs display
if (co.chkBreadcrumbsHideHomeLink===undefined) co.chkBreadcrumbsHideHomeLink=false;

config.macros.breadcrumbs =  {
	crumbs: [], // the list of current breadcrumbs
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var area=createTiddlyElement(place,"span",null,"breadCrumbs",null);
		area.setAttribute("homeSep",params[0]?params[0]:this.homeSeparator); // custom home separator
		area.setAttribute("crumbSep",params[1]?params[1]:this.crumbSeparator); // custom crumb separator
		this.render(area);
	},
	add: function (title) {
		var thisCrumb = title;
		var ind = this.crumbs.indexOf(thisCrumb);
		if(ind === -1)
			this.crumbs.push(thisCrumb);
		else if (config.options.chkReorderBreadcrumbs)
			this.crumbs.push(this.crumbs.splice(ind,1)[0]); // reorder crumbs
		else
			this.crumbs=this.crumbs.slice(0,ind+1); // trim crumbs
		if (config.options.chkBreadcrumbsLimitOpenTiddlers)
			this.limitOpenTiddlers();
		this.refresh();
		return false;
	},
	getAreas: function() {
		var crumbAreas=[];
		// find all DIVs with classname=="breadCrumbs"

		// Note: use try/catch to avoid "Bad NPObject as private data" fatal error  caused when
		// some versions of embedded QuickTime player element is accessed by hasClass() function.
		var all=document.getElementsByTagName("*");
		for (var i=0; i<all.length; i++)
			try{ if (hasClass(all[i],"breadCrumbs")) crumbAreas.push(all[i]); } catch(e) {;}
		// find single DIV w/fixed ID (backward compatibility)
		var byID=document.getElementById("breadCrumbs")
		if (byID && !hasClass(byID,"breadCrumbs")) crumbAreas.push(byID);
		if (!crumbAreas.length && config.options.chkCreateDefaultBreadcrumbs) {
			// no existing crumbs display areas... create one...
			var defaultArea = createTiddlyElement(null,"span",null,"breadCrumbs",null);
		 	defaultArea.style.display= "none";
			var targetArea= document.getElementById("tiddlerDisplay");
		 	targetArea.parentNode.insertBefore(defaultArea,targetArea);
			crumbAreas.push(defaultArea);
		}
		return crumbAreas;
	},
	refresh: function() {
		var crumbAreas=this.getAreas();
		for (var i=0; i<crumbAreas.length; i++) {
			crumbAreas[i].style.display = config.options.chkShowBreadcrumbs?"block":"none";
			removeChildren(crumbAreas[i]);
			this.render(crumbAreas[i]);
		}
	},
	render: function(here) {
		var out=""

		var homeSep=here.getAttribute("homeSep"); if (!homeSep) homeSep=this.homeSeparator;
		var crumbSep=here.getAttribute("crumbSep"); if (!crumbSep) crumbSep=this.crumbSeparator;
		if (!config.options.chkBreadcrumbsHideHomeLink) {
			createTiddlyButton(here,"Home",null,this.home,"tiddlyLink tiddlyLinkExisting");
			out+=homeSep;
		}
		for (c=0; c<this.crumbs.length; c++) // remove non-existing tiddlers from crumbs
			if (!store.tiddlerExists(this.crumbs[c]) && !store.isShadowTiddler(this.crumbs[c]))
				this.crumbs.splice(c,1);
		var count=this.crumbs.length;
		if (config.options.chkBreadcrumbsLimit && config.options.txtBreadcrumbsLimit<count)
			count=config.options.txtBreadcrumbsLimit;
		var list=[];
		for (c=this.crumbs.length-count; c<this.crumbs.length; c++) list.push('[['+this.crumbs[c]+']]');
		if (config.options.chkBreadcrumbsReverse) list.reverse();
		out+=list.join(crumbSep);
		wikify(out,here);
	},
	home: function() {
		story.closeAllTiddlers();
		restart();
		config.macros.breadcrumbs.crumbs = [];
		var crumbAreas=config.macros.breadcrumbs.getAreas();
		for (var i=0; i<crumbAreas.length; i++) crumbAreas[i].style.display = "none";
		return false;
	},
	limitOpenTiddlers: function() {
		var limit=config.options.txtBreadcrumbsLimitOpenTiddlers; if (limit<1) limit=1;
		for (c=this.crumbs.length-1; c>=0; c--) {
			var tid=this.crumbs[c];
			var elem=document.getElementById(story.idPrefix+tid);
			if (elem) { // tiddler is displayed
				if (limit <=0) { // display limit has been reached
					if (elem.getAttribute("dirty")=="true") { // tiddler is being edited
						var msg="'"+tid+"' is currently being edited.\n\n";
						msg+="Press OK to save and close this tiddler\nor press Cancel to leave it opened";
						if (confirm(msg)) { story.saveTiddler(tid); story.closeTiddler(tid); }
					}
					else
						story.closeTiddler(this.crumbs[c]);
				}
				limit--;
			}
		}
	}
};
if (config.macros.breadcrumbs.homeSeparator==undefined) // note: not a cookie
	config.macros.breadcrumbs.homeSeparator=" | ";
if (config.macros.breadcrumbs.crumbSeparator==undefined)  // note: not a cookie
	config.macros.breadcrumbs.crumbSeparator=" > ";

config.commands.previousTiddler = {
	text: 'back',
	tooltip: 'view the previous tiddler',
	hideReadOnly: false,
	dateFormat: 'DDD, MMM DDth YYYY hh:0mm:0ss',
	handler: function(event,src,title) {
		var here=story.findContainingTiddler(src); if (!here) return;
		var crumbs=config.macros.breadcrumbs.crumbs;
		if (crumbs.length>1) {
			var crumb=crumbs[crumbs.length-2];
			story.displayTiddler(here,crumb);
		}
		else
			config.macros.breadcrumbs.home();
		return false;
	}
};

config.macros.previousTiddler= {
	label: 'back',
	prompt: 'view the previous tiddler',
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var label=params.shift(); if (!label) label=this.label;
		var prompt=params.shift(); if (!prompt) prompt=this.prompt;
		createTiddlyButton(place,label,prompt,function() {
			var crumbs=config.macros.breadcrumbs.crumbs;
			if (crumbs.length>1) {
				var crumb=crumbs[crumbs.length-2];
				story.displayTiddler(place,crumb);
			}
			else
				config.macros.breadcrumbs.home();
		});
	}
}

// hijack story.displayTiddler() so crumbs can be refreshed when a tiddler is displayed
if (Story.prototype.breadCrumbs_coreDisplayTiddler==undefined)
	Story.prototype.breadCrumbs_coreDisplayTiddler=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,tiddler,template,animate,slowly)
{
	var title=(tiddler instanceof Tiddler)?tiddler.title:tiddler;
	this.breadCrumbs_coreDisplayTiddler.apply(this,arguments);
	// if not displaying tiddler during document startup, then add it to the breadcrumbs
	// note: 'startingUp' flag is a global, set/reset by the core init() function
	if (!startingUp || config.options.chkShowStartupBreadcrumbs) config.macros.breadcrumbs.add(title);
}



// hijack store.removeTiddler() so crumbs can be refreshed when a tiddler is deleted
if (TiddlyWiki.prototype.breadCrumbs_coreRemoveTiddler==undefined)
	TiddlyWiki.prototype.breadCrumbs_coreRemoveTiddler=TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler= function(title)
{
	this.breadCrumbs_coreRemoveTiddler.apply(this,arguments);
	config.macros.breadcrumbs.refresh();
}
//}}}
/***
|Name|BreadcrumbsPluginInfo|
|Author|Eric Shulman|
|Source|http://www.TiddlyTools.com/#BreadcrumbsPlugin|
|Documentation|http://www.TiddlyTools.com/#BreadcrumbsPluginInfo|
|Version|2.0.0|
|License|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.displayTiddler,TiddlyWiki.prototype.removeTiddler|
|Description|Documentation for BreadcrumbsPlugin|
This plugin provides a list of links to all tiddlers opened during the session, creating a "trail of breadcrumbs" from one tiddler to the next, allowing you to quickly navigate to any previously viewed tiddler, or select 'home' to reset the display to the initial set of tiddlers that were open at the start of the session (i.e., when the document was loaded into the browser).
!!!!!Usage
<<<
syntax:
{{{
<<breadcrumbs homeSeparator crumbSeparator>>
}}}
By default, the breadcrumbs are displayed as a continuous, //horizontal// word-wrapped line of text, using default character sequences for ''homeSeparator'' (" | ") and ''crumbSeparator'' (" > ").  The //optional// ''homeSeparator'' and ''crumbSeparator'' macro parameters allow you to specify alternative separators.  For example, to display the breadcrumbs //vertically// (in a stack, rather than a row), set the separator values to use {{{[[<br>]]}}}... and, to display a horizontal line as the home separator, use {{{[[<html><hr></html>]]}}}.


<<<
!!!!!Examples:
<<<
{{{
<<breadcrumbs>>
}}}
<<breadcrumbs>>
{{{
<<breadcrumbs [[<html><hr></html>]] [[<br>]]>>

}}}
<<breadcrumbs [[<html><hr></html>]] [[<br>]]>>
<<<
!!!!!Customization
<<<
Using CSS and a few of the plugin configuration options (see below), you can make the breadcrumbs display resemble browser tabs by adding the following to your [[StyleSheet]]:
{{{
.breadCrumbs { border-bottom:1px solid; }
.breadCrumbs a {
	border: 1px solid; padding: 0px 1em;
	-moz-border-radius-topleft:.5em; -moz-border-radius-topright:.5em;
	-webkit-border-top-left-radius:.5em; -webkit-border-top-right-radius:.5em;
}
}}}
and this in [[ConfigTweaks]] (tagged with systemConfig, of course):
{{{
config.options.chkShowStartupBreadcrumbs=true;
config.options.chkBreadcrumbsLimitOpenTiddlers=true;
config.options.txtBreadcrumbsLimitOpenTiddlers=1;
config.macros.breadcrumbs.homeSeparator=" ";
config.macros.breadcrumbs.crumbSeparator=" ";
}}}


<<<
!!!!!Configuration
<<<
__''display placement:''__
<<option chkCreateDefaultBreadcrumbs>> automatically create breadcrumbs display (if needed)
{{{<<option chkCreateDefaultBreadcrumbs>>}}}
>By default, the plugin automatically creates the "breadCrumbs" display element at the top of the story column, just above the tiddlerDisplay area.  To manually control the display and placement of the breadcrumbs display, you can define a DIV with class="breadCrumbs" in a custom [[PageTemplate]] or embed the {{{<<breadcrumbs>>}}} macro in specific tiddler content.


>
>For example, to add the breadcrumbs below the mainMenu, change this:
{{{
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
}}}
>to:
{{{
<div id='mainMenu'>
	<div refresh='content' tiddler='MainMenu'></div>
	<div id='breadCrumbs' class='breadCrumbs'></div>

</div>
}}}
>You can also block automatic creation of the breadcrumbs display by setting
{{{
config.options.chkCreateDefaultBreadcrumbs=false;
}}}
>in a [[CookieJar]]/[[ConfigTweaks]] plugin tiddler.

__''other settings:''__
<<option chkShowBreadcrumbs>> show/hide breadcrumbs display
{{{<<option chkShowBreadcrumbs>>}}}
>This checkbox toggles the visibility of the breadcrumbs display.  However, the display is not updated until the next crumb is added (or a previous crumb is clicked on).  For immediate effect, the [[ToggleBreadcrumbs]] script uses [[InlineJavascriptPlugin]] to synchronize the checkbox setting and the breadcrumbs display.
<<option chkReorderBreadcrumbs>> re-order breadcrumbs when visiting a previously viewed tiddler
{{{<<option chkReorderBreadcrumbs>>}}}

>When visiting a previously viewed tiddler, the title of the most-recently displayed tiddler is simply moved to the end of the list and individual breadcrumbs are not removed from the list unless the underlying tiddler is deleted.  When ''re-ordering'' is disabled, the breadcrumbs list is ''trimmed'' so that all crumbs following that tiddler are removed from the list.

<<option chkBreadcrumbsHideHomeLink>> omit 'Home' link from breadcrumbs display
{{{<<option chkBreadcrumbsHideHomeLink>>}}}
>Enabling this option suppresses the automatic display of the "Home" link (and home separator).  To manually add the home link elsewhere in your document, use the following HTML:
{{{
<html><a href="javascript:;" onclick="config.macros.breadcrumbs.home()">home</a></html>

}}}
<<option chkShowStartupBreadcrumbs>> show breadcrumbs for 'startup' tiddlers
{{{<<option chkShowStartupBreadcrumbs>>}}}
>Breadcrumbs are usually only added for tiddlers that are opened after the document has been loaded, and not for tiddlers displayed during initial startup (e.g., [[DefaultTiddlers]]).  Enabling this option displays breadcrumbs for all viewed tiddlers, regardless of when they are opened.
<<option chkBreadcrumbsReverse>> show breadcrumbs in reverse order
{{{<<option chkBreadcrumbsReverse>>}}}
>As tiddlers are displayed, breadcrumbs are usually added to the //end// of the list.  Enabling this option displays breadcrumbs in reverse order, so that the most recently visited tiddlers are listed first.
<<option chkBreadcrumbsLimit>> limit breadcrumbs display to {{twochar{<<option txtBreadcrumbsLimit>>}}} items
{{{<<option chkBreadcrumbsLimit>>}}} and {{{<<option txtBreadcrumbsLimit>>}}}


>By default, breadcrumbs are displayed for all tiddlers that have been visited (unless the list is being 'trimmed' by disabling the chkReorderBreadcrumbs option above).  Enabling this option limits the display of the list to a maximum specified number of breadcrumbs.
<<option chkBreadcrumbsLimitOpenTiddlers>> limit open tiddlers to {{twochar{<<option txtBreadcrumbsLimitOpenTiddlers>>}}} items
{{{<<option chkBreadcrumbsLimitOpenTiddlers>>}}} and {{{<<option txtBreadcrumbsLimitOpenTiddlers>>}}}
>By default, tiddlers remain open (e.g., displayed in the story column) until you explicitly close them.  When this option is enabled, only the most recently opened tiddlers will remain open: ''any tiddlers in excess of the specified limit are automatically closed.''  //Note: for 'data safety', if a tiddler is being edited, you will be asked for permission to "save-and-close" that tiddler or leave it open (even if that would exceed the specified limit).//
<<<
!!!!!Revisions
<<<

2008.05.01 [2.0.0] added 'limit open tiddlers' feature (with safety check for tiddler in edit mode)
2008.04.06 [1.9.1] corrected 'limit' logic so that //last// N crumbs are shown instead of //first// N crumbs.  Also, added chkBreadcrumbsHideHomeLink
2008.04.04 [1.9.0] added chkBreadcrumbsReverse and chk/txtBreadcrumbsLimit
2008.03.29 [1.8.4] in displayTiddler(), get title from tiddler object (if needed).  Fixes errors caused when calling function passes a tiddler *object* instead of a tiddler *title*
2008.03.24 [1.8.3] include shadow tiddlers in breadcrumbs list.  Also changed settings so that "reordering" breadcrumbs is the default, instead of "trimming" the list
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.10.26 [1.8.2] documentation cleanup
2007.10.18 [1.8.1] in GetAreas(), use try/catch to avoid "Bad NPObject as private data" fatal error caused when embedded QuickTime player element is accessed by hasClass() function.
2007.10.02 [1.8.0] major documentation and code cleanup.  Moved config.breadCrumbs.* to config.macros.breadcrumbs.* to consolidate objects.  Also, fixed homeSeparator and crumbSeparator default handling.
2007.10.02 [1.7.0] added config.options.chkShowStartupBreadcrumbs option
2007.09.16 [1.6.1] in getAreas(), removed errant use of 'place' (was causing fatal error when creating default breadcrumbs display element).  Also, added chkCreateDefaultBreadcrumbs configuration setting to enable/disable automatic creation of a default breadcrumbs display.
2007.09.16 [1.6.0] re-wrote refresh() to enable multiple display instances, by finding elements with "breadCrumbs" classname.  Fallback to fixed ID (="breadCrumbs") is still used for backward-compatibility.  move rendering code from refresh() to separate render() function, and added definition for {{{<<breadCrumbs>>}}} macro to support embedding breadcrumbs displays in tiddler content.
2007.09.15 [1.5.9.1] updated documentation
2007.09.15 [1.5.9] defined homeSeparator (" | ") and crumbSeparator (" > ") as object properties so that they can be redefined as desired for different layouts (e.g., using 'newline' for the crumbSeparator will arrange crumbs in a column rather than a row.
2007.06.21 [1.5.8.1] in home(), return false to prevent IE from attempting to navigate away...
2007.05.26 [1.5.8] added support for {{{<<option chkReorderBreadcrumbs>>}}} to toggle trim vs. re-order behavior when visiting previously viewed tiddlers
2007.05.25 [1.5.7] added support for {{{<<option chkShowBreadcrumbs>>}}} to toggle //display// of breadcrumbs
2007.05.24 [1.5.6] in refresh(), remove non-existing tiddler titles from crumb list.  Also, hijack removeTiddler() so crumbs can be updated after tiddler is deleted.
2007.04.11 [1.5.5] added optional params to previousTiddler macro handler() to allow alternative label and tooltip text (instead of default "back")
2007.03.02 [1.5.4] in refresh(), for TW2.2, look for "storyDisplay" instead of "tiddlerDisplay" but keep fallback to "tiddlerDisplay" for TW2.1 or earlier
2007.02.24 [1.5.3] changed from hijack of onClickTiddlerLink to hijack of displayTiddler() so that ALL displayed tiddlers are recorded in the crumbs, including programmatically displayed tiddlers opened by macros, scripts, etc., (such as [[GotoPlugin]], among many others) in addition to those opened by clicks on links.
2007.02.24 [1.5.2.0] eliminated global space clutter by moving function and data declarations so they are contained inside config.breadCrumbs object.
2007.02.06 [1.5.1] added "previousTiddler" macro (for use in sidebar)
2007.02.05 [1.5.0] added "previousTiddler" toolbar command (aka, "back")
2006.08.04 [1.4.0.1] change spaces to tabs
2006.08.04 [1.4.0] modified from 1.4.0 distro: in refresh(), set {{{display:none/block}}} instead of {{{visibility:hidden/visible}}}.  In home(), check for valid crumbArea before setting style.
2006.08.02 [1.4.0] Fixed bug, the redefined onClickTiddlerLink_orig_breadCrumbs works incorrectly on IE
2006.07.20 [1.3.0] Runs compatibly with TW 2.1.0 (rev #403+)
2006.02.07 [1.2.0] change global array breadCrumbs to config.breadCrumbs by Eric's suggestion
2006.02.04 [1.1.0] JSLint checked
2006.02.01 [1.0.0] initial release


<<<
There are many 'Built-in Functions' in MATLAB. Some of the more commonly used functions are listed below. One can compute the value of a function appled to all elements of an array. For example, computing the exponential of each element of {{{A}}} is found  by 

{{{>>exp(A)}}}


|!Function |!Description  |!Function|!Description |!Function |!Description |
|acos  |Inverse cosine  |acosh |Inverse hyperbolic cosine|acot |Inverse cotangent|
|acoth |Inverse hyperbolic cotangent  |acsc    |Inverse cosecant  |acsh |Inverse hyperbolic cosecant|
|asec |Inverse secant |asech |Inverse hyperbolic secant |asin |Inverse sine |
|asinh |Inverse hyperbolic sine |atan |Inverse tangent |atanh |Inverse hyperbolic tangent|
|atan2 |Four-quadrant inverse tangent|cos |Cosine|cosh |Hyperbolic cosine |
|cot |Cotangent |coth |Hyperbolic cotangent |csc |Cosecant |
|csch |Hyperbolic cosecant |hypot |Square root of sum of squares |sec |Secant |
|sech |Hyperbolic secant |sin |Sine |sinh |Hyperbolic sine |
|tan |Tangent |tanh |Hyperbolic tangent |exp |Exponential|
|log |Natural logarithm |log2 |Base 2 logarithm|log10 |Common (base 10) logarithm|
|sqrt |Square root|nthroot |Real nth root| abs |Absolute value|
|angle |Phase angle |conj |Complex conjugate|i |Imaginary unit|
|imag|Complex imaginary part|j|Imaginary unit| real|Complex real part|
|sign |Signum|fix |Round towards zero |floor |Round towards minus infinity|
|ceil |Round towards plus infinity |round |Round towards nearest integer |mod |Modulus after division|
|rem |Remainder after division|factor |Prime factors |factorial |Factorial function |
|gcd |Greatest common divisor |isprime |Determine if input is prime number|lcm |Least common multiple|
|nchoosek |All combinations of N elements taken K at a time |perms |All possible permutations | primes|Generate list of prime numbers|
|rat, rats |Rational fraction approximation| | | | |
<html>
Here is a copy of my <a href="KouroshShoele_resume_rec.pdf">Resume</a> (Short version).  <a href="http://docs.google.com/viewer?url=http://fsisg.ucsd.edu/KouroshShoele_resume_rec.pdf">Online read</a>
</html>
<html>
Here is a copy of my <a href="KouroshShoele_CV_rec.pdf">CV</a> (detailed version). <a href="http://docs.google.com/viewer?url=http://fsisg.ucsd.edu/KouroshShoele_CV_rec.pdf">Online read</a>
</html>
<<calendar thismonth>> 
/***
|Name|CalendarPlugin|
|Source|http://www.TiddlyTools.com/#CalendarPlugin|
|Version|2008.09.09|
|Author|Eric Shulman|
|Original Author|SteveRumsby|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Options|##Configuration|
|Description|display monthly and yearly calendars|

NOTE: For enhanced date display (including popups), you must also install [[DatePlugin]]
!!!!!Usage:
<<<
|{{{<<calendar>>}}}|Produce a full-year calendar for the current year|
|{{{<<calendar year>>}}}|Produce a full-year calendar for the given year|
|{{{<<calendar year month>>}}}|Produce a one-month calendar for the given month and year|
|{{{<<calendar thismonth>>}}}|Produce a one-month calendar for the current month|
|{{{<<calendar lastmonth>>}}}|Produce a one-month calendar for last month|
|{{{<<calendar nextmonth>>}}}|Produce a one-month calendar for next month|
|{{{<<calendar +n>>}}}<br>{{{<<calendar -n>>}}}|Produce a one-month calendar for a month +/- 'n' months from now|
<<<
!!!!!Configuration:
<<<
|''First day of week:''<br>{{{config.options.txtCalFirstDay}}}|<<option txtCalFirstDay>>|(Monday = 0, Sunday = 6)|
|''First day of weekend:''<br>{{{config.options.txtCalStartOfWeekend}}}|<<option txtCalStartOfWeekend>>|(Monday = 0, Sunday = 6)|

<<option chkDisplayWeekNumbers>> Display week numbers //(note: Monday will be used as the start of the week)//
|''Week number display format:''<br>{{{config.options.txtWeekNumberDisplayFormat }}}|<<option txtWeekNumberDisplayFormat >>|
|''Week number link format:''<br>{{{config.options.txtWeekNumberLinkFormat }}}|<<option txtWeekNumberLinkFormat >>|
<<<
!!!!!Revisions
<<<
2008.09.10: added "+n" (and "-n") param to permit display of relative months (e.g., "+6" means "six months from now", "-3" means "three months ago".  Based on suggestion from Jean.
2008.06.17: added support for config.macros.calendar.todaybg
2008.02.27: in handler(), DON'T set hard-coded default date format, so that *customized* value (pre-defined in config.macros.calendar.journalDateFmt is used.
2008.02.17: in createCalendarYear(), fix next/previous year calculation (use parseInt() to convert to numeric value).  Also, use journalDateFmt for date linking when NOT using [[DatePlugin]].
2008.02.16: in createCalendarDay(), week numbers now created as TiddlyLinks, allowing quick creation/navigation to 'weekly' journals (based on request from Kashgarinn)
2008.01.08: in createCalendarMonthHeader(), "month year" heading is now created as TiddlyLink, allowing quick creation/navigation to 'month-at-a-time' journals
2007.11.30: added "return false" to onclick handlers (prevent IE from opening blank pages)
2006.08.23: added handling for weeknumbers (code supplied by Martin Budden (see "wn**" comment marks).  Also, incorporated updated by Jeremy Sheeley to add caching for reminders (see [[ReminderMacros]], if installed)
2005.10.30: in config.macros.calendar.handler(), use "tbody" element for IE compatibility.  Also, fix year calculation for IE's getYear() function (which returns '2005' instead of '105'). Also, in createCalendarDays(), use showDate() function (see [[DatePlugin]], if installed) to render autostyled date with linked popup.  Updated calendar stylesheet definition: use .calendar class-specific selectors, add text centering and margin settings
2006.05.29: added journalDateFmt handling
<<<
***/
/***
!!!!!Code section:
***/
//{{{
version.extensions.CalendarPlugin= { major: 0, minor: 7, revision: 0, date: new Date(2008, 6, 17)};

if(config.options.txtCalFirstDay == undefined)
  config.options.txtCalFirstDay = 0;
if(config.options.txtCalStartOfWeekend == undefined)
  config.options.txtCalStartOfWeekend = 5;
if(config.options.chkDisplayWeekNumbers == undefined)//wn**
  config.options.chkDisplayWeekNumbers = false;
if(config.options.chkDisplayWeekNumbers)
  config.options.txtCalFirstDay = 0;
if(config.options.txtWeekNumberDisplayFormat == undefined)//wn**
  config.options.txtWeekNumberDisplayFormat = "w0WW";
if(config.options.txtWeekNumberLinkFormat == undefined)//wn**
  config.options.txtWeekNumberLinkFormat = "YYYY-w0WW";

config.macros.calendar = {};
config.macros.calendar.monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
config.macros.calendar.daynames = ["M", "T", "W", "T", "F", "S", "S"];
config.macros.calendar.todaybg = "#ccccff";
config.macros.calendar.weekendbg = "#c0c0c0";
config.macros.calendar.monthbg = "#e0e0e0";
config.macros.calendar.holidaybg = "#ffc0c0";
config.macros.calendar.journalDateFmt = "DD MMM YYYY";
config.macros.calendar.monthdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
config.macros.calendar.holidays = [ ]; // Not sure this is required anymore - use reminders instead
//}}}
//{{{
function calendarIsHoliday(date) // Is the given date a holiday?
{
	var longHoliday = date.formatString("0DD/0MM/YYYY");
	var shortHoliday = date.formatString("0DD/0MM");
	for(var i = 0; i < config.macros.calendar.holidays.length; i++) {
		if(config.macros.calendar.holidays[i] == longHoliday || config.macros.calendar.holidays[i] == shortHoliday)
			return true;
	}
	return false;
}
//}}}
//{{{
config.macros.calendar.handler = function(place,macroName,params) {
	var calendar = createTiddlyElement(place, "table", null, "calendar", null);
	var tbody = createTiddlyElement(calendar, "tbody", null, null, null);
	var today = new Date();
	var year = today.getYear();
	if (year<1900) year+=1900;

 	// get format for journal link by reading from SideBarOptions (ELS 5/29/06 - based on suggestion by Martin Budden)
	var text = store.getTiddlerText("SideBarOptions");
	var re = new RegExp("<<(?:newJournal)([^>]*)>>","mg"); var fm = re.exec(text);
	if (fm && fm[1]!=null) { var pa=fm[1].readMacroParams(); if (pa[0]) this.journalDateFmt = pa[0]; }

	var month=-1;
	if (params[0] == "thismonth") {
		var month=today.getMonth();
	} else if (params[0] == "lastmonth") {
		var month = today.getMonth()-1; if (month==-1) { month=11; year--; }
	} else if (params[0] == "nextmonth") {
		var month = today.getMonth()+1; if (month>11) { month=0; year++; }
	} else if (params[0]&&"+-".indexOf(params[0].substr(0,1))!=-1) {
		var month = today.getMonth()+parseInt(params[0]);
		if (month>11) { year+=Math.floor(month/12); month%=12; };
		if (month<0)  { year+=Math.floor(month/12); month=12+month%12; }
	} else if (params[0]) {
		year = params[0];
		if(params[1]) month=parseInt(params[1])-1;
		if (month>11) month=11; if (month<0) month=0;
	}

	if (month!=-1) {
		cacheReminders(new Date(year, month, 1, 0, 0), 31);
		createCalendarOneMonth(tbody, year, month);
	} else {
		cacheReminders(new Date(year, 0, 1, 0, 0), 366);
		createCalendarYear(tbody, year);
	}
	window.reminderCacheForCalendar = null;
}
//}}}
//{{{
//This global variable is used to store reminders that have been cached
//while the calendar is being rendered.  It will be renulled after the calendar is fully rendered.
window.reminderCacheForCalendar = null;
//}}}
//{{{
function cacheReminders(date, leadtime)
{
	if (window.findTiddlersWithReminders == null) return;
	window.reminderCacheForCalendar = {};
	var leadtimeHash = [];
	leadtimeHash [0] = 0;
	leadtimeHash [1] = leadtime;
	var t = findTiddlersWithReminders(date, leadtimeHash, null, 1);
	for(var i = 0; i < t.length; i++) {
		//just tag it in the cache, so that when we're drawing days, we can bold this one.
		window.reminderCacheForCalendar[t[i]["matchedDate"]] = "reminder:" + t[i]["params"]["title"]; 
	}
}
//}}}
//{{{
function createCalendarOneMonth(calendar, year, mon)
{
	var row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, true, year, mon);
	row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarDayHeader(row, 1);
	createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarMonth(calendar, year, mon)
{
	var row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, false, year, mon);
	row = createTiddlyElement(calendar, "tr", null, null, null);
	createCalendarDayHeader(row, 1);
	createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}
//{{{
function createCalendarYear(calendar, year)
{
	var row;
	row = createTiddlyElement(calendar, "tr", null, null, null);
	var back = createTiddlyElement(row, "td", null, null, null);
	var backHandler = function() {
		removeChildren(calendar);
		createCalendarYear(calendar, parseInt(year)-1);
		return false; // consume click
	};
	createTiddlyButton(back, "<", "Previous year", backHandler);
	back.align = "center";
	var yearHeader = createTiddlyElement(row, "td", null, "calendarYear", year);
	yearHeader.align = "center";
	yearHeader.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?22:19);//wn**
	var fwd = createTiddlyElement(row, "td", null, null, null);
	var fwdHandler = function() {
		removeChildren(calendar);
		createCalendarYear(calendar, parseInt(year)+1);
		return false; // consume click
	};
	createTiddlyButton(fwd, ">", "Next year", fwdHandler);
	fwd.align = "center";
	createCalendarMonthRow(calendar, year, 0);
	createCalendarMonthRow(calendar, year, 3);
	createCalendarMonthRow(calendar, year, 6);
	createCalendarMonthRow(calendar, year, 9);
}
//}}}
//{{{
function createCalendarMonthRow(cal, year, mon)
{
	var row = createTiddlyElement(cal, "tr", null, null, null);
	createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon], false, year, mon);
	createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+1], false, year, mon);
	createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+2], false, year, mon);
	row = createTiddlyElement(cal, "tr", null, null, null);
	createCalendarDayHeader(row, 3);
	createCalendarDayRows(cal, year, mon);
}
//}}}
//{{{
function createCalendarMonthHeader(cal, row, name, nav, year, mon)
{
	var month;
	if (nav) {
		var back = createTiddlyElement(row, "td", null, null, null);
		back.align = "center";
		back.style.background = config.macros.calendar.monthbg;

		var backMonHandler = function() {
			var newyear = year;
			var newmon = mon-1;
			if(newmon == -1) { newmon = 11; newyear = newyear-1;}
			removeChildren(cal);
			cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
			createCalendarOneMonth(cal, newyear, newmon);
			return false; // consume click
		};
		createTiddlyButton(back, "<", "Previous month", backMonHandler);
		month = createTiddlyElement(row, "td", null, "calendarMonthname")
		createTiddlyLink(month,name,true);
		month.setAttribute("colSpan", config.options.chkDisplayWeekNumbers?6:5);//wn**
		var fwd = createTiddlyElement(row, "td", null, null, null);
		fwd.align = "center";
		fwd.style.background = config.macros.calendar.monthbg; 

		var fwdMonHandler = function() {
			var newyear = year;
			var newmon = mon+1;
			if(newmon == 12) { newmon = 0; newyear = newyear+1;}
			removeChildren(cal);
			cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
			createCalendarOneMonth(cal, newyear, newmon);
			return false; // consume click
		};
		createTiddlyButton(fwd, ">", "Next month", fwdMonHandler);
	} else {
		month = createTiddlyElement(row, "td", null, "calendarMonthname", name)
		month.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?8:7);//wn**
	}
	month.align = "center";
	month.style.background = config.macros.calendar.monthbg;
}
//}}}
//{{{
function createCalendarDayHeader(row, num)
{
	var cell;
	for(var i = 0; i < num; i++) {
		if (config.options.chkDisplayWeekNumbers) createTiddlyElement(row, "td");//wn**
		for(var j = 0; j < 7; j++) {
			var d = j + (config.options.txtCalFirstDay - 0);
			if(d > 6) d = d - 7;
			cell = createTiddlyElement(row, "td", null, null, config.macros.calendar.daynames[d]);
			if(d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))
				cell.style.background = config.macros.calendar.weekendbg;
		}
	}
}
//}}}
//{{{
function createCalendarDays(row, col, first, max, year, mon) {
	var i;
	if (config.options.chkDisplayWeekNumbers){
		if (first<=max) {
			var ww = new Date(year,mon,first);
			var td=createTiddlyElement(row, "td");//wn**
			var link=createTiddlyLink(td,ww.formatString(config.options.txtWeekNumberLinkFormat),false);
			link.appendChild(document.createTextNode(ww.formatString(config.options.txtWeekNumberDisplayFormat)));
		}
		else createTiddlyElement(row, "td", null, null, null);//wn**
	}
	for(i = 0; i < col; i++)
		createTiddlyElement(row, "td", null, null, null);
	var day = first;
	for(i = col; i < 7; i++) {
		var d = i + (config.options.txtCalFirstDay - 0);
		if(d > 6) d = d - 7;
		var daycell = createTiddlyElement(row, "td", null, null, null);
		var isaWeekend = ((d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))? true:false);
		if(day > 0 && day <= max) {
			var celldate = new Date(year, mon, day);
			// ELS 2005.10.30: use <<date>> macro's showDate() function to create popup
			// ELS 5/29/06 - use journalDateFmt 
			if (window.showDate)
				showDate(daycell,celldate,"popup","DD",config.macros.calendar.journalDateFmt,true, isaWeekend);
			else {
				if(isaWeekend) daycell.style.background = config.macros.calendar.weekendbg;
				var title = celldate.formatString(config.macros.calendar.journalDateFmt);
				if(calendarIsHoliday(celldate))
					daycell.style.background = config.macros.calendar.holidaybg;
				var now=new Date();
				if ((now-celldate>=0) && (now-celldate<86400000)) // is today?
					daycell.style.background = config.macros.calendar.todaybg;
				if(window.findTiddlersWithReminders == null) {
					var link = createTiddlyLink(daycell, title, false);
					link.appendChild(document.createTextNode(day));
				} else
					var button = createTiddlyButton(daycell, day, title, onClickCalendarDate);
			}
		}
		day++;
	}
}
//}}}
//{{{
// We've clicked on a day in a calendar - create a suitable pop-up of options.
// The pop-up should contain:
//  * a link to create a new entry for that date
//  * a link to create a new reminder for that date
//  * an <hr>
//  * the list of reminders for that date
// NOTE: The following code is only used when [[DatePlugin]] is not present
function onClickCalendarDate(e)
{
	var button = this;
	var date = button.getAttribute("title");
	var dat = new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0, 2));

	date = dat.formatString(config.macros.calendar.journalDateFmt);
	var popup = createTiddlerPopup(this);
	popup.appendChild(document.createTextNode(date));
	var newReminder = function() {
		var t = store.getTiddlers(date);
		displayTiddler(null, date, 2, null, null, false, false);
		if(t) {
			document.getElementById("editorBody" + date).value += "\n<<reminder day:" + dat.getDate() +
				" month:" + (dat.getMonth()+1) + " year:" + (dat.getYear()+1900) + " title: >>";
		} else {
			document.getElementById("editorBody" + date).value = "<<reminder day:" + dat.getDate() +
				" month:" + (dat.getMonth()+1) +" year:" + (dat.getYear()+1900) + " title: >>";
		}
		return false; // consume click
	};

	var link = createTiddlyButton(popup, "New reminder", null, newReminder); 
	popup.appendChild(document.createElement("hr"));
	var t = findTiddlersWithReminders(dat, [0,14], null, 1);
	for(var i = 0; i < t.length; i++) {
		link = createTiddlyLink(popup, t[i].tiddler, false);
		link.appendChild(document.createTextNode(t[i].tiddler));
	}
	return false; // consume click
}
//}}}
//{{{
function calendarMaxDays(year, mon)
{
	var max = config.macros.calendar.monthdays[mon];
	if(mon == 1 && (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) max++;
	return max;
}
//}}}
//{{{
function createCalendarDayRows(cal, year, mon)
{
	var row = createTiddlyElement(cal, "tr", null, null, null);
	var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first1 < 0) first1 = first1 + 7;
	var day1 = -first1 + 1;
	var first2 = (new Date(year, mon+1, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first2 < 0) first2 = first2 + 7;
	var day2 = -first2 + 1;
	var first3 = (new Date(year, mon+2, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first3 < 0) first3 = first3 + 7;
	var day3 = -first3 + 1;

	var max1 = calendarMaxDays(year, mon);
	var max2 = calendarMaxDays(year, mon+1);
	var max3 = calendarMaxDays(year, mon+2);

	while(day1 <= max1 || day2 <= max2 || day3 <= max3) {
		row = createTiddlyElement(cal, "tr", null, null, null);
		createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
		createCalendarDays(row, 0, day2, max2, year, mon+1); day2 += 7;
		createCalendarDays(row, 0, day3, max3, year, mon+2); day3 += 7;
	}
}
//}}}
//{{{
function createCalendarDayRowsSingle(cal, year, mon)
{
	var row = createTiddlyElement(cal, "tr", null, null, null);
	var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
	if(first1 < 0) first1 = first1+ 7;
	var day1 = -first1 + 1;
	var max1 = calendarMaxDays(year, mon);
	while(day1 <= max1) {
		row = createTiddlyElement(cal, "tr", null, null, null);
		createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
	}
}
//}}}
//{{{
setStylesheet(".calendar, .calendar table, .calendar th, .calendar tr, .calendar td { text-align:center; } .calendar, .calendar a { margin:0px !important; padding:0px !important; }", "calendarStyles");
//}}}
// // override cookie settings for CalendarPlugin:
//{{{
config.options.txtCalFirstDay=6;
config.options.txtCalStartOfWeekend=5;
//}}}

// // override internal default settings for CalendarPlugin:
//{{{
config.macros.calendar.journalDateFmt="DDD MMM 0DD YYYY";
//}}}
[[SE 102]]
<div macro='gradient vert #06a #058'><div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler templateChooser collapseOthers expandTiddler permalink references jump'></div>
<div class='title' macro='view title'></div></div>
<html>
<font size="3" color=darkblue> <b>Kourosh Shoele</b> </font>
<br>
<b>E-mail:</b> <font color=darkred>kshoele at ucsd dot edu </font> 


<br>
<b>Mailing address: </b>
<br> Department of Structural Engineering
<br> Jacobs School of Engineering
<br> University of California, San Diego
<br> 9500 Gilman Drive, MC 0085
<br> La Jolla, CA 92093-0085
</html>
/***
|Name|DatePlugin|
|Source|http://www.TiddlyTools.com/#DatePlugin|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.7.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Options|##Configuration|
|Description|formatted dates plus popup menu with 'journal' link, changes and (optional) reminders|
There are quite a few calendar generators, reminders, to-do lists, 'dated tiddlers' journals, blog-makers and GTD-like schedule managers that have been built around TW.  While they all have different purposes, and vary in format, interaction, and style, in one way or another each of these plugins displays and/or uses date-based information to make finding, accessing and managing relevant tiddlers easier.  This plugin provides a general approach to embedding dates and date-based links/menus within tiddler content.
!!!!!Documentation
>see [[DatePluginInfo]]
!!!!!Configuration
<<<
<<option chkDatePopupHideCreated>> omit 'created' section from date popups
<<option chkDatePopupHideChanged>> omit 'changed' section from date popups
<<option chkDatePopupHideTagged>> omit 'tagged' section from date popups
<<option chkDatePopupHideReminders>> omit 'reminders' section from date popups
<<option chkShowJulianDate>> display Julian day number (1-365) below current date

see [[DatePluginConfig]] for additional configuration settings, for use in calendar displays, including:
*date formats
*color-coded backgrounds
*annual fixed-date holidays
*weekends
<<<
!!!!!Revisions
<<<
2008.03.08 [2.7.0] in addModifiedsToPopup(), if a tiddler was created on the specified date, don't list it in the 'changed' section of the popup.  Based on a request from Kashgarinn.
|please see [[DatePluginInfo]] for additional revision details|
2005.10.30 [0.9.0] pre-release
<<<
!!!!!Code
***/
//{{{
version.extensions.DatePlugin= {major: 2, minor: 7, revision: 0, date: new Date(2008,3,8)};

config.macros.date = {
	format: "YYYY.0MM.0DD", // default date display format
	linkformat: "YYYY.0MM.0DD", // 'dated tiddler' link format
	linkedbg: "#babb1e", // "babble"
	todaybg: "#ffab1e", // "fable"
	weekendbg: "#c0c0c0", // "cocoa"
	holidaybg: "#ffaace", // "face"
	createdbg: "#bbeeff", // "beef"
	modifiedsbg: "#bbeeff", // "beef"
	remindersbg: "#c0ffee", // "coffee"
	holidays: [ "01/01", "07/04", "07/25", "11/16", "11/24" ], // NewYearsDay, IndependenceDay(US), Kourosh's Birthday (hooray!), Neda's Birthday Thanksgiving(US)
	weekend: [ 1,0,0,0,0,0,1 ] // [ day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6 ]
};

config.macros.date.handler = function(place,macroName,params)
{
	// do we want to see a link, a popup, or just a formatted date?
	var mode="display";
	if (params[0]=="display") { mode=params[0]; params.shift(); }
	if (params[0]=="popup") { mode=params[0]; params.shift(); }
	if (params[0]=="link") { mode=params[0]; params.shift(); }
	// get the date
	var now = new Date();
	var date = now;
	if (!params[0] || params[0]=="today")
		{ params.shift(); }
	else if (params[0]=="filedate")
		{ date=new Date(document.lastModified); params.shift(); }
	else if (params[0]=="tiddler")
		{ date=store.getTiddler(story.findContainingTiddler(place).id.substr(7)).modified; params.shift(); }
	else if (params[0].substr(0,8)=="tiddler:")
		{ var t; if ((t=store.getTiddler(params[0].substr(8)))) date=t.modified; params.shift(); }
	else {
		var y = eval(params.shift().replace(/Y/ig,(now.getYear()<1900)?now.getYear()+1900:now.getYear()));
		var m = eval(params.shift().replace(/M/ig,now.getMonth()+1));
		var d = eval(params.shift().replace(/D/ig,now.getDate()+0));
		date = new Date(y,m-1,d);
	}
	// date format with optional custom override
	var format=this.format; if (params[0]) format=params.shift();
	var linkformat=this.linkformat; if (params[0]) linkformat=params.shift();
	showDate(place,date,mode,format,linkformat);
}

window.showDate=showDate;
function showDate(place,date,mode,format,linkformat,autostyle,weekend)
{
	if (!mode) mode="display";
	if (!format) format=config.macros.date.format;
	if (!linkformat) linkformat=config.macros.date.linkformat;
	if (!autostyle) autostyle=false;

	// format the date output
	var title = date.formatString(format);
	var linkto = date.formatString(linkformat);

	// just show the formatted output
	if (mode=="display") { place.appendChild(document.createTextNode(title)); return; }

	// link to a 'dated tiddler'
	var link = createTiddlyLink(place, linkto, false);
	link.appendChild(document.createTextNode(title));
	link.title = linkto;
	link.date = date;
	link.format = format;
	link.linkformat = linkformat;

	// if using a popup menu, replace click handler for dated tiddler link
	// with handler for popup and make link text non-italic (i.e., an 'existing link' look)
	if (mode=="popup") {
		link.onclick = onClickDatePopup;
		link.style.fontStyle="normal";
	}
	// format the popup link to show what kind of info it contains (for use with calendar generators)
	if (autostyle) setDateStyle(place,link,weekend);
}
//}}}

//{{{
// NOTE: This function provides default logic for setting the date style when displayed in a calendar
// To customize the date style logic, please see[[DatePluginConfig]]
function setDateStyle(place,link,weekend) {
	// alias variable names for code readability
	var date=link.date;
	var fmt=link.linkformat;
	var linkto=date.formatString(fmt);
	var cmd=config.macros.date;

	if ((weekend!==undefined?weekend:isWeekend(date))&&(cmd.weekendbg!=""))
		{ place.style.background = cmd.weekendbg; }
	if (hasModifieds(date)||hasCreateds(date)||hasTagged(date,fmt))
		{ link.style.fontStyle="normal"; link.style.fontWeight="bold"; }
	if (hasReminders(date))
		{ link.style.textDecoration="underline"; }
	if (isToday(date))
		{ link.style.border="1px solid black"; }
	if (isHoliday(date)&&(cmd.holidaybg!=""))
		{ place.style.background = cmd.holidaybg; }
	if (hasCreateds(date)&&(cmd.createdbg!=""))
		{ place.style.background = cmd.createdbg; }
	if (hasModifieds(date)&&(cmd.modifiedsbg!=""))
		{ place.style.background = cmd.modifiedsbg; }
	if ((hasTagged(date,fmt)||store.tiddlerExists(linkto))&&(cmd.linkedbg!=""))
		{ place.style.background = cmd.linkedbg; }
	if (hasReminders(date)&&(cmd.remindersbg!=""))
		{ place.style.background = cmd.remindersbg; }
	if (isToday(date)&&(cmd.todaybg!=""))
		{ place.style.background = cmd.todaybg; }
	if (config.options.chkShowJulianDate) { // optional display of Julian date numbers
		var m=[0,31,59,90,120,151,181,212,243,273,304,334];
		var d=date.getDate()+m[date.getMonth()];
		var y=date.getFullYear();
		if (date.getMonth()>1 && (y%4==0 && y%100!=0) || y%400==0)
			d++; // after February in a leap year
		wikify("@@font-size:80%;<br>"+d+"@@",place);
	}




}
//}}}

//{{{
function isToday(date) // returns true if date is today
	{ var now=new Date(); return ((now-date>=0) && (now-date<86400000)); }

function isWeekend(date) // returns true if date is a weekend
	{ return (config.macros.date.weekend[date.getDay()]); }

function isHoliday(date) // returns true if date is a holiday
{
	var longHoliday = date.formatString("0MM/0DD/YYYY");
	var shortHoliday = date.formatString("0MM/0DD");
	for(var i = 0; i < config.macros.date.holidays.length; i++) {
		var holiday=config.macros.date.holidays[i];
		if (holiday==longHoliday||holiday==shortHoliday) return true;
	}
	return false;
}
//}}}

//{{{
// Event handler for clicking on a day popup
function onClickDatePopup(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var popup = Popup.create(this);
	if(popup) {
		// always show dated tiddler link (or just date, if readOnly) at the top...
		if (!readOnly || store.tiddlerExists(this.date.formatString(this.linkformat)))
			createTiddlyLink(popup,this.date.formatString(this.linkformat),true);
		else
			createTiddlyText(popup,this.date.formatString(this.linkformat));
		if (!config.options.chkDatePopupHideCreated)
			addCreatedsToPopup(popup,this.date,this.format);
		if (!config.options.chkDatePopupHideChanged)
			addModifiedsToPopup(popup,this.date,this.format);
		if (!config.options.chkDatePopupHideTagged)
			addTaggedToPopup(popup,this.date,this.linkformat);
		if (!config.options.chkDatePopupHideReminders)
			addRemindersToPopup(popup,this.date,this.linkformat);
	}
	Popup.show(popup,false);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}
//}}}

//{{{
function indexCreateds() // build list of tiddlers, hash indexed by creation date
{
	var createds= { };
	var tiddlers = store.getTiddlers("title","excludeLists");
	for (var t = 0; t < tiddlers.length; t++) {
		var date = tiddlers[t].created.formatString("YYYY0MM0DD")
		if (!createds[date])
			createds[date]=new Array();
		createds[date].push(tiddlers[t].title);
	}
	return createds;
}
function hasCreateds(date) // returns true if date has created tiddlers
{
	if (!config.macros.date.createds) config.macros.date.createds=indexCreateds();
	return (config.macros.date.createds[date.formatString("YYYY0MM0DD")]!=undefined);
}

function addCreatedsToPopup(popup,when,format)
{
	var force=(store.isDirty() && when.formatString("YYYY0MM0DD")==new Date().formatString("YYYY0MM0DD"));
	if (force || !config.macros.date.createds) config.macros.date.createds=indexCreateds();
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var createds = config.macros.date.createds[when.formatString("YYYY0MM0DD")];
	if (createds) {
		createds.sort();
		var e=createTiddlyElement(popup,"div",null,null,"created ("+createds.length+")");
		for(var t=0; t<createds.length; t++) {
			var link=createTiddlyLink(popup,createds[t],false);
			link.appendChild(document.createTextNode(indent+createds[t]));
			createTiddlyElement(popup,"br",null,null,null);
		}
	}
}
//}}}

//{{{
function indexModifieds() // build list of tiddlers, hash indexed by modification date
{
	var modifieds= { };
	var tiddlers = store.getTiddlers("title","excludeLists");
	for (var t = 0; t < tiddlers.length; t++) {
		var date = tiddlers[t].modified.formatString("YYYY0MM0DD")
		if (!modifieds[date])
			modifieds[date]=new Array();
		modifieds[date].push(tiddlers[t].title);
	}
	return modifieds;
}
function hasModifieds(date) // returns true if date has modified tiddlers
{
	if (!config.macros.date.modifieds) config.macros.date.modifieds = indexModifieds();
	return (config.macros.date.modifieds[date.formatString("YYYY0MM0DD")]!=undefined);
}

function addModifiedsToPopup(popup,when,format)
{
	var date=when.formatString("YYYY0MM0DD");
	var force=(store.isDirty() && date==new Date().formatString("YYYY0MM0DD"));
	if (force || !config.macros.date.modifieds) config.macros.date.modifieds=indexModifieds();
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var mods = config.macros.date.modifieds[date];
	if (mods) {
		// if a tiddler was created on this date, don't list it in the 'changed' section
		if (config.macros.date.createds && config.macros.date.createds[date]) {
			var temp=[];
			for(var t=0; t<mods.length; t++)
				if (!config.macros.date.createds[date].contains(mods[t]))
					temp.push(mods[t]);
			mods=temp;
		}
		mods.sort();
		var e=createTiddlyElement(popup,"div",null,null,"changed ("+mods.length+")");
		for(var t=0; t<mods.length; t++) {
			var link=createTiddlyLink(popup,mods[t],false);
			link.appendChild(document.createTextNode(indent+mods[t]));
			createTiddlyElement(popup,"br",null,null,null);
		}
	}
}
//}}}

//{{{
function hasTagged(date,format) // returns true if date is tagging other tiddlers
{
	return store.getTaggedTiddlers(date.formatString(format)).length>0;
}

function addTaggedToPopup(popup,when,format)
{
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var tagged=store.getTaggedTiddlers(when.formatString(format));
	if (tagged.length) var e=createTiddlyElement(popup,"div",null,null,"tagged ("+tagged.length+")");
	for(var t=0; t<tagged.length; t++) {
		var link=createTiddlyLink(popup,tagged[t].title,false);
		link.appendChild(document.createTextNode(indent+tagged[t].title));
		createTiddlyElement(popup,"br",null,null,null);
	}
}
//}}}

//{{{
function indexReminders(date,leadtime) // build list of tiddlers with reminders, hash indexed by reminder date
{
	var reminders = { };
	if(window.findTiddlersWithReminders!=undefined) { // reminder plugin is installed
		// DEBUG var starttime=new Date();
		var t = findTiddlersWithReminders(date, [0,leadtime], null, null, 1);
		for(var i=0; i<t.length; i++) reminders[t[i].matchedDate]=true;
		// DEBUG var out="Found "+t.length+" reminders in "+((new Date())-starttime+1)+"ms\n";
		// DEBUG out+="startdate: "+date.toLocaleDateString()+"\n"+"leadtime: "+leadtime+" days\n\n";
		// DEBUG for(var i=0; i<t.length; i++) { out+=t[i].matchedDate.toLocaleDateString()+" "+t[i].params.title+"\n"; }
		// DEBUG alert(out);
	}
	return reminders;
}

function hasReminders(date) // returns true if date has reminders
{
	if (window.reminderCacheForCalendar)
		return window.reminderCacheForCalendar[date]; // use calendar cache
	if (!config.macros.date.reminders)
		config.macros.date.reminders = indexReminders(date,90); // create a 90-day leadtime reminder cache
	return (config.macros.date.reminders[date]);
}

function addRemindersToPopup(popup,when,format)
{
	if(window.findTiddlersWithReminders==undefined) return; // reminder plugin not installed

	var indent = String.fromCharCode(160)+String.fromCharCode(160);
	var reminders=findTiddlersWithReminders(when, [0,31],null,null,1);
	createTiddlyElement(popup,"div",null,null,"reminders ("+(reminders.length||"none")+")");
	for(var t=0; t<reminders.length; t++) {
		link = createTiddlyLink(popup,reminders[t].tiddler,false);
		var diff=reminders[t].diff;
		diff=(diff<1)?"Today":((diff==1)?"Tomorrow":diff+" days");
		var txt=(reminders[t].params["title"])?reminders[t].params["title"]:reminders[t].tiddler;
		link.appendChild(document.createTextNode(indent+diff+" - "+txt));
		createTiddlyElement(popup,"br",null,null,null);
	}
	if (readOnly) return;	// omit "new reminder..." link
	var link = createTiddlyLink(popup,indent+"new reminder...",true); createTiddlyElement(popup,"br");
	var title = when.formatString(format);
	link.title="add a reminder to '"+title+"'";
	link.onclick = function() {
		// show tiddler editor
		story.displayTiddler(null, title, 2, null, null, false, false);
		// find body 'textarea'
		var c =document.getElementById("tiddler" + title).getElementsByTagName("*");
		for (var i=0; i<c.length; i++) if ((c[i].tagName.toLowerCase()=="textarea") && (c[i].getAttribute("edit")=="text")) break;
		// append reminder macro to tiddler content
		if (i<c.length) {
			if (store.tiddlerExists(title)) c[i].value+="\n"; else c[i].value="";
			c[i].value += "<<reminder";
			c[i].value += " day:"+when.getDate();
			c[i].value += " month:"+(when.getMonth()+1);
			c[i].value += " year:"+when.getFullYear();
			c[i].value += ' title:"Enter a title" >>';
		}
	};
}
//}}}
/***
|Name|DatePluginConfig|
|Source|http://www.TiddlyTools.com/#DatePluginConfig|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.6.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|formats, background colors and other optional settings for DatePlugin|
***/
// // Default popup content display options (can be overridden by cookies)
//{{{
if (config.options.chkDatePopupHideCreated===undefined)
	config.options.chkDatePopupHideCreated=false;
if (config.options.chkDatePopupHideChanged===undefined)
	config.options.chkDatePopupHideChanged=false;
if (config.options.chkDatePopupHideTagged===undefined)
	config.options.chkDatePopupHideTagged=false;
if (config.options.chkDatePopupHideReminders===undefined)
	config.options.chkDatePopupHideReminders=false;
//}}}

// // show Julian date number below regular date
//{{{
if (config.options.chkShowJulianDate===undefined)
	config.options.chkShowJulianDate=false;
//}}}

// // fixed-date annual holidays
//{{{
config.macros.date.holidays=[
	"01/01", // NewYearsDay, 
	"07/04", // US Independence Day
	"07/25",  // Kourosh's Birthday (hooray!)
	"11/16"  // Neda's Birthday (hooray!)
];
//}}}

// // weekend map (1=weekend, 0=weekday)
//{{{
config.macros.date.weekend=[ 1,0,0,0,0,0,1 ]; // day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6
//}}}

// // date display/link formats
//{{{
config.macros.date.format="YYYY.0MM.0DD"; // default date display format
config.macros.date.linkformat="YYYY.0MM.0DD"; // 'dated tiddler' link format
//}}}

// // When displaying a calendar (see [[CalendarPlugin]]), you can customize the colors/styles that are applied to the calendar dates by modifying the values and/or functions below:
//{{{
// default calendar colors
config.macros.date.weekendbg="#c0c0c0";
config.macros.date.holidaybg="#ffaace";
config.macros.date.createdbg="#bbeeff";
config.macros.date.modifiedsbg="#bbeeff";
config.macros.date.linkedbg="#babb1e";
config.macros.date.remindersbg="#c0ffee";

// apply calendar styles
function setDateStyle(place,link,weekend) {
	// alias variable names for code readability
	var date=link.date;
	var fmt=link.linkformat;
	var linkto=date.formatString(fmt);
	var cmd=config.macros.date;

	if ((weekend!==undefined?weekend:isWeekend(date))&&(cmd.weekendbg!=""))
		{ place.style.background = cmd.weekendbg; }
	if (hasModifieds(date)||hasCreateds(date)||hasTagged(date,fmt))
		{ link.style.fontStyle="normal"; link.style.fontWeight="bold"; }
	if (hasReminders(date))
		{ link.style.textDecoration="underline"; }
	if (isToday(date))
		{ link.style.border="1px solid black"; }
	if (isHoliday(date)&&(cmd.holidaybg!=""))
		{ place.style.background = cmd.holidaybg; }
	if (hasCreateds(date)&&(cmd.createdbg!=""))
		{ place.style.background = cmd.createdbg; }
	if (hasModifieds(date)&&(cmd.modifiedsbg!=""))
		{ place.style.background = cmd.modifiedsbg; }
	if ((hasTagged(date,fmt)||store.tiddlerExists(linkto))&&(cmd.linkedbg!=""))
		{ place.style.background = cmd.linkedbg; }
	if (hasReminders(date)&&(cmd.remindersbg!=""))
		{ place.style.background = cmd.remindersbg; }
	if (isToday(date)&&(cmd.todaybg!=""))
		{ place.style.background = cmd.todaybg; }
	if (config.options.chkShowJulianDate) {
		var m=[0,31,59,90,120,151,181,212,243,273,304,334];
		var d=date.getDate()+m[date.getMonth()];
		var y=date.getFullYear();
		if (date.getMonth()>1 && (y%4==0 && y%100!=0) || y%400==0) d++; // after February in a leap year
		wikify("@@font-size:80%;<br>"+d+"@@",place);
	}
}
//}}}
|Name|DatePluginInfo|
|Source|http://www.TiddlyTools.com/#DatePlugin|
|Documentation|http://www.TiddlyTools.com/#DatePluginInfo|
|Version|2.7.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for DatePlugin|
There are quite a few calendar generators, reminders, to-do lists, 'dated tiddlers' journals, blog-makers and GTD-like schedule managers that have been built around TW.  While they all have different purposes, and vary in format, interaction, and style, in one way or another each of these plugins displays and/or uses date-based information to make finding, accessing and managing relevant tiddlers easier.  This plugin provides a general approach to embedding dates and date-based links/menus within tiddler content.
!!!!!Usage
<<<
This plugin display formatted dates, for the specified year, month, day using number values or mathematical expressions such as (Y+1) or (D+30).  Optionally, you can create a link from the formatted output to a 'dated tiddler' for quick blogging or create a popup menu that includes the dated tiddler link plus links to tiddlers that were created/changed on that date, or are tagged with that date, as well as links to any pending reminders for the coming 31 days (if the RemindersPlugin is installed).  This plugin also provides a public API for easily incorporating formatted date output (with or without the links/popups) into other plugins, such as calendar generators, etc.

This plugin defines a macro: {{{<<date [mode] [date] [format] [linkformat]>>}}}.  All of the macro parameters are optional and, in it's simplest form, {{{<<date>>}}}, it is equivalent to the ~TiddlyWiki core macro, {{{<<today>>}}}.

However, where {{{<<today>>}}} simply inserts the current date/time in a predefined format (or custom format, using {{{<<today [format]>>}}}), the {{{<<date>>}}} macro's parameters take it much further than that:
* [mode] is either ''display'', ''link'' or ''popup''.  If omitted, it defaults to ''display''.  This param let's you select between simply displaying a formatted date, or creating a link to a specific 'date titled' tiddler or a popup menu containing a dated tiddler link, plus links to changes and reminders.
* [date] lets you enter ANY date (not just today) as ''year, month, and day values or simple mathematical expressions'' using pre-defined variables, Y, M, and D for the current year, month and day, repectively.  You can display the modification date of the current tiddler by using the keyword: ''tiddler'' in place of the year, month and day parameters.  Use ''tiddler://name-of-tiddler//'' to display the modification date of a specific tiddler.  You can also use keywords ''today'' or ''filedate'' to refer to these //dynamically changing// date/time values.  
* [format] and [linkformat] uses standard ~TiddlyWiki date formatting syntax.  The default is "YYYY.0MM.0DD"
>^^''DDD'' - day of week in full (eg, "Monday"), ''DD'' - day of month, ''0DD'' - adds leading zero^^
>^^''MMM'' - month in full (eg, "July"), ''MM'' - month number, ''0MM'' - adds leading zero^^
>^^''YYYY'' - full year, ''YY'' - two digit year, ''hh'' - hours, ''mm'' - minutes, ''ss'' - seconds^^
>^^//note: use of hh, mm or ss format codes is only supported with ''tiddler'', ''today'' or ''filedate'' values//^^
* [linkformat] - specify an alternative date format so that the title of a 'dated tiddler' link can have a format that differs from the date's displayed format

In addition to the macro syntax, DatePlugin also provides a public javascript API so that other plugins that work with dates (such as calendar generators, etc.) can quickly incorporate date formatted links or popups into their output:

''{{{showDate(place, date, mode, format, linkformat, autostyle, weekend)}}}'' 

Note that in addition to the parameters provided by the macro interface, the javascript API also supports two optional true/false parameters:
* [autostyle] - when true, the font/background styles of formatted dates are automatically adjusted to show the date's status:  'today' is boxed, 'changes' are bold, 'reminders' are underlined, while weekends and holidays (as well as changes and reminders) can each have a different background color to make them more visibly distinct from each other.
* [weekend] - true indicates a weekend, false indicates a weekday.  When this parameter is omitted, the plugin uses internal defaults to automatically determine when a given date falls on a weekend.
<<<
!!!!!Examples
<<<
The current date: <<date>>
The current time: <<date today "0hh:0mm:0ss">>
Today's blog: <<date link today "DDD, MMM DDth, YYYY">>
Recent blogs/changes/reminders: <<date popup Y M D-1 "yesterday">> <<date popup today "today">> <<date popup Y M D+1 "tomorrow">>
The first day of next month will be a <<date Y M+1 1 "DDD">>
This tiddler (DatePlugin) was last updated on: <<date tiddler "DDD, MMM DDth, YYYY">>
The SiteUrl was last updated on: <<date tiddler:SiteUrl "DDD, MMM DDth, YYYY">>
This document was last saved on <<date filedate "DDD, MMM DDth, YYYY at 0hh:0mm:0ss">>
<<date 2006 07 24 "MMM DDth, YYYY">> will be a <<date 2006 07 24 "DDD">>
<<<
!!!!!Revisions
<<<
2008.03.08 [2.7.0] in addModifiedsToPopup(), if a tiddler was created on the specified date, don't list it in the 'changed' section of the popup.  Based on a request from Kashgarinn
2008.01.31 [2.6.0] refactored date style logic into separate setDateStyle() function so it can be overridden by a custom definition.  See [[DatePluginConfig]].
2008.01.11 [2.5.0] added options to selectively suppress created/changes/tagged/reminders popup content 
2008.01.08 [*.*.*] plugin size reduction: documentation moved to DatePluginInfo
2007.11.21 [2.4.0] added hasTagged() and addTaggedToPopup() to list any tiddlers that has been tagged using the title of the dated journal tiddler asa tag value (i.e., the tiddlers that will be listed in the standard "tagging" display when viewing the journal tiddler itself).  Based on a request from Coby.
2007.06.20 [2.3.1] in onClickDatePopup(), use Popup.show() instead of deprecated ScrollToTiddlerPopup().  Fixes fatal error that prevents popups from being properly displayed
2007.05.31 [2.3.0] list "created" tiddlers in date popup.  Also, force re-cache of created/modified indices when displaying current date and store.isDirty(), so that popup is kept in sync with tiddler changes.
2006.05.09 [2.2.1] added "todaybg" handling to set background color of current date.  Also, honor excludeLists tag when getting lists of tiddlers.  Based on suggestions by Mark Hulme.
2006.05.05 [2.2.0] added "linkedbg" handling to set background color when a 'dated tiddler' exists.  Based on a suggestion by Mark Hulme.
2006.03.08 [2.1.2] add 'override leadtime' flag param in call to findTiddlersWithReminders(), and add "Enter a title" default text to new reminder handler.  Thanks to Jeremy Sheeley for these additional tweaks.
2006.03.06 [2.1.0] hasReminders() nows uses window.reminderCacheForCalendar[] when present.  If calendar cache is not present, indexReminders() now uses findTiddlersWithReminders() with a 90-day look ahead to check for reminders.  Also, switched default background colors for autostyled dates: reminders are now greenish ("c0ffee") and holidays are now reddish ("ffaace").
2006.02.14 [2.0.5] when readOnly is set (by TW core), omit "new reminders..." popup menu item and, if a "dated tiddler" does not already exist, display the date as simple text instead of a link.
2006.02.05 [2.0.4] added var to variables that were unintentionally global.  Avoids FireFox 1.5.0.1 crash bug when referencing global variables
2006.01.18 [2.0.3] In 1.2.x the tiddler editor's text area control was given an element ID=("tiddlerBody"+title), so that it was easy to locate this field and programmatically modify its content.  With the addition of configuration templates in 2.x, the textarea no longer has an ID assigned.  To find this control we now look through all the child nodes of the tiddler editor to locate a "textarea" control where attribute("edit") equals "text", and then append the new reminder to the contents of that control.
2006.01.11 [2.0.2] correct 'weekend' override detection logic in showDate()
2006.01.10 [2.0.1] allow custom-defined weekend days (default defined in config.macros.date.weekend[] array)
added flag param to showDate() API to override internal weekend[] array
2005.12.27 [2.0.0] Update for TW2.0
Added parameter handling for 'linkformat'
2005.12.21 [1.2.2] FF's date.getYear() function returns 105 (for the current year, 2005).  When calculating a date value from Y M and D expressions, the plugin adds 1900 to the returned year value get the current year number.  But IE's date.getYear() already returns 2005.  As a result, plugin calculated date values on IE were incorrect (e.g., 3905 instead of 2005).  Adding +1900 is now conditional so the values will be correct on both browsers.
2005.11.07 [1.2.1] added support for "tiddler" dynamic date parameter
2005.11.06 [1.2.0] added support for "tiddler:title" dynamic date parameter
2005.11.03 [1.1.2] when a reminder doesn't have a specified title parameter, use the title of the tiddler that contains the reminder as "fallback" text in the popup menu.  Based on a suggestion from BenjaminKudria.
2005.11.03 [1.1.1] Temporarily bypass hasReminders() logic to avoid excessive overhead from generating the indexReminders() cache.  While reminders can still appear in the popup menu, they just won't be indicated by auto-styling the date number that is displayed.  This single change saves approx. 60% overhead (5 second delay reduced to under 2 seconds).
2005.11.01 [1.1.0] corrected logic in hasModifieds() and hasReminders() so caching of indexed modifieds and reminders is done just once, as intended.  This should hopefully speed up calendar generators and other plugins that render multiple dates...

2005.10.31 [1.0.1] documentation and code cleanup
2005.10.31 [1.0.0] initial public release
2005.10.30 [0.9.0] pre-release
<<<
[[Home]]
/***
|!''Name:''|!''E''asily ''A''daptable ''S''ource ''E''ditor|
|''Description:''|this framework allows you to easily create commands that work on the current tiddler text selection in edit mode|
|''Version:''|0.1.0|
|''Date:''|13/01/2007|
|''Source:''|http://yann.perrin.googlepages.com/twkd.html#E.A.S.E|
|''Author:''|[[Yann Perrin|YannPerrin]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.x|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
***/
////Messages Definition
//{{{
config.messages.Ease = {
noselection:"nothing selected",
asktitle:"enter the new tiddler title",
exists:" already exists, please enter another title",
askForTagsLabel:"enter the new tiddler tags",
tiddlercreated:" tiddler created"
}
//}}}
////
//{{{
if (!window.TWkd) window.TWkd={context:{}};
if (!TWkd.Ease)
 TWkd.Ease = function (text,tooltip){
 this.text = text;
 this.tooltip = tooltip;
 this.modes = [];
 this.addMode = function(modeDefinition) {this.modes.push(modeDefinition);};
 this.handler = function(event,src,title) {
 TWkd.context.command = this;
 TWkd.context.selection=this.getSelection(title);
 if (this.modes.length==1) {
 this.modes[0].operation();
 }
 else {
 var popup = Popup.create(src);
 if(popup) {
 for (var i=0; i<this.modes.length; i++) {
 createTiddlyButton(createTiddlyElement(popup,"li"), this.modes[i].name, this.modes[i].tooltip, this.OperateFromButton, null, 'id'+i, null);
 }
 Popup.show(popup,false);
 event.cancelBubble = true;
 if (event.stopPropagation) event.stopPropagation();
 return false;
 }
 }
 };
 };

TWkd.Ease.prototype.OperateFromButton = function(e){
 var commandMode=this.getAttribute('Id').replace('id','');
 TWkd.context.command.modes[commandMode].operation();
};

TWkd.Ease.prototype.getTiddlerEditField = function(title,field){
 var tiddler = document.getElementById(story.idPrefix + title);
 if(tiddler != null){
 var children = tiddler.getElementsByTagName("*")
 var e = null;
 for (var t=0; t<children.length; t++){
 var c = children[t];
 if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea"){
 if(!e) {e = c;}
 if(c.getAttribute("edit") == field){e = c;}
 }
 }
 if(e){return e;}
 }
} // closes getTiddlerEditField function definition
 
TWkd.Ease.prototype.getSelection = function(title,quiet) {
 var tiddlerTextArea = this.getTiddlerEditField(title,"text");
 var result = {};
 if (document.selection != null && tiddlerTextArea.selectionStart == null) {
 tiddlerTextArea.focus();
 var range = document.selection.createRange();
 var bookmark = range.getBookmark();
 var contents = tiddlerTextArea.value;
 var originalContents = contents;
 var marker = "##SELECTION_MARKER_" + Math.random() + "##";
 while(contents.indexOf(marker) != -1) {
 marker = "##SELECTION_MARKER_" + Math.random() + "##";
 }
 var selection = range.text;
 range.text = marker + range.text + marker;
 contents = tiddlerTextArea.value;
 result.start = contents.indexOf(marker);
 contents = contents.replace(marker, "");
 result.end = contents.indexOf(marker);
 tiddlerTextArea.value = originalContents;
 range.moveToBookmark(bookmark);
 range.select();
 }
 else {
 result.start=tiddlerTextArea.selectionStart;
 result.end=tiddlerTextArea.selectionEnd;

 }
 result.content=tiddlerTextArea.value.substring(result.start,result.end);
 result.source=title;
 if (!result.content&&!quiet) displayMessage(config.messages.Ease.noselection);
 return(result);
}//closes getSelection function definition

// replace selection or insert new content
TWkd.Ease.prototype.putInPlace=function(content,workplace) {
 var tiddlerText = this.getTiddlerEditField(workplace.source,"text");
 tiddlerText.value = tiddlerText.value.substring(0,workplace.start)+content+tiddlerText.value.substring(workplace.end);
}

// asking for title
TWkd.Ease.prototype.askForTitle = function(suggestion) {
 if (!suggestion)
 suggestion = "";
 var newtitle;
 while (!newtitle||store.tiddlerExists(newtitle))
 {
 if (store.tiddlerExists(newtitle))
 displayMessage(newtitle+config.messages.Ease.exists);
 newtitle = prompt(config.messages.Ease.asktitle,suggestion);
 if (newtitle==null)
 {
 displayMessage(config.messages.Ease.titlecancel);
 return(false);
 }
 }
 return(newtitle);
}//closes askForTitle function definition

// creation of a new tiddler
TWkd.Ease.prototype.newTWkdLibTiddler = function(title,content,from,askForTags){
 var tiddler = new Tiddler();
 tiddler.title = title;
 tiddler.modifier = config.options.txtUserName;
 tiddler.text = content;
 (from) ? tiddler.tags = [from] : tiddler.tags=[];
 if (askForTags)
 tiddler.tags = prompt(config.messages.Ease.askForTagsLabel,'[['+from+']]').readBracketedList();
 store.addTiddler(tiddler);
 //store.notifyAll();
 displayMessage(title+config.messages.Ease.tiddlercreated);
}

if (!TWkd.Mode)
 TWkd.Mode = function (name,tooltip,ask,operation) {
 this.name = name;
 this.tooltip = tooltip;
 this.ask = ask;
 this.operation = operation;
 };
//}}}
<div class='title' macro='view title'></div>
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
<div class='editor' macro='edit title'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>

!! Anisotropic bio-membranes  
Skeleton-reinforced bio-membranes are ubiquitous in nature and play critical roles in many biological functions. One example is the wings of insects, whose flexibility is determined primarily by the architecture of the embedded veins. In most cases, the spanwise bending stiffness was found to be at least 1-2 orders of magnitude higher than the chordwise bending stiffness. Also in many cases, existence of clustered or thickened veins near the leading edge are observed. 

Many fish possess caudal, dorsal, pectoral, or ventral fins that are stiffened by fin rays embedded in a thin layer of collagenous membrane. According to morphological studies, a fin ray contains a central bundle of collagen surrounded by small segmented bony elements called hemitrichs. These elements are paired and resemble a bimetallic strip with two elongated bony elements separated by the central collagen core. Along the length of a hemitrich, and at the ends, there exist short ligaments and elastic fibers. In addition, the basal end of each ray attaches to four separate muscles. This architecture enables a fish to not only control the motion of each individual ray by moving and rotating its basal end, but also control the curvature along the ray through the tendons. This property allows the fish to achieve multi-degree of freedom control of its fins, and is expected to have fundamental effects on the hydrodynamic performance of the fins in generating propulsion force during cruising and maneuvering.

{{centeredTable{
| [img(60%,auto)[fish3.png]]<br>Venation structure in the wing of a Manduca sexta. The leading edge veins are shown in red. | [img(100%,auto)[fish1.png]]<br> Picture of a bluegill sungfish with all its fins. | [img(65%,auto)[fish2.png]]<br> Fin ray structure of a bluegill sunfish (Lepomis macrochirus) (from Alben et al. 2007). |
|borderless|k
}}}

It remains to be fully understood the exact function of the anisotropic flexibility of these skeleton-strengthened fins or wings in insect flying and fish swimming. But there are Evidences of the beneficial effects of structural flexibility in force generation. In my Ph.D. program, I have studies benefits and performance of such flexible anisotropic fins.

Compared with the conventional rigid foil design, the membrane design possesses the following advantages:
{{alignBullets{
*@@color(darkred):Enhanced efficiency@@: As illustrated in our preliminary study (e.g. Zhu 2007), a flexible foil with 3D deformability yields better performance than a rigid one, manifested in the increased efficiency, reduced sensitivity to kinematic parameters, and diminished force in the transverse direction.
*@@color(darkred):Controllability and versatility@@: With strengthening skeletons, the structural properties of the composite membrane can be adjusted and its motion can be controlled in detail to create different locomotion modes. For example, in a ray-strengthened fin, the motion of each ray as well as its curvature can be controlled so that it can easily achieve complicated movements to generate different forces (thrust, lift, etc.) required in cruising, bursting, and maneuvering.
*@@color(darkred):Structural strength and lightness@@: The biomimetic composite membrane provides a light structure with high strength.
*@@color(darkred):Deployability@@: The skeleton-reinforced membrane resembles deployable structures such as cable roof buildings. These structures can be easily folded and unfolded, making them an ideal design as a portable device.
{{textcenter{
[img(100%,auto)[FSI in Intermediate Re | icon2b.jpg][Flexible loop-Immersed boundary method]]<br>Flexible loop, FSI in Intermediate Re
}}}
MATLAB comes with common [[Built-in Functions]] and many other specialized functions in a variety of areas. Some of these can be found by looking at MATLAB's ''Help'' section. If these do not satisfy your needs, you can design your own functions. Functions take some input, in the form of scalars, vectors, or matrices, and can output specific results. 

As a simple example, lets say that we want the area of a triangle give the three sides, //a//, //b//, //c//. As you know, this can be solved using [[Heron's Formula|http://mathworld.wolfram.com/HeronsFormula.html]]: //A = (s(s-a)(s-b)(s-c))^^1/2^^ //, where // s = (a+b+c)/2//.

The input variables are the sides and the output is the area. Open up the editor and type in the following lines and save as heron.m:

{{{
function f=heron(a,b,c)
% This function computes the area of a triangle with sides a,b,c

s=(a+b+c)/2;
f=sqrt(s*(s-a)*(s-b)*(s-c));
}}}

In the command window you can call this function:

{{{>>heron(3,4,5)}}}

It produces an answer of {{{6}}}. Since this is a known triangle, it is easy to see that the function works. Now you can try the function with several other triangles. You can also call this function from other scripts and functions provided heron.m is in the path. 

In the above function we have added a comment statement. This comment will appear if you now type in 

{{{>>help heron}}}

Also, we were careful to add semicolons after each line so that we do not get extraneous output displayed in the command window.

If we type in any of the variables {{{a}}}, {{{b}}}, {{{c}}}, {{{s}}}, we will not get any output. These are what are called local variables. One can get a bit more sophisticated by declaring global variables known to several functions and scripts. One can also pass parameters, input matrices, or output matrices. But the simplest form of functions has been provided by this example. 

Sometimes one wants to define a one line function and creating a file might seem like a lot to do. In more recent version of MATLAB the //inline// object has been introduced. One can define a function, like //f(x)=exp(-x^^2^^) //, simply by typing in the command window or in some script:

{{{>>f = inline(exp(-x^2);}}} 

Now evaluate //f(0.1)//. However, one cannot use this function on a vector //x// since the //x^^2^^// would return an error. In such cases you need to add a dot:

{{{>>f = inline(exp(-x.^2);}}}

Then you could do the following:

{{{>>x=[0.1 0.2 0.3];}}}
{{{>>f(x)}}} 

to obtain {{{[ 0.9900    0.9608    0.9139]}}}.

One final way to handle one line functions is by using //anonymous functions//, which are a recent addition to MATLAB. This can be done for the above example:

{{{>>f = @(x) exp(-x^2);}}} 
{{{>>f(0.1)}}}

One can define functions of several variables with a parameter previously defined in the script or work session:

{{{>>a = 6.0}}}
{{{>>f = @(x,y) x^2 + a*y^2}}}
{{{>>f(2,3)}}}
When you launch the program you will get a main window with several subwindows. The subwindow on the right is the Command Window. You can type simple commands in this window after >> In this window you can try simple commands. Note that MATLAB is case sensitive.  

One way to learn about MATLAB is to try the demos. Type demo and hit RETURN. Then under the MATLAB folder on the left you can select different demos. 

If you want HELP, you can access topics under the menu item or type help topic in the command line. 
You can recall previously types lines using the up and down arrows. You can quit by typing exit or quit, or just exit from the menu. 
!!Solid and Structures
{{alignBullets{
*@@color(darkblue):Continuum Mechanics@@
*@@color(darkblue):Theory of Elasticity@@
*@@color(darkblue):Theory of Plasticity and Viscoelasticity@@
*@@color(darkblue):Soil Structure Interaction@@
*@@color(darkblue):Active Controls of Structures@@
*@@color(darkblue):Random Vibrations@@
*@@color(darkblue):Theory of Plates and Shells@@
*@@color(darkblue):Advanced Engineering Mathematics@@
*@@color(darkblue):Advanced Structural Analysis@@
*@@color(darkblue):Structural Dynamics@@
*@@color(darkblue):Advanced Structural Dynamics@@
*@@color(darkblue):Nonlinear Structural Dynamics@@
*@@color(darkblue):Structural Stability@@
*@@color(darkblue):Cable Structures@@
*@@color(darkblue):Experimental Mechanics and NDE@@
}}}
!!Computational Mechanics
{{alignBullets{
*@@color(darkblue):Finite Element I@@
*@@color(darkblue):Finite Element II@@
*@@color(darkblue):Fluid Structure Interaction@@
*@@color(darkblue):Computational Fluid Dynamic@@
*@@color(darkblue):Computational Fluid Dynamic with Finite Element Method@@
*@@color(darkblue):Parallel computing@@
*@@color(darkblue):Numerical Analysis@@
*@@color(darkblue):Numerical Method and Differential Equations@@
*@@color(darkblue):Numerical Optimization I@@
*@@color(darkblue):Numerical Optimization II@@
*@@color(darkblue):Numerical Optimization III@@
*@@color(darkblue):Numerical Partial Differential Equations I@@
*@@color(darkblue):Numerical Partial Differential Equations II@@
*@@color(darkblue):Numerical Partial Differential Equations III@@
}}}
!!Fluid Mechanics
{{alignBullets{
*@@color(darkblue):Fluid Mechanics I@@
*@@color(darkblue):Fluid Mechanics II@@
*@@color(darkblue):Biological Fluid Mechanics@@
*@@color(darkblue):Hydrodynamics and Marine Structures@@
*@@color(darkblue):Introduction to Turbulence and Turbulent Mixing@@
}}}
!!Control and Math
{{alignBullets{
*@@color(darkblue):Complex Analysis I@@
*@@color(darkblue):Differential Geometry I@@
*@@color(darkblue):Differential Geometry II@@
*@@color(darkblue):Stochastic Processes in Dynamic Systems@@
*@@color(darkblue):Parametric Identification, Theory and Applications@@
*@@color(darkblue):Time Series Analysis and Applications@@
*@@color(darkblue):Nonlinear Systems@@
*@@color(darkblue):Nonlinear Control@@
*@@color(darkblue):Adaptive Control@@
*@@color(darkblue):Control of Distributed Parameter Systems@@
*@@color(darkblue):Neural Networks@@
}}}
<<closeAll>><<permaview>><<newTiddler>><<newJournal 'DD MMM YYYY'>><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel 'options �' 'Change TiddlyWiki advanced options'>> 
{{firstletter{
 @@color:black;I@@
 }}} am currently a postdoctoral researcher at [[The Flow Simulation and Analysis Group|http://engineering.jhu.edu/fsag/]] in the [[Department of Mechanical Engineering|www.me.jhu.edu/‎]], Whiting School of Engineering, the [[Johns Hopkins University| www.jhu.edu/‎]]. . Previously, I was a research engineer at Re Vision LLC (2011-2013) and a Post-doctoral research assisstant (2011) in [[Department of Structural Engineering|http://www.structures.ucsd.edu/]] at [[University of California, San Diego (UCSD)|http://www.ucsd.edu/]]. I received  my Ph.D. from the [[Department of Structural Engineering|http://www.structures.ucsd.edu/]] at [[University of California, San Diego (UCSD)|http://www.ucsd.edu/]] in 2011. My doctoral dissertation was supervised by Professor [[Qiang Zhu|http://structures.ucsd.edu/index.php?page=structural_engineering/people/faculty/zhu]]  and it was about fluid structure interaction with flexible structures. I received my M.Sc. in structural engineering form  [[Civil and Environmental Engineering department|http://civil.sharif.edu/]] of [[Sharif University of Technology|http://www.sharif.ir/en/]] in 2006.   My master thesis was about detection of nonlinear damages based on adaptive tracking technique using dynamical response. I received my B.Sc. from the Civil Engineering department of [[Shiraz University| http://www.shirazu.ac.ir/en/]] in 2003.

For further details about my research interests, please click [[here|Research interests]].
/***
|Name|ImageSizePlugin|
|Source|http://www.TiddlyTools.com/#ImageSizePlugin|
|Version|1.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin,formatter|
|Requires||
|Overrides|'image' formatter|
|Description|extends image syntax to add optional CSS width/height values|
!!!!!Usage

<<<
Extends standard TiddlyWiki image syntax, ''{{{[img[...]]}}}'', so you can specify CSS width/height values.

The extended syntax is:
>''{{{[img(x,y)[...]]}}}''
>where x and y are the desired width and height of the image, specified using CSS units of measurement (e.g., px, em, cm, in, or %).  Use ''auto'' for either the width or height to scale image proportionally (i.e., maintain aspect ratio).  You may also calculate a CSS value on-the-fly by using //evaluated javascript//, enclosed between """{{""" and """}}""", e.g, {{{({{widthFunction()}},{{heightFunction()}})}}}.

Note: this plugin also includes enhancements to support:
*[[AttachFilePluginFormatters]] (embed image files as text-encoded tiddlers)
* [[ImagePathPlugin]] (fallback locations for missing images)
Please refer to those plugins for details...
<<<
!!!!!Examples
<<<

{{{
[<img(34%,auto)[images/meow.gif]]
[<img(21%,auto)[images/meow.gif]]
[<img(13%,auto)[images/meow.gif]]
[<img(8%,auto)[images/meow.gif]]
[<img(5%,auto)[images/meow.gif]]
[<img(3%,auto)[images/meow.gif]]
[<img(2%,auto)[images/meow.gif]]
[img(1%,auto)[images/meow.gif]]
}}}
[<img(34%,auto)[images/meow.gif]]
[<img(21%,auto)[images/meow.gif]]
[<img(13%,auto)[images/meow.gif]]
[<img(8%,auto)[images/meow.gif]]
[<img(5%,auto)[images/meow.gif]]
[<img(3%,auto)[images/meow.gif]]
[<img(2%,auto)[images/meow.gif]]
[img(1%,auto)[images/meow.gif]]
{{clear block{}}}

<<<
!!!!!Revisions

<<<
2008.01.19 [1.1.0] added support for evaluated width/height values!!
2008.01.18 [1.0.1] code cleanup plus improved regexp for matching "(width,height)" by eliminating hard-coded recognition of [px,em,cm,in,%] CSS units.  Syntax now accepts ANY values for width/height, and leaves it to the browser's CSS processing to handle any invalid values.
2008.01.17 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImageSizePlugin= {major: 1, minor: 1, revision: 0, date: new Date(2008,1,19)};

// replace standard handler for image formatter
// note: includes modifications for [[AttachFilePluginFormatters]] AND [[ImagePathPlugin]]
var f=config.formatters.findByField("name","image");
config.formatters[f].match="\\[[<>]?[Ii][Mm][Gg](?:\\([^,]*,[^\\)]*\\))?\\[";
config.formatters[f].lookaheadRegExp=/\[([<]?)(>?)[Ii][Mm][Gg](\([^,]*,[^\)]*\))?\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg;
config.formatters[f].handler=function(w) {
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var floatLeft=lookaheadMatch[1];
		var floatRight=lookaheadMatch[2];
		var XY=lookaheadMatch[3];
		var tooltip=lookaheadMatch[4];
		var src=lookaheadMatch[5];
		var link=lookaheadMatch[6];
		// Simple bracketted link
		var e = w.output;
		if(link) { // LINKED IMAGE
			if (config.formatterHelpers.isExternalLink(link)) {
				if (config.macros.attach && config.macros.attach.isAttachment(link)) {
					// see [[AttachFilePluginFormatters]]
					e = createExternalLink(w.output,link);
					e.href=config.macros.attach.getAttachment(link);
					e.title = config.macros.attach.linkTooltip + link;
				} else
					e = createExternalLink(w.output,link);
			} else 
				e = createTiddlyLink(w.output,link,false,null,w.isStatic);
			addClass(e,"imageLink");
		}
		var img = createTiddlyElement(e,"img");
		if(floatLeft) img.align="left"; else if(floatRight) img.align="right"; // FLOAT LEFT/RIGHT
		if(XY) { // CUSTOM SIZE with optional EVAL'ED width/height ({{...}},{{...}})
			var parts=XY.replace(/[\(\)]/g,'').split(","); var x=parts[0]; var y=parts[1];
			if (x.substr(0,2)=="{{") {
				try{img.style.width=eval(x.substr(2,x.length-4));}
				catch(e){displayMessage(e.description||e.toString())}
			} else img.style.width=x;

			if (y.substr(0,2)=="{{") {
				try{img.style.height=eval(y.substr(2,y.length-4));}
				catch(e){displayMessage(e.description||e.toString())}
			} else img.style.height=y;
		}
		if(tooltip) img.title = tooltip; // TOOLTIP
		// GET IMAGE SOURCE (get attachment or resolve fallback path as needed)
		if (config.macros.attach && config.macros.attach.isAttachment(src))
			src=config.macros.attach.getAttachment(src); // see [[AttachFilePluginFormatters]]
		else if (config.formatterHelpers.resolvePath) { // see [[ImagePathPlugin]]
			// Note: IE and Safari use onError to call resolvePath() only if initial lookup fails
			// (avoids security messages for initial filesystem access)... otherwise, attempt to
			// resolve the original path/file before initial rendering
			if (config.browser.isIE || config.browser.isSafari) {
				img.onerror=(function(){
					this.src=config.formatterHelpers.resolvePath(this.src,false);
					return false;
				});
			} else
				src=config.formatterHelpers.resolvePath(lookaheadMatch[5],true);
		}
		img.src=src; // RENDER IMAGE
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	}
}
//}}}
 @@color(black):font-size(0.8em): Post Doctoral Researcher
Mechanical Engineering
Johns Hopkins University

[[Home]]
<<slider chkSlide [[ResearchItems]] Research>>
[[Graduate Courses]]
[[Activities]]
[[Calendar of Events]]
[[Miscellaneous]]
<<slider chkSlide [[ClassItems]] TAs>>
[[Contact]]
[[Share]]
!!Sample Matlab codes
@@color(red):NOTE:@@ Some Matlab codes below have input argument as fun or dfun. Be careful, If inside the code, @@color(darkred): eval(fun)@@ or @@color(darkred): eval(dfun)/ feval(fun)@@ is used, you can call them like below (I show how to use first code),
{{{
>> syms x;           %defining symbolic x
>> f= x.^2 ;           % your function here x^2
>> IR=rectangular(2,3,20,f)    %integration of f from 2 to 3 with 20 interval
}}}
Otherwise, you need to write a function and pass its name inside ' ' to the code, for example using input argument 'funname' for passing funtion funname to the code. For further information refer to [[Basic MATLAB]]

#Introduction
#Numerical integration
#*Rectangular & trapezoidal rules 
{{{
function int = rectangular(a,b,m,fun)
h=(b-a)/m; x=[a:h:b-h/2]; dim = max(size(x)); y=eval(fun);
if size(y)==1, y=diag(ones(dim))*y; end; int=h*sum(y);
}}}
{{{
function int = trapezc(a,b,m,fun)
h=(b-a)/m; x=[a:h:b]; dim = max(size(x)); y=eval(fun);
if size(y)==1, y=diag(ones(dim))*y; end;
int=h*(0.5*y(1)+sum(y(2:m))+0.5*y(m+1));
}}}
#*Simpson’s Rule
{{{
function int = simpsonc(a,b,m,fun)
h=(b-a)/m; x=[a:h/2:b]; dim = max(size(x)); y=eval(fun);
if size(y)==1, y=diag(ones(dim))*y; end;
int=(h/6)*(y(1)+2*sum(y(3:2:2*m-1))+4*sum(y(2:2:2*m))+y(2*m+1));
}}}
#*Romberg integration
{{{
function [A]=romberg(a,b,n,fun);

for i=1:(n+1), A(i,1)=trapezc(a,b,2ˆ(i-1),fun); end;
for j=2:(n+1), for i=j:(n+1),
A(i,j)=(4ˆ(j-1)*A(i,j-1)-A(i-1,j-1))/(4ˆ(j-1)-1); end; end;
}}}
#*~Gauss-Legender integration
{{{
function int=gausslege(a,b,n,fun)
%Approximates integral using Gauss-Legendre quadrature method
p(1,1)=1;
p(2,1:2)=[1 0]; 
for k=2:n
   p(k+1,1:k+1)=((2*k-1)*[p(k,1:k) 0]-(k-1)*[0 0 p(k-1,1:k-1)])/k;
end
%Polin roots
x=roots(p(n+1,:));
%Change of integration variable if it's needed
if a~=-1 | b~=1
   y=flege(fun,a,b);
   G=subs(y,x);
else
   G=feval(fun,x);		
end
%Polin derivative
pn=polyder(p(n+1,:));
%Calculus of the coefficients
for i=1:n
   C(i)=2./((1-x(i).^2).*((polyval(pn,x(i))).^2));
end
%Product of the function at the nodes and the coefficients
int=dot(C,G);

function y=flege(fun,a,b)
%Performs variable change if a=!-1 | b=!1
syms x;
x=((b-a)./2).*x+(b+a)./2;
dx=(b-a)./2;
y=feval(fun,x)*dx;
}}}
#Nonlinear equations
#*Linear iteration
{{{
function [xvect,xdif,fx,nit]=fixpoint(x0,nmax,toll,fun,phi)
err=toll+1; nit=0; xvect=x0; x=x0; fx=eval(fun); xdif=[];
while (nit < nmax & err > toll),
      nit=nit+1; x=xvect(nit); xn=eval(phi); err=abs(xn-x);
      xdif=[xdif; err]; x=xn; xvect=[xvect;x]; fx=[fx;eval(fun)];
end;
}}}
#*~Newton-Raphson algorithm
{{{
function [xvect,xdif,fx,nit]=newton(x0,nmax,toll,fun,dfun)
err=toll+1; nit=0; xvect=x0; x=x0; fx=eval(fun); xdif=[];
while (nit < nmax & err > toll),
      nit=nit+1; x=xvect(nit); dfx=eval(dfun);
      if (dfx == 0), err=toll*1.e-10;
              disp(’ Stop for vanishing dfun ’);
      else,
              xn=x-fx(nit)/dfx; err=abs(xn-x); xdif=[xdif; err];
              x=xn; xvect=[xvect;x]; fx=[fx;eval(fun)];
     end;
end;
}}}
#*Bisection method
{{{
function [xvect,xdif,fx,nit]=bisect(a,b,toll,nmax,fun)
err=toll+1; nit=0; xvect=[]; fx=[]; xdif=[];
while (nit < nmax & err > toll)
       nit=nit+1; c=(a+b)/2; x=c; fc=eval(fun); xvect=[xvect;x];
       fx=[fx;fc]; x=a; if (fc*eval(fun) > 0), a=c; else, b=c; end;
       err=abs(b-a); xdif=[xdif;err];
end;
}}}
#Nonlinear ordinary differential equations
#*Taylor and Euler algorithm
{{{
function E=euler(fun,a,b,ya,M)

%Input    - y'=fun is the function 
%            - a and b are the left and right endpoints
%            - ya is the initial condition y(a)
%            - M is the number of steps
%Output - E=[T' Y'] where T is the vector of abscissas and
%            - Y is the vector of ordinates

%If fun is defined as an M-file function use the @ notation
% call E=euler(@fun,a,b,ya,M).
%If fun is defined as an anonymous function use the
% call E=euler(fun,a,b,ya,M).

%  NUMERICAL METHODS: Matlab Programs
% (c) 2004 by John H. Mathews and Kurtis D. Fink
%  Complementary Software to accompany the textbook:
%  NUMERICAL METHODS: Using Matlab, Fourth Edition
%  ISBN: 0-13-065248-2
%  Prentice-Hall Pub. Inc.
%  One Lake Street
%  Upper Saddle River, NJ 07458

h=(b-a)/M;
T=zeros(1,M+1);
Y=zeros(1,M+1);
T=a:h:b;
Y(1)=ya;
for j=1:M
   Y(j+1)=Y(j)+h*fun(T(j),Y(j));
end

E=[T' Y'];
}}}
{{{
function T4=taylor(dfun,a,b,ya,M)

%Input    - dfun=[y' y'' y''' y''''] where y'=fun(t,y)
%            - a and b are the left and right endpoints
%            - ya is the initial condition y(a)
%            - M is the number of steps
%Output - T4=[T' Y'] where T is the vector of abscissas and
%            - Y is the vector of ordinates
%If dfun is an M-file function call T4=taylor(@dfun,a,b,ya,M).
%If dfun is an anonymous function call T4=taylor(dfun,a,b,ya,M).

%  NUMERICAL METHODS: Matlab Programs
% (c) 2004 by John H. Mathews and Kurtis D. Fink
%  Complementary Software to accompany the textbook:
%  NUMERICAL METHODS: Using Matlab, Fourth Edition
%  ISBN: 0-13-065248-2
%  Prentice-Hall Pub. Inc.
%  One Lake Street
%  Upper Saddle River, NJ 07458

h=(b-a)/M;
T=zeros(1,M+1);
Y=zeros(1,M+1);
T=a:h:b;
Y(1)=ya;
for j=1:M
   D=dfun(T(j),Y(j));
   Y(j+1)=Y(j)+h*(D(1)+h*(D(2)/2+h*(D(3)/6+h*D(4)/24)));
end
T4=[T' Y'];
}}}
#*~Runge-Kutta algorithms
{{{
function runge_kutta4(a, b, N, alpha)

%function runge_kutta4() approximates the solution of the IVP
%y' = f(t,y) with t in the interval [a;b] and y(a) = alpha (the initial condition)
%by the Runge-Kutta method of order four.

%the inputs to this function are:
%a and b: the endpoints of the interval where the solution is to be approximated
%N: the number of subdivisions in the interval [a;b]
%alpha: the initial condition
%the ouput is a set of values approximating the solution of the IVP
%some extra lines of code could be added for visualization and comparison with the exact 
%solution if known [plot(t, exact solution as y(t)]

%This file was generated after following a course in numerical methods at
%the University of Pretoria, Department of Mathematics and Applied Mathematics
%The algorithmic scheme in this file was drawn from the book of Burden & Faires
%Numerical Analysis, 7th Ed.
%Author: Alain G. Kapitho
%Date  : Dec. 2005

h = (b-a)/N;		%the step size
t(1) = a;			
w(1) = alpha;		%the initial value
for i = 1:N
   k1 = h*fun(t(i), w(i));
   k2 = h*fun(t(i)+h/2, w(i)+(k1)/2);
   k3 = h*fun(t(i)+h/2, w(i)+(k2)/2);
   k4 = h*fun(t(i)+h, w(i)+k3);
   w(i+1) = w(i) + (k1 + 2*k2 + 2*k3 + k4)/6;
   t(i+1) = a + i*h;
end
[t' w']
%this line of code below is optional if visualization is not needed
plot(t, w, 'r*')
%function 
function dy = fun(t, y)
dy = y./t - (y./t)^2;
}}}

#*Stability analysis
#Linear systems of equations
#*Cramer’s rule
#*Elimination schemes
#*LU factorization
{{{
function [A] = lu_kji (A)
%LU factorization of matrix A. kji version
[n,n]=size(A);
for k=1:n-1
     A(k+1:n,k)=A(k+1:n,k)/A(k,k);
     for j=k+1:n, for i=k+1:n
          A(i,j)=A(i,j)-A(i,k)*A(k,j);
     end, end
end
}}}
{{{
function [A] = lu_jki (A)
%LU factorization of matrix A. jki version
[n,n]=size(A);
for j=1:n
    for k=1:j-1, for i=k+1:n
         A(i,j)=A(i,j)-A(i,k)*A(k,j);
    end, end
    for i=j+1:n, A(i,j)=A(i,j)/A(j,j); end
end
}}}
{{{
function [A] = lu_ijk (A)
%LU factorization of the matrix A: ijk version
[n,n]=size(A);
for i=1:n
    for j=2:i
        A(i,j-1)=A(i,j-1)/A(j-1,j-1);
        for k=1:j-1, A(i,j)=A(i,j)-A(i,k)*A(k,j); end
    end
    for j=i+1:n
        for k=1:i-1, A(i,j)=A(i,j)-A(i,k)*A(k,j); end
    end
end
}}}
#*QR factorization
{{{
function [Q,R] = QR(A)
%Modified Gram-Schmidt method
[m,n]=size(A);
Q=zeros(m,n); Q(1:m,1) = A(1:m,1); R=zeros(n); R(1,1)=1;
for k = 1:n
    R(k,k) = norm (A(1:m,k)); Q(1:m,k) = A(1:m,k)/R(k,k);
    for j=k+1:n
        R (k,j) = Q (1:m,k)’ * A(1:m,j);
        A (1:m,j) = A (1:m,j) - Q(1:m,k)*R(k,j);
    end
end
}}}
#*Jacobi’s method
{{{
function [x]=jacobi(A, b, N)

%Jacobi(A, b, N) solve iteratively a system of linear equations whereby
%A is the coefficient matrix, and b is the right-hand side column vector.
%N is the maximum number of iterations.
%The method implemented is the Jacobi iterative. 
%The starting vector is the null vector, but can be adjusted to one's needs.
%The iterative form is based on the Jacobi transition/iteration matrix
%Tj = inv(D)*(L+U) and the constant vector cj = inv(D)*b.
%The output is the solution vector x. 

%This file follows the algorithmic guidelines given in the book 
%Numerical Analysis, 7th Ed, by Burden & Faires
%Author: Alain G. Kapitho
%Date  : Dec. 2005
%Rev.  : Aug. 2007

n = size(A,1);
%splitting matrix A into the three matrices L, U and D
D = diag(diag(A));
L = tril(-A,-1);
U = triu(-A,1);
%transition matrix and constant vector used for iterations
Tj = inv(D)*(L+U);
cj = inv(D)*b;
tol = 1e-05;
k = 1;
x = zeros(n,1);			%starting vector
while k <= N
   x(:,k+1) = Tj*x(:,k) + cj;
   if norm(x(:,k+1)-x(:,k)) < tol
      disp('The procedure was successful')
      disp('Condition ||x^(k+1) - x^(k)|| < tol was met after k iterations')
      disp(k);
      break
   end
   k = k+1;
end
if norm(x(:,k+1)- x(:,k)) > tol || k > N
   disp('Maximum number of iterations reached without satisfying condition:')
   disp('||x^(k+1) - x^(k)|| < tol'); disp(tol);
   disp('Please, examine the sequence of iterates')
   disp('In case you observe convergence, then increase the maximum number of iterations')
   disp('In case of divergence, the matrix may not be diagonally dominant')
end
}}}
#Partial differential equations
#*Elliptic PDE
#*Parabolic PDE
#*~Crank-Nicholson method
#*Hyperbolic PDE
#Interpolation and approximation of functions
#*Interpolating polynomials
#*Polynomials based on differences
#*Newton’s divided difference polynomials
{{{
function [d]=dividif(x,y)
[n,m]=size(y);
if n == 1, n = m; end
n = n-1; d = zeros (n+1,n+1); d (:,1) = y’;
for j = 2:n+1
      for i = j:n+1
            d (i,j) = ( d (i-1,j-1)-d (i,j-1))/(x (i-j+1)-x (i));
      end
end
}}}
#*Chebyshev polynomials
{{{
function tk = ChebyshevPoly(n)
% Given nonnegative integer n, compute the 
% Chebyshev polynomial T_n. Return the result as a column vector whose mth
% element is the coefficient of x^(n+1-m).
if n==0 
    tk = 1;
elseif n==1
    tk = [1 0]';
else
    tkm2 = zeros(n+1,1);  tkm2(n+1) = 1;
    tkm1 = zeros(n+1,1);  tkm1(n) = 1;
    for k=2:n
        tk = zeros(n+1,1);
        for e=n-k+1:2:n
            tk(e) = 2*tkm1(e+1) - tkm2(e);
        end
        if mod(k,2)==0
            tk(n+1) = (-1)^(k/2);
        end
        if k<n
            tkm2 = tkm1;  tkm1 = tk;
        end
    end
end
}}}
#*Legendre Polynomials
{{{
function p=legendrep(m,x)
%   function which construct Legendre polynomial Pm(x)
%   where M is the degree of polynomial and X is the variable. 
%   Result - P is the char string that should be evaluated EVAL(P)
%   Example:
%   P=legendrep(2,'cos(theta)') will produce
%   P='(3*cos(theta).^2 -1)/2' which then can be evaluated as
%   theta=0.3; P=legendrep(2,'cos(theta)'); Lp=eval(P); produce
%   Lp = 0.8690
%% References: 
%   Gradshteyn, Ryzhik "Table of Integrals Series and Products", 6th ed., p.973
%__________________________________________________
% 	Sergei Koptenko, Resonant Medical Inc., Toronto 
%	sergei.koptenko@resonantmedical.com 
%______________March/30/2004_______________________
switch m
case 0
    p='1';     return
case 1
    p=x;     return
case 2
    p=['(3*' x '.^2 -1)/2'];     return
case 3
    p=['(5*' x '.^3 - 3 *' x ')/2'];     return
case 4
    p=['(35 *' x '.^4 - 30 * ' x '.^2 + 3)/8'];     return
case 5
    p=['( 63 * ' x '.^5 - 70 * ' x '.^3 + 15 *' x ' )/8'];     return
case 6
    p=['(231 *' x '.^6 - 315 * ' x '.^4 + 105 * ' x '.^2 -5)/16'];     return
 case 7
   p=['(429 * ' x '.^7 - 693 * ' x '.^5 +315 * ' x '.^3 -35 *' x ' )/16'];     return
case 8
    p=['(6435 *' x '.^8 -12012 *' x '.^6 + 6930 * ' x '.^4 -1260 * ' x '.^2 +35)/128'];     return
case 9
    p=['(12155 * ' x '.^9 -25740 * ' x '.^7 +18018 * ' x '.^5 -4620 * ' x '.^3 +315 *' x ' )/128'];
    return
case 10
       p=['(46189 *' x '.^10 -109395 *' x '.^8 +90090 *' x '.^6 -30030 * ' x '.^4 +3465 * ' x '.^2 -63)/256'];
    return
case 11
   p=['(88179 * ' x '.^11 -230945 * ' x '.^9 +218790 * ' x '.^7 -90090 * ' x '.^5 +15015 * ' x '.^3 -693 *' x ' )/256'];
    return  
case 12
    p=['(676039 *' x '.^12 -1939938 *' x '.^10 +2078505 *' x '.^8 -1021020 *' x '.^6 +225225 * ' x '.^4 -18018 * ' x '.^2 +231)/1024'];
    return
otherwise
    iii=m-10;    %shift counter    
   pp=strvcat(legendrep(11,x),legendrep(12,x)); % get last two members
    for ii=3:1:iii,   % Begin construct from 13th member        
        p_ii=[num2str(1/(ii)) ' * (' num2str(2*ii-1) ' * ' x '.*(' ...
        deblank(pp(ii-1,:)) ')-' num2str(ii-1) '.*(' deblank(pp(ii-2,:)) '))'];
        pp=strvcat(pp, p_ii);
    end
p=deblank(pp(iii,:)); % remove traiing blanks
   return
end
return
}}}

#*Least squares methods
MATLAB's power is that one can work with matrices. In the section [[Arithmetic Operations]] we have described how to enter row and column vectors, which are 1x//n// and //n//x1 matrices, respectively. In order to build bigger matrices, one can type in the matrices row by row. So,

{{{>>[1 2 3; 4 5 6; 7 8 9]}}} 

will produce the matrix 

{{{ans=}}} 

{{{         1    2   3}}}
{{{         4    5   6}}}
{{{         7    8   9}}}

Writing 

{{{>>A=[1 2 3; 4 5 6; 7 8 9]}}} 

we can call up a particular element using {{{A(2,3)}}} to extract the second row and third column, {{{6}}}. you can also change and element by entering 

{{{>>A(2,3)=10;}}}
{{{>>A}}}

to obtain

{{{A=}}} 

{{{         1    2   3}}}
{{{         4    5   10}}}
{{{         7    8   9}}}

You can also extract rows and columns. 

{{{>>B=A(1,:)}}}
{{{>>C=A(:,1}}}

{{{B}}} is the first row and {{{C}}} is the first column. 

Typing

{{{>>A(1,:)=2*B}}} yields  

{{{ans=}}} 

{{{         2    4   6}}}
{{{         4    5   10}}}
{{{         7    8   9}}}

There are several special matrices: {{{eye(N)}}} is the //N//x//N// identity matrix, {{{zeros(N,M)}}} produces and //N//x//M// matrix of zeros, {{{ones(N,M)}}} produces and //N//x//M// matrix of ones, and {{{diag(a)}}} produces a diagonal matrix with vector {{{a}}} along the main diagonal. 
!! UCSD related sites
{{alignBullets{
*@@color(darkblue):[[UCSD Academic Calendar|http://blink.ucsd.edu/Blink/External/Topics/Policy/0,1162,20632,00.html]]@@
*@@color(darkblue):[[Mechanical and Aerospace Engineering|http://maeweb.ucsd.edu/seminars.php]]@@
*@@color(darkblue):[[Graduate Degree Program in Computation Science, Mathematics, and Engineering (CSME)|http://csme.ucsd.edu/]]@@
}}}
!!Some websites
{{alignBullets{
*@@color(darkblue):[[Lauder Laboratories Harvard|http://www.oeb.harvard.edu/lauder/]]@@
*@@color(darkblue):[[Immersed boundary method|http://en.wikipedia.org/wiki/Immersed_boundary_method]]@@
*@@color(darkblue):[[Differential geometry|http://en.wikipedia.org/wiki/Differential_geometry]]@@
*//@@color(green):(NEW)@@//@@color(darkblue):''[[ Introduction to locomotion at low and intermediate Reynolds numbers, ''Stephen Childress" (New York University)|http://www.ima.umn.edu/videos/?id=1240]]''@@

}}}


!!General

{{centeredTable{
| <html><iframe width="420" height="315" src="http://www.youtube.com/embed/RLEeS1R3anU" frameborder="0" allowfullscreen></iframe></html><br> Jerrold Marsden on Discrete Mechanics and Optimal Control |
|borderless|k
}}}

@@color(darkblue):''Dreams''@@
Hold fast to dreams
For if dreams die
Life is a broken-winged bird
That cannot fly.
Hold fast to dreams
For when dreams go
Life is a barren field
Frozen with snow
@@color(darkred)://Langston Hughes//@@
<!--{{{-->
<div id='header'>
</div>

<div id='sidebar'>
<div id='titleLine'></div>
<span id='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span id='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>

<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>

<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>

<div id='tiddlerDisplay'></div>
</div>

<!--}}}-->
/***
|Name|PlayerPlugin|
|Source|http://www.TiddlyTools.com/#PlayerPlugin|
|Version|1.1.4|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Embed a media player in a tiddler|
!!!!!Usage
<<<
{{{<<player [id=xxx] [type] [URL] [width] [height] [autoplay|true|false] [showcontrols|true|false] [extras]>>}}}

''id=xxx'' is optional, and specifies a unique identifier for each embedded player.  note: this is required if you intend to display more than one player at the same time.

''type'' is optional, and is one of the following: ''windows'', ''realone'', ''quicktime'', ''flash'', ''image'' or ''iframe''.  If the media type is not specified, the plugin automatically detects Windows, Real, QuickTime, Flash video or JPG/GIF images by matching known file extensions and/or specialized streaming-media transfer protocols (such as RTSP:).  For unrecognized media types, the plugin displays an error message.

''URL'' is the location of the media content

''width'' and ''height'' are the dimensions of the video display area (in pixels)

''autoplay'' or ''true'' or ''false'' is optional, and specifies whether the media content should begin playing as soon as it is loaded, or wait for the user to press the "play" button.  Default is //not// to autoplay.

''showcontrols'' or ''true'' or ''false'' is optional, and specifies whether the embedded media player should display its built-in control panel (e.g., play, pause, stop, rewind, etc), if any.  Default is to display the player controls.

''extras'' are optional //pairs// of parameters that can be passed to the embedded player, using the {{{<param name=xxx value=yyy>}}} HTML syntax.

''If you use [[AttachFilePlugin]] to encode and store a media file within your document, you can play embedded media content by using the title of the //attachment tiddler//'' as a parameter in place of the usual reference to an external URL.  When playing an attached media content, you should always explicitly specify the media type parameter, because the name used for the attachment tiddler may not contain a known file extension from which a default media type can be readily determined.
<<<
!!!!!Configuration
<<<
Default player size:
width: <<option txtPlayerDefaultWidth>> height: <<option txtPlayerDefaultHeight>>
<<<
===
+++[Still Images]...
GIF (best for illustrations, animations, diagrams, etc.)
{{{<<player id=7 image images/meow.gif auto auto>>}}}
<<player id=7 image images/meow.gif auto auto>>
JPG (best for photographs, scanned images, etc.)
{{{<<player id=8 image images/meow2.jpg 200 150>>}}}
<<player id=8 image images/meow2.jpg 200 150>>
===
<<<
!!!!!Revisions
<<<
2008.05.10 [1.1.4] in handlers(), immediately return if no params (prevents error in macro).  Also, refactored auto-detect code to make type mapping configurable.
2007.10.15 [1.1.3] in loadURL(), add recognition for .PNG (still image), fallback to iframe for unrecognized media types
2007.08.31 [1.1.2] added 'click-through' link for JPG/GIF images
2007.06.21 [1.1.1] changed "hidecontrols" param to "showcontrols" and recognize true/false values in addition to 'showcontrols', added "autoplay" param (also recognize true/false values), allow "auto" as value for type param
2007.05.22 [1.1.0] added support for type=="iframe" (displays src URL in an IFRAME)
2006.12.06 [1.0.1] in handler(), corrected check for config.macros.attach (instead of config.macros.attach.getAttachment) so that player plugin will work when AttachFilePlugin is NOT installed.  (Thanks to Phillip Ehses for bug report)
2006.11.30 [1.0.0] support embedded media content using getAttachment() API defined by AttachFilePlugin or AttachFilePluginFormatters.  Also added support for 'image' type to render JPG/GIF still images
2006.02.26 [0.7.0] major re-write.  handles default params better.  create/recreate player objects via loadURL() API for use with interactive forms and scripts.
2006.01.27 [0.6.0] added support for 'extra' macro params to pass through to object parameters
2006.01.19 [0.5.0] Initial ALPHA release
2005.12.23 [0.0.0] Started
<<<
!!!!!Code
***/
//{{{
version.extensions.PlayerPlugin= {major: 1, minor: 1, revision: 4, date: new Date(2008,5,10)};

config.macros.player = {};
config.macros.player.html = {};
config.macros.player.handler= function(place,macroName,params) {
	if (!params.length) return; // missing parameters - do nothing
	var id=null;
	if (params[0].substr(0,3)=="id=") id=params.shift().substr(3);
	var type="";
	if (!params.length) return; // missing parameters - do nothing
	var p=params[0].toLowerCase();
	if (p=="auto" || p=="windows" || p=="realone" || p=="quicktime" || p=="flash" || p=="image" || p=="iframe")
		type=params.shift().toLowerCase();
	var url=params.shift(); if (!url || !url.trim().length) url="";
	if (url.length && config.macros.attach!=undefined) // if AttachFilePlugin is installed
		if ((tid=store.getTiddler(url))!=null && tid.isTagged("attachment")) // if URL is attachment
			url=config.macros.attach.getAttachment(url); // replace TiddlerTitle with URL
	var width=params.shift();
	var height=params.shift();
	var autoplay=false;
	if (params[0]=='autoplay'||params[0]=='true'||params[0]=='false')
		autoplay=(params.shift()!='false');
	var show=true;
	if (params[0]=='showcontrols'||params[0]=='true'||params[0]=='false')
		show=(params.shift()!='false');
	var extras="";
	while (params[0]!=undefined)
		extras+="<param name='"+params.shift()+"' value='"+params.shift()+"'> ";
	this.loadURL(place,id,type,url,width,height,autoplay,show,extras);
}

if (config.options.txtPlayerDefaultWidth==undefined) config.options.txtPlayerDefaultWidth="100%";
if (config.options.txtPlayerDefaultHeight==undefined) config.options.txtPlayerDefaultHeight="480"; // can't use "100%"... player height doesn't stretch right :-(

config.macros.player.typeMap={
	windows: ['mms', '.asx', '.wvx', '.wmv', '.mp3'],
	realone: ['rtsp', '.ram', '.rpm', '.rm', '.ra'],
	quicktime: ['.mov', '.qt'],
	flash: ['.swf', '.flv'],
	image: ['.jpg', '.gif', '.png'],
	iframe: ['.htm', '.html', '.shtml', '.php']
};

config.macros.player.loadURL=function(place,id,type,url,width,height,autoplay,show,extras) {

	if (id==undefined) id="tiddlyPlayer";
	if (!width) var width=config.options.txtPlayerDefaultWidth;
	if (!height) var height=config.options.txtPlayerDefaultHeight;
	if (url && (!type || !type.length || type=="auto")) { // determine type from URL
		u=url.toLowerCase();
		var map=config.macros.player.typeMap;
		for (var t in map) for (var i=0; i<map[t].length; i++)
			if (u.indexOf(map[t][i])!=-1) var type=t;
	}
	if (!type || !config.macros.player.html[type]) var type="none";
	if (!url) var url="";
	if (show===undefined) var show=true;
	if (!extras) var extras="";
	if (type=="none" && url.trim().length) type="iframe"; // fallback to iframe for unrecognized media types

	// adjust parameter values for player-specific embedded HTML
	switch (type) {
		case "windows":
			autoplay=autoplay?"1":"0"; // player-specific param value
			show=show?"1":"0"; // player-specific param value
			break;
		case "realone":
			autoplay=autoplay?"true":"false";
			show=show?"block":"none";
			height-=show?60:0; // leave room for controls
			break;
		case "quicktime":
			autoplay=autoplay?"true":"false";
			show=show?"true":"false";
			break;
		case "image":
			show=show?"block":"none";
			break;
		case "iframe":
			show=show?"block":"none";
			break;
	}

	// create containing div for player HTML
	// and add or replace player in TW DOM structure
	var newplayer = document.createElement("div");
	newplayer.playerType=type;
	newplayer.setAttribute("id",id+"_div");
	var existing = document.getElementById(id+"_div");
	if (existing && !place) place=existing.parentNode;
	if (!existing)
		place.appendChild(newplayer);
	else {
		if (place==existing.parentNode) place.replaceChild(newplayer,existing)
		else { existing.parentNode.removeChild(existing); place.appendChild(newplayer); }
	}

	var html=config.macros.player.html[type];
	html=html.replace(/%i%/mg,id);
	html=html.replace(/%w%/mg,width);
	html=html.replace(/%h%/mg,height);
	html=html.replace(/%u%/mg,url);
	html=html.replace(/%a%/mg,autoplay);
	html=html.replace(/%s%/mg,show);
	html=html.replace(/%x%/mg,extras);
	newplayer.innerHTML=html;
}
//}}}

// // Player-specific API functions: isReady(id), isPlaying(id), toggleControls(id), showControls(id,flag)

//{{{
// status values:
// Windows: 0=Undefined, 1=Stopped, 2=Paused, 3=Playing, 4=ScanForward, 5=ScanReverse
//          6=Buffering, 7=Waiting, 8=MediaEnded, 9=Transitioning, 10=Ready, 11=Reconnecting
// RealOne: 0=Stopped, 1=Contacting, 2=Buffering, 3=Playing, 4=Paused, 5=Seeking
// QuickTime: 'Waiting', 'Loading', 'Playable', 'Complete', 'Error:###'
// Flash: 0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete
config.macros.player.isReady=function(id)
{
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') return !((p.playState==0)||(p.playState==7)||(p.playState==9)||(p.playState==11));
	if (d.playerType=='realone') return (p.GetPlayState()>1);
	if (d.playerType=='quicktime') return !((p.getPluginStatus()=='Waiting')||(p.getPluginStatus()=='Loading'));
	if (d.playerType=='flash') return (p.ReadyState>2);
	return true;
}
config.macros.player.isPlaying=function(id)
{
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') return (p.playState==3);
	if (d.playerType=='realone') return (p.GetPlayState()==3);
	if (d.playerType=='quicktime') return (p.getPluginStatus()=='Complete');
	if (d.playerType=='flash') return (p.ReadyState<4);
	return false;
}
config.macros.player.showControls=function(id,flag) {
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') { p.ShowControls=flag; p.ShowStatusBar=flag; }
	if (d.playerType=='realone') { alert('show/hide controls not available'); }
	if (d.playerType=='quicktime')      // if player not ready, retry in one second
		{ if (this.isReady(id)) p.setControllerVisible(flag); else setTimeout('config.macros.player.showControls("'+id+'",'+flag+')',1000); }
	if (d.playerType=='flash') { alert('show/hide controls not available'); }
}
config.macros.player.toggleControls=function(id) {
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') var flag=!p.ShowControls;
	if (d.playerType=='realone') var flag=true; // TBD
	if (d.playerType=='quicktime') var flag=!p.getControllerVisible();
	if (d.playerType=='flash') var flag=true; // TBD
	this.showControls(id,flag);
}
config.macros.player.fullScreen=function(id) {
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') p.DisplaySize=3;
	if (d.playerType=='realone') p.SetFullScreen();
	if (d.playerType=='quicktime') { alert('full screen not available'); }
	if (d.playerType=='flash') { alert('full screen not available'); }
}
//}}}

// // Player HTML

//{{{
// placeholder (no player)
config.macros.player.html.none=' \
	<table id="%i%" width="%w%" height="%h%" style="background-color:#111;border:0;margin:0;padding:0;"> \
	<tr style="background-color:#111;border:0;margin:0;padding:0;"> \
	<td width="%w%" height="%h%" style="background-color:#111;color:#ccc;border:0;margin:0;padding:0;text-align:center;"> \
	&nbsp; \
	%u% \
	&nbsp; \
	</td></tr></table>';
//}}}

//{{{
// JPG/GIF/PNG still images
config.macros.player.html.image='\
	<a href="%u%" target="_blank"><img width="%w%" height="%h%" style="display:%s%;" src="%u%"></a>';
//}}}

//{{{
// IFRAME web page viewer
config.macros.player.html.iframe='\
	<iframe id="%i%" width="%w%" height="%h%" style="display:%s%;background:#fff;" src="%u%"></iframe>';
//}}}

//{{{
// Windows Media Player
// v7.1 ID: classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6
// v9	ID: classid=CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95
config.macros.player.html.windows=' \
	<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;width:%w%;height:%h%px;" \
		classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" \
		codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715" \
		align="baseline" border="0" \
		standby="Loading Microsoft Windows Media Player components..." \
		type="application/x-oleobject"> \
		<param name="FileName" value="%u%"> <param name="ShowControls" value="%s%"> \
		<param name="ShowPositionControls" value="1"> <param name="ShowAudioControls" value="1"> \
		<param name="ShowTracker" value="1"> <param name="ShowDisplay" value="0"> \
		<param name="ShowStatusBar" value="1"> <param name="AutoSize" value="1"> \
		<param name="ShowGotoBar" value="0"> <param name="ShowCaptioning" value="0"> \
		<param name="AutoStart" value="%a%"> <param name="AnimationAtStart" value="1"> \
		<param name="TransparentAtStart" value="0"> <param name="AllowScan" value="1"> \
		<param name="EnableContextMenu" value="1"> <param name="ClickToPlay" value="1"> \
		<param name="InvokeURLs" value="1"> <param name="DefaultFrame" value="datawindow"> \
		%x% \
		<embed src="%u%" style="margin:0;padding:0;width:%w%;height:%h%px;" \
			align="baseline" border="0" width="%w%" height="%h%" \
			type="application/x-mplayer2" \
			pluginspage="http://www.microsoft.com/windows/windowsmedia/download/default.asp" \
			name="%i%" showcontrols="%s%" showpositioncontrols="1" \
			showaudiocontrols="1" showtracker="1" showdisplay="0" \
			showstatusbar="%s%" autosize="1" showgotobar="0" showcaptioning="0" \
			autostart="%a%" autorewind="0" animationatstart="1" transparentatstart="0" \
			allowscan="1" enablecontextmenu="1" clicktoplay="0" invokeurls="1" \
			defaultframe="datawindow"> \
		</embed> \
	</object>';
//}}}

//{{{
// RealNetworks' RealOne Player
config.macros.player.html.realone=' \
	<table width="%w%" style="border:0;margin:0;padding:0;"><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \
	<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \
		CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \
		<PARAM NAME="CONSOLE" VALUE="player"> \
		<PARAM NAME="CONTROLS" VALUE="ImageWindow"> \
		<PARAM NAME="AUTOSTART" Value="%a%"> \
		<PARAM NAME="MAINTAINASPECT" Value="true"> \
		<PARAM NAME="NOLOGO" Value="true"> \
		<PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \
		<PARAM NAME="SRC" VALUE="%u%"> \
		%x% \
		<EMBED width="%w%" height="%h%" controls="ImageWindow" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;" \
			name="%i%" \
			src="%u%" \
			console=player \
			maintainaspect=true \
			nologo=true \
			backgroundcolor=#333333 \
			autostart=%a%> \
		</OBJECT> \
	</td></tr><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \

	<object id="%i%_controls" width="%w%" height="60" style="margin:0;padding:0;display:%s%" \
		CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \
		<PARAM NAME="CONSOLE" VALUE="player"> \
		<PARAM NAME="CONTROLS" VALUE="All"> \
		<PARAM NAME="NOJAVA" Value="true"> \
		<PARAM NAME="MAINTAINASPECT" Value="true"> \
		<PARAM NAME="NOLOGO" Value="true"> \
		<PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \
		<PARAM NAME="SRC" VALUE="%u%"> \
		%x% \
		<EMBED WIDTH="%w%" HEIGHT="60" NOJAVA="true" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;display:%s%" \
			controls="All" \
			name="%i%_controls" \
			src="%u%" \
			console=player \
			maintainaspect=true \
			nologo=true \
			backgroundcolor=#333333> \
		</OBJECT> \
	</td></tr></table>';
//}}}

//{{{
// QuickTime Player
config.macros.player.html.quicktime=' \
	<OBJECT ID="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \
		CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" \
		CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab"> \
		<PARAM name="SRC" VALUE="%u%"> \
		<PARAM name="AUTOPLAY" VALUE="%a%"> \
		<PARAM name="CONTROLLER" VALUE="%s%"> \
		<PARAM name="BGCOLOR" VALUE="#333333"> \
		<PARAM name="SCALE" VALUE="aspect"> \
		<PARAM name="SAVEEMBEDTAGS" VALUE="true"> \
		%x% \
		<EMBED name="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \
			SRC="%u%" \
			AUTOPLAY="%a%" \
			SCALE="aspect" \
			CONTROLLER="%s%" \
			BGCOLOR="#333333" \
			EnableJavaSript="true" \
			PLUGINSPAGE="http://www.apple.com/quicktime/download/"> \
		</EMBED> \
	</OBJECT>';
//}}}

//{{{
// Flash Player
config.macros.player.html.flash='\
	<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \
		classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" \
		codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0"> \
		<param name="movie" value="%u%"> \
		<param name="quality" value="high"> \
		<param name="SCALE" value="exactfit"> \
		<param name="bgcolor" value="333333"> \
		%x% \
		<embed name="%i%" src="%u%" style="margin:0;padding:0;" \
			height="%h%" width="%w%" quality="high" \
			pluginspage="http://www.macromedia.com/go/getflashplayer" \
			type="application/x-shockwave-flash" scale="exactfit"> \
		</embed> \
	</object>';
//}}}
/***
|Name|Plugin: Scientific Notation|
|Created by|BobMcElrath|
|Email|my first name at my last name dot org|
|Location|http://bob.mcelrath.org/tiddlyjsmath-2.0.3.html|
|Version|1.0|
|Requires|[[TiddlyWiki|http://www.tiddlywiki.com]] &ge; 2.0.3, [[jsMath|http://www.math.union.edu/~dpvc/jsMath/]] &ge; 3.0, [[Plugin: jsMath]]|
!Description
This plugin will render numbers expressed in scientific notation, such as {{{3.5483e12}}} using the jsMath plugin to display it in an intuitive way such as 3.5483e12.  You may customize the number of significant figures displayed, as well as "normalize" numbers so that {{{47392.387e9}}} is displayed as 47392.387e9.
!Installation
Install the Requirements, above, add this tiddler to your tiddlywiki, and give it the {{{systemConfig}}} tag.
!History
* 1-Feb-06, version 1.0, Initial release
!Code
***/
//{{{
config.formatters.push({
  name: "scientificNotation",
  match: "\\b[0-9]+\\.[0-9]+[eE][+-]?[0-9]+\\b",
  element: "span",
  className: "math",
  normalize: true,                          // set to 'true' to convert numbers to X.XXX \times 10^{y}
  sigfigs: 3,                               // with this many digits in the mantissa
  handler: function(w) {
    var snRegExp = new RegExp("\\b([0-9]+(?:\\.[0-9]+)?)[eE]([-0-9+]+)\\b");
    var mymatch = snRegExp.exec(w.matchText);
    var mantissa = mymatch[1];
    var exponent = parseInt(mymatch[2]);
    // normalize the number.
    if(this.normalize) {
      mantissa = parseFloat(mantissa);
      while(mantissa > 10.0) {
        mantissa = mantissa / 10.0;
        exponent++; 
      }
      while(mantissa < 1.0) {
        mantissa = mantissa * 10.0;
        exponent--;
      }
      var sigfigsleft = this.sigfigs;
      mantissa = parseInt(mantissa) + "." + (Math.round(Math.pow(10,this.sigfigs-1)*mantissa)+"").substr(1,this.sigfigs-1);
    }
    var e = document.createElement(this.element);
    e.className = this.className;
    if(exponent == 0) {
      e.appendChild(document.createTextNode(mantissa));
    } else {
      e.appendChild(document.createTextNode(mantissa + "\\times 10^{" + exponent + "}"));
    }
    w.output.appendChild(e);
  }
});
//}}}
/***
|Name|Plugin: arXiv Links|
|Created by|BobMcElrath|
|Email|my first name at my last name dot org|
|Location|http://bob.mcelrath.org/tiddlyjsmath-2.0.3.html|
|Version|1.0|
|Requires|[[TiddlyWiki|http://www.tiddlywiki.com]] &ge; 2.0.3|
!Description
This formatting plugin will render links to the [[arXiv|http://www.arxiv.org]] preprint system.  If you type a paper reference such as hep-ph/0509024, it will be rendered as an external link to the abstract of that paper.
!Installation
Add this tiddler to your tiddlywiki, and give it the {{{systemConfig}}} tag.
!History
* 1-Feb-06, version 1.0, Initial release
!Code
***/
//{{{
config.formatters.push({
  name: "arXivLinks",
  match: "\\b(?:astro-ph|cond-mat|hep-ph|hep-th|hep-lat|gr-qc|nucl-ex|nucl-th|quant-ph|(?:cs|math|nlin|physics|q-bio)(?:\\.[A-Z]{2})?)/[0-9]{7}\\b",
  element: "a",
  handler: function(w) {
    var e = createExternalLink(w.output, "http://arxiv.org/abs/"+w.matchText);
    e.target = "_blank"; // open in new window
    w.outputText(e,w.matchStart,w.nextMatch);
  }
});
//}}}
/***
|Name|Plugin: jsMath|
|Created by|BobMcElrath|
|Email|my first name at my last name dot org|
|Location|http://bob.mcelrath.org/tiddlyjsmath.html|
|Version|1.5.1|
|Requires|[[TiddlyWiki|http://www.tiddlywiki.com]] &ge; 2.0.3, [[jsMath|http://www.math.union.edu/~dpvc/jsMath/]] &ge; 3.0|
!Description
LaTeX is the world standard for specifying, typesetting, and communicating mathematics among scientists, engineers, and mathematicians.  For more information about LaTeX itself, visit the [[LaTeX Project|http://www.latex-project.org/]].  This plugin typesets math using [[jsMath|http://www.math.union.edu/~dpvc/jsMath/]], which is an implementation of the TeX math rules and typesetting in javascript, for your browser.  Notice the small button in the lower right corner which opens its control panel.
!Installation
In addition to this plugin, you must also [[install jsMath|http://www.math.union.edu/~dpvc/jsMath/download/jsMath.html]] on the same server as your TiddlyWiki html file.  If you're using TiddlyWiki without a web server, then the jsMath directory must be placed in the same location as the TiddlyWiki html file.

I also recommend modifying your StyleSheet use serif fonts that are slightly larger than normal, so that the math matches surrounding text, and \\small fonts are not unreadable (as in exponents and subscripts).
{{{
.viewer {
  line-height: 125%;
  font-family: serif;
  font-size: 12pt;
}
}}}

If you had used a previous version of [[Plugin: jsMath]], it is no longer necessary to edit the main tiddlywiki.html file to add the jsMath <script> tag.  [[Plugin: jsMath]] now uses ajax to load jsMath.
!History
* 11-Nov-05, version 1.0, Initial release
* 22-Jan-06, version 1.1, updated for ~TW2.0, tested with jsMath 3.1, editing tiddlywiki.html by hand is no longer necessary.
* 24-Jan-06, version 1.2, fixes for Safari, Konqueror
* 27-Jan-06, version 1.3, improved error handling, detect if ajax was already defined (used by ZiddlyWiki)
* 12-Jul-06, version 1.4, fixed problem with not finding image fonts
* 26-Feb-07, version 1.5, fixed problem with Mozilla "unterminated character class".
* 27-Feb-07, version 1.5.1, Runs compatibly with TW 2.1.0+, by Bram Chen
!Examples
|!Source|!Output|h
|{{{The variable $x$ is real.}}}|The variable $x$ is real.|
|{{{The variable \(y\) is complex.}}}|The variable \(y\) is complex.|
|{{{This \[\int_a^b x = \frac{1}{2}(b^2-a^2)\] is an easy integral.}}}|This \[\int_a^b x = \frac{1}{2}(b^2-a^2)\] is an easy integral.|
|{{{This $$\int_a^b \sin x = -(\cos b - \cos a)$$ is another easy integral.}}}|This $$\int_a^b \sin x = -(\cos b - \cos a)$$ is another easy integral.|
|{{{Block formatted equations may also use the 'equation' environment \begin{equation}  \int \tan x = -\ln \cos x \end{equation} }}}|Block formatted equations may also use the 'equation' environment \begin{equation}  \int \tan x = -\ln \cos x \end{equation}|
|{{{Equation arrays are also supported \begin{eqnarray} a &=& b \\ c &=& d \end{eqnarray} }}}|Equation arrays are also supported \begin{eqnarray} a &=& b \\ c &=& d \end{eqnarray} |
|{{{I spent \$7.38 on lunch.}}}|I spent \$7.38 on lunch.|
|{{{I had to insert a backslash (\\) into my document}}}|I had to insert a backslash (\\) into my document|
!Code
***/
//{{{

// AJAX code adapted from http://timmorgan.org/mini
// This is already loaded by ziddlywiki...
if(typeof(window["ajax"]) == "undefined") {
  ajax = {
      x: function(){try{return new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{return new ActiveXObject('Microsoft.XMLHTTP')}catch(e){return new XMLHttpRequest()}}},
      gets: function(url){var x=ajax.x();x.open('GET',url,false);x.send(null);return x.responseText}
  }
}

// Load jsMath
jsMath = {
  Setup: {inited: 1},          // don't run jsMath.Setup.Body() yet
  Autoload: {root: new String(document.location).replace(/[^\/]*$/,'jsMath/')}  // URL to jsMath directory, change if necessary
};
var jsMathstr;
try {
  jsMathstr = ajax.gets(jsMath.Autoload.root+"jsMath.js");
} catch(e) {
  alert("jsMath was not found: you must place the 'jsMath' directory in the same place as this file.  "
       +"The error was:\n"+e.name+": "+e.message);
  throw(e);  // abort eval
}
try {
  window.eval(jsMathstr);
} catch(e) {
  alert("jsMath failed to load.  The error was:\n"+e.name + ": " + e.message + " on line " + e.lineNumber);
}
jsMath.Setup.inited=0;  //  allow jsMath.Setup.Body() to run again

// Define wikifers for latex
config.formatterHelpers.mathFormatHelper = function(w) {
    var e = document.createElement(this.element);
    e.className = this.className;
    var endRegExp = new RegExp(this.terminator, "mg");
    endRegExp.lastIndex = w.matchStart+w.matchLength;
    var matched = endRegExp.exec(w.source);
    if(matched) {
        var txt = w.source.substr(w.matchStart+w.matchLength, 
            matched.index-w.matchStart-w.matchLength);
        if(this.keepdelim) {
          txt = w.source.substr(w.matchStart, matched.index+matched[0].length-w.matchStart);
        }
        e.appendChild(document.createTextNode(txt));
        w.output.appendChild(e);
        w.nextMatch = endRegExp.lastIndex;
    }
}

config.formatters.push({
  name: "displayMath1",
  match: "\\\$\\\$",
  terminator: "\\\$\\\$\\n?", // 2.0 compatability
  termRegExp: "\\\$\\\$\\n?",
  element: "div",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

config.formatters.push({
  name: "inlineMath1",
  match: "\\\$", 
  terminator: "\\\$", // 2.0 compatability
  termRegExp: "\\\$",
  element: "span",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

var backslashformatters = new Array(0);

backslashformatters.push({
  name: "inlineMath2",
  match: "\\\\\\\(",
  terminator: "\\\\\\\)", // 2.0 compatability
  termRegExp: "\\\\\\\)",
  element: "span",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

backslashformatters.push({
  name: "displayMath2",
  match: "\\\\\\\[",
  terminator: "\\\\\\\]\\n?", // 2.0 compatability
  termRegExp: "\\\\\\\]\\n?",
  element: "div",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

backslashformatters.push({
  name: "displayMath3",
  match: "\\\\begin\\{equation\\}",
  terminator: "\\\\end\\{equation\\}\\n?", // 2.0 compatability
  termRegExp: "\\\\end\\{equation\\}\\n?",
  element: "div",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

// These can be nested.  e.g. \begin{equation} \begin{array}{ccc} \begin{array}{ccc} ...
backslashformatters.push({
  name: "displayMath4",
  match: "\\\\begin\\{eqnarray\\}",
  terminator: "\\\\end\\{eqnarray\\}\\n?", // 2.0 compatability
  termRegExp: "\\\\end\\{eqnarray\\}\\n?",
  element: "div",
  className: "math",
  keepdelim: true,
  handler: config.formatterHelpers.mathFormatHelper
});

// The escape must come between backslash formatters and regular ones.
// So any latex-like \commands must be added to the beginning of
// backslashformatters here.
backslashformatters.push({
    name: "escape",
    match: "\\\\.",
    handler: function(w) {
        w.output.appendChild(document.createTextNode(w.source.substr(w.matchStart+1,1)));
        w.nextMatch = w.matchStart+2;
    }
});

config.formatters=backslashformatters.concat(config.formatters);

window.wikify = function(source,output,highlightRegExp,tiddler)
{
    if(source && source != "") {
        if(version.major == 2 && version.minor > 0) {
            var wikifier = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
            wikifier.subWikifyUnterm(output);
        } else {
            var wikifier = new Wikifier(source,formatter,highlightRegExp,tiddler);
            wikifier.subWikify(output,null);
        }
        jsMath.ProcessBeforeShowing();
    }
}
//}}}
!!Selected Conference Publications
*''//@@color(green):       @@//'' @@color(darkblue):"''Two-dimensional study of fluid interaction with ray-strengthened fin using immersed boundary method''"
@@''Kourosh Shoele'', Qiang Zhu. //63rd Annual Meeting of the Division of Fluid Dynamics//, Nov. 23-25, 2010; Long Beach, CA.
*''//@@color(green):       @@//'' @@color(darkblue):"''Fully Coupled Dynamic Model of Offshore Wind Turbines''"
@@''Kourosh Shoele'', Qiang Zhu //Prevention First 2010, An Onshore and Offshore Prevention Symposium//, Oct. 19-20, 2010; Long Beach, CA.
*''//@@color(green):       @@//'' @@color(darkblue):"''Labriform swimming of a ray-strengthened pectoral fin''"
@@''Kourosh Shoele'', Qiang Zhu. //62nd Annual Meeting of the Division of Fluid Dynamics//, Nov. 22-24, 2009; Minneapolis, Minnesota.
*''//@@color(green):       @@//'' @@color(darkblue):"''Performance of skeleton-reinforced biomembranes in locomotion''"
@@Qiang Zhu, ''Kourosh Shoele''. //61th Annual Meeting of the Division of Fluid Dynamics//, Nov. 23-25, 2008; San Antonio, Texas.

!!Presentations
{{alignBullets {
*@@color(darkblue):"Invited speaker"@@, 2011 WSLCA Winter conference, Long Beach, 2011.
*@@color(darkblue):"Invited speaker"@@, Prevention 1st 2010, An Onshore and Offshore Symposium, Long Beach, 2010.
*@@color(darkblue):"Invited speaker"@@, Department of Structural Engineering, University of California San Diego, 2010.
*@@color(darkblue):"Talk"@@, 63rd Annual Meeting of the Division of Fluid Dynamics, Long Beach, 2010.
*@@color(darkblue):"Talk"@@, 4th Southern California Symposium on Flow Physics, University of California, Irvine, Apr 2010.
*@@color(darkblue):"Talk"@@, 62nd Annual Meeting of the Division of Fluid Dynamics, Minneapolis, Minnesota, 2009.
*@@color(darkblue):"Poster"@@, NASA Int. Workshop on Environment and Energy, UC, San Diego, 2010.
*@@color(darkblue):"Poster"@@, Research Expo of Jacob Engineering School, University of California, San Diego, 2010.
*@@color(darkblue):"Poster"@@, Research Expo of Jacob Engineering School, University of California, San Diego, 2009.
}}}
''//@@color(darkblue):13-   @@//'' ''//@@color(green):(NEW)@@//'' @@color(darkblue):"''Experimental and Numerical Investigation of Dynamic and Performance of Heaving Point Absorber with a Subsea Reaction Plate.''"@@,  Mirko Previsic,''Kourosh Shoele'' and Jeff Epler, //sub judice.//
@@color(gray):Abstract:The aim of this study was to validate different theoretical performance models using subscale wave tank tests. The device modeled is a heaving point absorber working against a submerged reaction plate. This type of device has been pursued by a number of commercial and is therefore relevant as a benchmark for future efforts on similar
devices. A set of model tests were carried out at 1:33 scale in the hydraulic laboratory at Scripps Institute of Oceanography. Wave periods between 5 and 20 seconds were selected to test the response of the model to sinusoidal waves. This corresponds roughly to the range of wave periods encountered at most deployment sites of interest globally. A novel viscous damper was developed as part of the project to represent the power take-off. Two theoretical models were developed and their results were compared to the model tests. The first model is based on the commercial code AQWA, which uses hydrodynamic coefficients obtained from a boundary element code and uses those in a timedomain solver where additional terms can be introduced representing the viscous forces on the body. A second model was developed using hydrodynamic coefficients from WAMIT, which were used in a custom time-domain code developed in Matlab. Finally, a wave to wire model was used to compute annual power production at a target deployment location in Northern California. The results show that good agreement between both codes and model testing can be attained if viscous forces are properly represented in the system. @@

!!Recent publications


''//@@color(darkblue):12-   @@//'' ''//@@color(green):(NEW)@@//'' @@color(darkblue):"''Cost Reduction Pathways for Wave Energy.''"@@, Mirko Previsic and  ''Kourosh Shoele'', //Ewtec 2013//,[[PDF|http://fsisg.ucsd.edu/p10.pdf]].
@@color(gray):Abstract: Wave energy will not find any wide-spread adoption until it becomes more cost effective and can be demonstrated at larger scale. This paper reviews the cost-reduction potential in wave power technologies from a plant-scale perspective. It starts with an identification of a baseline cost scenario and discusses the level of COE improvement that could come from different  areas of innovation. Advanced control strategies that allows for power production to be maximized is one of the most important aspects of design optimization. The presented work builds on previous techno-economic assessments and quantifies the effects of specific cost-reduction pathways. A key focus is given to advanced controls performance optimization and its ability to reduce cost of electricity from wave energy converters. Finally it provides a list of research priorities that will allow the wave power sector to make continued progress towards a competitive cost of electricity. @@


''//@@color(darkblue):11-   @@//'' ''//@@color(green):(NEW)@@//'' @@color(darkblue):"''A Novel Simulation Toolbox for Wave Energy Converters.''"@@, ''Kourosh Shoele'' and Mirko Previsic, //Ewtec 2013//,[[PDF|http://fsisg.ucsd.edu/p9.pdf]].
@@color(gray):Abstract: To design a wave energy conversion system, time  domain numerical modelling is required. This is due to the  nonlinearities present in the system from different sources,  including hydrodynamic forces, device dynamics, control  mechanisms, and mooring lines. Combining model accuracy with  the efficient calculation of hydrodynamic forces in the time  domain can be challenging and time consuming to implement.  This paper describes an easy-to-use and unified computational framework that handles those challenges efficiently for different types of wave energy converters. The framework is implemented as a toolbox that contains the key components of a wave-to-wire model. The preprocessing, post-processing, and standardization of the modelling process are among the unique capabilities of the toolbox that enable users to evaluate different device concepts and optimize device performance without having to deal with all the modelling challenges typically encountered in such a project. Finally, a short validation of the model and comparison with wave tank experiments are discussed. @@


''//@@color(darkblue):10-   @@//'' ''//@@color(green):        @@//'' @@color(darkblue):"''Performance of a Wing with Nonuniform Flexibility in Hovering Flight.''"@@, ''Kourosh Shoele'' and Qiang Zhu,  //Physics of Fluids//,25, 041901 (2013). [[PDF|http://fsisg.ucsd.edu/p8.pdf]].
@@color(gray):Abstract: The deformability of insect wings is associated with the embedded skeleton (venation). In this paper, the aerodynamic performance of wings with nonuniform flexibility is computationally investigated. By using a two-dimensional rendition, the underlying veins are modeled as springs, and the membrane is modeled as a flexible plate. The focus is on the effects of the detailed distribution of vein flexibility upon the performance of such a wing in the generation of lift force. Specifically, we  are interested in finding the importance of leading edge strengthening. Towards this end, the aerodynamic performances of three wings, a rigid wing, a flexible wing with identical veins, and a flexible wing with strengthened leading edge, are studied and compared against each other. It is shown that the flexible wing with leading edge strengthening is capable of producing significantly higher lift force without consuming more energy. This is found to be related to the stabilizing and cambering effects at the leading edge, which enhances the leading edge vortices. In addition, in contrast to the other two wings, which show sensitivity to kinematic parameters, the wing with strengthened leading edge perform well over a wide range of parameters.@@


''//@@color(darkblue):9-   @@//'' ''//@@color(green):        @@//'' @@color(darkblue):"''Numerical Modeling of the Performance of Ray Fins in Fish Locomotion.''"@@, Qiang Zhu and ''Kourosh Shoele'',  //Natural Locomotion in Fluids and on Surfaces//, The IMA Volumes in Mathematics and its Applications, 155(2), 151-157, 2012.[[original PDF|http://www.springerlink.com/content/vx1x86812p716183/]].
@@color(gray):Abstract: This is a review of our recent investigation on the structure versus performance of ray fins via a potential-flow based fluid-structure interaction model. The kinematics and dynamic performance of two structurally idealized fins, a caudal fin and a pectoral fin, are considered. The numerical method includes a boundary-element model of the fluid motion and a fully-nonlinear Euler–Bernoulli beam model of the embedded rays. Using this model we studied thrust generation and propulsion efficiency of the fins at different combinations of parameters. Effects of kinematic as well as structural properties are examined. It has been illustrated that the fish’s capacity to control the motion of each individual ray, as well as the anisotropic deformability of the fins determined by the architecture of the rays (especially the detailed distribution of ray stiffness), are essential to high propulsion performance.

Key words: ray fin; fluid-structure interaction; numerical simulation@@

''//@@color(darkblue):8-   @@//'' ''//@@color(green):        @@//'' @@color(darkblue):"''Leading Edge Strengthening and the Propulsion Performance of Flexible Ray Fins.''"@@, ''Kourosh Shoele'' and Qiang Zhu,  //Journal of Fluid Mechanics.//, 693: 402-432, 2012.[[PDF|http://fsisg.ucsd.edu/p6.pdf]].
@@color(gray):Abstract: A numerical model of a ray-reinforced fin is developed to investigate the relation between its structural characteristics and its force generation capacity during flapping motion. In this two-dimensional rendition. The finn kinematics is characterized by its oscillation frequency and the phase difference between different rays (which generates a pitching motion). An immersed boundary method (IBM) is applied for solving the fluid-structure interaction problem. The focus of the current paper is on the effects of ray flexibility, especially the detailed distribution of ray stiffness, upon the capacity of thrust generation. The correlation between thrust generation and features of the surrounding flow (especially the leading edge separation) is also examined. Comparisons are made among a finn with rigid rays, a fin with identical flexible rays, and a fin with flexible rays and strengthened leading edge. It is shown that with flexible rays, the thrust production can be significantly increased, especially in cases when the phase difference between different rays is not optimized. By strengthening the leading edge, a higher propulsion efficiency is observed. It is mostly attributed to the reduction of the effective angle of attack at the leading edge, accompanied by mitigation of leading edge separation and dramatic change in characteristics of the wake. In addition, the flexibility of the rays causes reorientation of the fluid force so that it tilts more towards the swimming direction and the thrust is thus increased.@@

''//@@color(darkblue):7-   @@//'' ''//@@color(green):        @@//'' @@color(darkblue):"''Dynamic and Structural Modeling of a Floating Wind Turbine ''"@@, ''Kourosh Shoele'' , Ian Prowell, Ahmed Elgamal, and Qiang Zhu. //International Journal of Offshore and Polar Engineering//, 21(2), 155-160, 2011.[[PDF|http://fsisg.ucsd.edu/p5.pdf]].
@@color(gray):Abstract: We numerically investigate the dynamic response of a floating wind turbine by developing a fluid-structure interaction model which includes a boundary element model (BEM) for the wave-body interaction, a cable dynamics model for the mooring system, and a finite element model (FEM) for the structural response. The BEM and the cable dynamics model are applied to calculate the frequency-dependent added mass, damping, and restoring coefficients that are used in the dynamic equations to predict the motion of the system, based on which the structural deformation is determined through the FEM. This hybrid approach is applied to simulate the dynamic response (including surging and pitching motions) and structural vibrations of a wind turbine based upon a 65KW design with a spar-buoy style mooring system. 

Key words: floating wind turbine; fluid-structure interaction; hybrid model@@

''//@@color(darkblue):6-   @@//'' ''//@@color(green):        @@//'' @@color(darkblue):"''Numerical Simulation of a Pectoral Fin during Labriform Swimming.''"@@,  ''Kourosh Shoele'' and Qiang Zhu, //Journal of Experimental Biology.//,213, 2038-2047, 2010.[[PDF|http://fsisg.ucsd.edu/p4.pdf]].
@@color(gray):Abstract: We numerically examine the fluid-structure interaction and force generation of a skeleton-reinforced fin that geometrically, structurally, and kinematically resembles the pectoral fin of a fish during labriform swimming. This fin contains a soft membrane with negligible bending stiffness and twelve embedded rays (modeled as beams). A potential flow based boundary element model is applied to solve the fluid flow around the fin, in which the vorticity field is modeled as thin vorticity sheets shed from prescribed locations (the sharp trailing edge). The fin motion is actuated by rolling and tilting motions of the rays (the motion of each ray is controlled individually), as well as pitching motions of the baseline. Consequently the fin undergoes a combination of flapping (lift-based) and rowing (drag-based) motions typical in labriform swimming. The fin kinematics contains two strokes, a recovery stroke and a power stroke. The performance of the fin depends upon kinematic parameters such as the Strouhal number, the phase lag between rays, the pitching motion of the baseline, and the passive deformations of the rays. The most interesting finding is that the strengthening of the ray at the leading edge plays a pivotal role in performance enhancement by reducing the effective angle of attack and decreasing the energy expenditure during the recovery stroke.

Key words: fluid-structure interaction, skeleton-reinforced membrane, pectoral fin, labriform locomotion @@

''//@@color(darkblue):5-   @@//'' ''//@@color(green):        @@//'' @@color(darkblue):"''Flow-induced vibrations of a deformable ring.''"@@, ''Kourosh Shoele'' and Qiang Zhu, //Journal of Fluid Mechanics.//, 650: 343-362, 2010.[[PDF|http://fsisg.ucsd.edu/p3.pdf]].
@@color(gray):Abstract: To understand flow-induced vibrations of deformable objects, we numerically investigate dynamics of an elastic ring pinned at one point within a uniform flow by using an immersed-boundary algorithm. The ring has no bending stiffness and its deformability is determined purely by its internal tension and characterized as a spring constant k. The vibration of the ring is decomposed into two parts: a pitching motion which includes a rigid-body rotation and a flexible bending motion in the transverse direction, and a tapping motion in the longitudinal direction. The pitching motion is dominated by the frequency of vortex shedding, while the primary frequency of the tapping motion is twice the frequency of vortex shedding. Resonance behavior is observed when //k// ~ 0.2 (//k// is normalized by the diameter of the undeformed ring, the speed of the upcoming flow, and the fluid density). Across the resonance region, abrupt jumps in terms of the motion amplitudes as well as the hydrodynamic loads are recorded. Within the resonance region, the lift force demonstrates a beating phenomenon reminiscent of findings throughreduced models and low-degree-of-freedom systems.@@

''//@@color(darkblue):4-   @@//'' ''//@@color(green):        @@//'' @@color(darkblue):"''Fluid-structure interactions of skeleton-reinforced fins: performance analysis of a paired fin in lift based propulsion.''"@@, ''Kourosh Shoele'' and Qiang Zhu, //Journal of Experimental Biology.//, 212(''16''): 2679-2690, 2009.[[PDF|http://fsisg.ucsd.edu/p2.pdf]].
@@color(gray):Abstract: We investigate the thrust generation capacity of a thin foil consisting of a membrane strengthened by embedded rays that is geometrically, structurally and kinematically similar to pectoral fins of bony fishes during lift-based labriform locomotion. Our numerical model includes a fully nonlinear Euler–Bernoulli beam model of the skeleton and a boundary-element model of the surrounding flow field. The fin undergoes a dorso–ventral flapping activated by rotations of the rays. Both the trailing edge vortices (TEV) and the leading edge vortices (LEV) are accounted for and modeled as shear layers. The thrust generation and propulsion efficiency are examined and documented. Our results show that synchronization of rays is pivotal to the performance of the system. A primary factor that determines the performance of the fin is phase lags between the rays, which create variations of the effective angle of attack at the leading edge as well as shape changes throughout the fin surface. Structural flexibility of the rays leads to passive deformations of the fin, which can increase the thrust generation and the propulsion efficiency.

Key words: pectoral fin, labriform locomotion, fully coupled simulation@@

''//@@color(darkblue):3-   @@//'' ''//@@color(green):         @@//'' @@color(darkblue):"''Propulsion performance of a skeleton-strengthened fin.''"@@, Qiang Zhu and ''Kourosh Shoele'', //Journal of Experimental Biology.//, 211(''13''), 2087-2100, 2008.[[PDF|http://fsisg.ucsd.edu/p1.pdf]].
@@color(gray):Abstract: We examine numerically the performance of a thin foil reinforced by embedded rays resembling the caudal fins of many fishes. In our study, the supporting rays are depicted as nonlinear Euler–Bernoulli beams with three-dimensional deformability. This structural model is then incorporated into a boundary-element hydrodynamic model to achieve coupled fluid–structure interaction simulation. Kinematically, we incorporate both a homocercal mode with dorso-ventral symmetry and a heterocercal mode with dorso-ventral asymmetry. Using the homocercal mode, our results demonstrate that the anisotropic deformability of the ray-reinforced fin significantly increases its capacity of force generation. This performance enhancement manifests as increased propulsion efficiency, reduced transverse force and reduced sensitivity to kinematic parameters. Further reduction in transverse force is observed by using the heterocercal mode. In the heterocercal model, the fin also generates a small lifting force, which may be important in vertical maneuvers. Via three-dimensional flow visualization, a chain of vortex rings is observed in the wake. Detailed features of the wake, e.g. the orientation of the vortex rings in the heterocercal mode, agree with predictions based upon particle image velocimetry (PIV) measurements of flow around live fish.

Key words: fish locomotion, flexible fin, skeleton-reinforced membrane, fluid–structure interaction @@

!!Selected old journal publications
''//@@color(darkblue):2-   @@//'' ''//@@color(green):         @@//'' @@color(darkblue):"''Localized identification of shear building with embedded foundation in frequency domain. ''"@@''Kourosh Shoele'', A. Vafai and A. Kaveh,  //The Structural Design of Tall and Special Buildings.//, 17(2), 245-256, 2008.
@@color(gray):Abstract: For studying the behavior of structure in an earthquake, it is advisable to model the structure as a multi-degrees of freedom system, consisting of numerous single-degree of freedom substructures and pay attention to soil–structure interaction. System identification is divided into two categories: namely time domain method and frequency domain approach. In this paper, a localized substructure identification of shear building considering the soil–structure interaction is presented using a frequency domain approach. In order to deal with noise-corrupted data, a spectral smoothing technique with Parzen's window reduction method is adapted. It is shown that better convergence and accuracy can be achieved by the present technique. As a result, it is shown that by taking into account the soil–structure interaction more realistic results can be obtained.@@

''//@@color(darkblue):1-   @@//'' ''//@@color(green):         @@//'' @@color(darkblue):"''Online detection of a breathing crack using an adaptive tracking technique. ''"@@''Kourosh Shoele'', A. Vafai and A. Kaveh,  //Acta Mechanica//, 188(3), 19-154, 2007.
@@color(gray):Abstract: Early detection of structural damage is an important goal of any structural health monitoring system. Among numerous data analysis techniques, those which are used for online damage detection have received considerable attention recently, although the problem of online detection in continuous structures, for example beams, is quite challenging. In this paper, it is shown how the type, the size and the location of breathing cracks are identified online with the use of the records which are gathered from a continuous beam. For determining the existence of a breathing crack in a beam, its vibrating behavior is simulated. The algorithm of the least square estimation with the use of adaptive tracking is employed for identification purposes. This algorithm is capable of detecting the abrupt changes in problem parameters and traces its variations. With the use of reducing domain algorithm, this identification method shows better results and can detect the breathing crack in beams more efficiently. Finally, it is shown that with the use of sufficient mode shapes the method is capable of identifying the breathing crack in beams and frames. The efficiency of the proposed algorithm is shown through some case studies.@@

Type the text for 'Research'
Following links are my area of research. In general they are fluid-structure interaction, fish swimming and offshore engineering. Also, other areas of my interest include Structural Dynamics, Computational physics, damage detection differential geometry and structural health monitoring.
Further information is presented in my [[publications|Publications]]

{{centeredTable{
| [img(100%,auto)[Ray-strengthened fins, Fluid-structure interaction in high Reynolds number |icon1b.jpg][Fluid Structure Interaction in High Reynolds Number]]<br>[[Locomotion of aquatic creatures, FSI in High Re |Ray-strengthened fins]] | [img(100%,auto)[Flexible loop, Fluid Structure Interaction in High Reynolds Number, Immersed boundary method|icon2b.jpg][Fluid Structure Interaction in Intermediate Reynolds Number]]<br> [[Flexible loop, flexible bluff bodies, FSI in intermediate Re, Immersed boundary method |Flexible loop-Immersed boundary method]] | [img(100%,auto)[Wind Turbine, Wave-Structure Interaction, Offshore Structures, Highly-flexible Mooring Systems|icon3b.jpg][Wave Structure Interaction]]<br> [[ Wave-body interactions, Highly-flexible mooring systems, Offshore structures |Wave structure interaction, Cable Dynamics and Offshore Eng.]] |
|borderless|k
}}}
[[Research interests]]
[[Publications]]
[[Presentations]]
[[CV]]
Encrypted(13B67EC3EDF87B19210540ED3725EAAA6506E1EB)
97517c90d604d7b5e9eec37e5f0884ed4a26daa9d0178b8ad2ef7c1f02ed937521
31363021de6f205c17d73e67213136302148afdf0f1ca84db7bb8ba2cea1c970
d5860279c445ea053c2139219175975c536ade11075eb3131468dfdaa6b28c1a
a3fd213334217d7676084444d0a64973798389425b6dcfa181cdd1c0fb106361
21313321d0539545c389d952ff31a9805b71d8213339219b9f386bbb21313630
215d8a57472614c87159594c3d1a2e6e7350922e1dbfca8a2dc2a83ffed8af56
08e7fc8b213131214a2d96dbf5f26d80956561bc90339821313121213334214c
c4046d44b8e5f7e1f71ff354213133213433f5067d6e79f33ac4199ef3ddd6b7
eabc21333321ca883429bce3cb647c472131322120d133ff3de63af90f951c14
a5b5bcf803213132211ec621313121314a75b56acb6735fdd726c68ff38b62d1
e0aee8e5c0b05e269d6fab2f3d06213021c775c19d02c6561052992f6be4be6a
c972e7ce99d2e46efefa6d1e057408c89173d19d5cc0de23025d97b121313121
46958eec0eb3b838fd6a7426ee8dab83f05421313121289f33ebdc2131312137
ea042133332111c08c25257b21313221f0769f577bcead9fb74b7cca339a3271
1346d72b2131363021a8943fa2f420403f3b262131363021019faffb839de657
4b52f4084e31efcad8ecbc4b5260713dcdd737fc49433f655ef6bdea4452bea1
290e751f97f721302107951c6260939007b5e57fa8a8301c5e43f2879f5d9cff
b25c945538b1e4891170bc17088c4ad5c12036e7042bca5e43e5b0a64ffbd06e
bf2a53795b47c43d93544fb8c9883ead5f251b71bc6bcdf63c2f4aaa7ae7d9f5
b26866682eb1813c9c3910da213131211de5302d2be21a34f7c81726c8ce56c0
7c548940be47fb32e15cab2131322156fc8edc4a011f01974c2af46e302ea760
0671d62d577707782f7285ee90c7e64a9241d16eb1787a1094a888fbbc8f9749
e50880f6aca4ed2f71bd85dc567dd721333921ec2131322191c8213339219d21
333921636be693fff7e62d55c549a2ea7b5e2133332105b889d42adcc98f6f11
7bc7c33d21333921e5d3027a213021a73d50723f9076536187114cde3890a8c9
ca7c5117392fba72e72131312130269a3211f21cce5e633025b97640a5bb6b21
313021042b88d84098b6362cf68d417e2319db9ffa647ab355eb213130212b8e
2130216b6836678a3c97a6c35afe6690407526acf54a7dc20873b3aeee285fac
bd3119ba1a5841213132218811e3b3632a3717ec99ebf0baeb6507abcd846c04
1142c352698f8f3b4b9f5c6ea83ba702fd065ecfdbecf1e067a68d7c672dec61
ae7c34021fab1c06a97c21333921a4d78154fd8a83b8da64fbf8a6f7fd934088
fc07dcd28920e25b2130211c3f6e743169fc50c1c3e7679d26e8365578dbbe78
9c2131363021ab3b5f8577cd0533f71481d957f2b59d6afb47ea2c77afb34b94
5fad65c95c753edf48056cc20754e7c136f2ea03e07efe1a7d5796f43537527f
59b17da8a21857da161721333921fd5a76b19eb22130214dae1224dfd9c60fbf
94a4104f13b16b9946e17fe3f636e2e67140c512d17a78fe82875f882576a533
1d4a1c061369e87e9e8a16107b50637d67d5634cb452ee29374ac6e849ce99c2
5ebccd430ee7b921313221dc4f61fd36f58ee330213021d42de3ed9b7d6ea573
f404f66dc77bc1061e79fd06426b752bb59ae0a68d755d33711bb050bdc46a33
5b845e525432d3ce2caa027cf6b424ee8783f889ba8d82f3028bdbd6522f77b2
d2f4f6f74c72a7d097f8213333213c02316cfac406ec263d28c54a8f46054062
3d157f74f5f3a9b8aa17e3bf4269495cb7213132210e3b0e02158021333321d2
8ce517951eabeacd73be08e6501524671d51a3f451a4c3779db1d1bef85c1748
1dc74aca2ee7723095cc4382f03e1d3635547c479c93da93dec1b2788672cb93
3cce4390b6e7abbd21313630217ed7ea31cc54492d3b98fc4b94c026a8e42ddd
3f201bd30ec04de3213131212485d3bcd02131363021de61104dba0275842a56
7e6f8fe128d9b26b989607ba88ea1e45f7ed193504d9e0213921153846ccb57c
966f4419bf66b3aec4ad2131332161852daf99fcba1269b89c8c0e2d21313321
29706259ab0e92c57ef431148c3d61f07490b14e6ac566f2f63a4a7d9a7aff13
3b849ded849f8ae3c42130212fdcc29ec9d97e897aa4aef325058f9ab8abf433
ce2c1399bfd821313630216a14a982621c3a62f56bde213021936c5d2c961afa
e921302117a16fb38d632131363021e141483ffcbfda986f958bcba1de7e0721
33392115be75b02131312184d68089baf31d152c1df0b721313221d9d086cba7
555e5787a7feb4d73191a95b4649f1821efdabf1f4741a3241cff1d035abfd7d
a821333321da79d7ccf85bb129c455bd2fb65463398068653f561968624806de
379e396ac94eccea9ff8cf5cecc6766a7b47eb58ce36ddabb289213921bd5e92
cfd0213021dba639b406834a6397f802cf545390c9961d7e0274e2518faa7d3e
47a221313321d0c1ee1c0236ce029059c68c28083f568e8048ef2083295c7e2a
e721333421c6c0ccc52131302120f171e4c14521333921f73c81942bf0696d24
34169521313021f69389965f2d6b7081355450d0b2a3764f2db352c273da415c
8eda990f426ef23e4784e7ea623345f03ff64f66678bca99ff90cbb038d2e83a
323f9f76022b4b8569493c64a1695b46ac99a314919f21313321213339214d0f
9afa21313221738cbd01181d074696d745941f3fee21313221c1aed386213136
3021ef21333321c2213333216516213021200f1a669a256ee86d1621313121ef
cc12db97ef16c7f894fb7a75831565a469df33865f4345d2cb9bbf1e6b5b8c71
f6cae231046b29e129c96d2c0e178e182050e1dfc2b854836eebe2c76918cf77
ab3e213339216d3072472aafe334fb52ca72b7bbff97ca069e68598447e86653
213021812131302140d39e2410e19023e42a7cb471305e80adb8e687d4c34e21
3334218915a248dce743bb1bed083aee8e4e2fe63f59b2b66f5a4905c1d2e048
d164e03436c93455c3ee57f0f2021790803bb0a94fc8bf8d5a6592255cad3857
192fd13b0fb3a63073eef5ec7d99f9806b725157d2ea181e2130217908b3bbee
5521313321c3ae193c119ea2af6e1e65bf0648f53baa639775d9ee34148756be
f7eb13a38383cfc373600f5c408d86b6ff408ab592c58597081ec8303ae84e21
333321df96902a96b07b9cc3b498991a5e52f8263e1c19e5adf0bd2d702c29a9
6fdaf11965cbc4df2038e5b8af5931ea38c07a28a5998daf7fe0607012d5c118
5d2139212133392139dba66b5eeb29d1070e13422c2f4b477a1b5db98bec3dc0
32fbcca2821685d5f2e764f2c321313021a30e92bf86037271fde5911c08d57f
b8f1dc7154e1de8eaa64f475ac48815ff591287b7a9ef7f2c3f3514fa7322051
4ef05b9113fa8db021333421d28c617e679e54776a185c2fec801690dd973ec3
e412f07856af85f6528d34dc02b84a1e659fc6a24a7103393c5046ef91d4f2ae
c321333321482baaaed2f4ff14f8a4e1ae05ce696a2139216d7f252133332189
b01bd14c904e4becde1277d6479dd6701bbaad83da64f1ebd642e1213334218d
6e433e537133b618eb3fc0d45d36ca17ddece0cbbaeb8b233dc0a93b32fbc64c
cee421313321909db79d867e7cd4eb1adbc3615c527c4279612139216472186b
516b2131332115a1b36143546790709c7e659f6eee0ffe0eb47c75d94177117e
f6aabcd8881694ae122c59e488a724b921313121385240ee38de477d21313630
21b3fac9f615cd21333421a91b16e221392173b4c9894c4eb0ee213131215ea3
ff28f863a1932543eff12f665377314e937373a2c1a86fe55625acb2ad692133
33212d70e3f5e76ef86cece1f19493356c07739f21313630213bc4307afe05ec
be902131363021cebdfc465c88975f741bb625ff01b22b0e93ec62c29882dc30
79193caa72bc02cbd167ea395147f16d7fdeb521313321ed25318fc880165d17
9cbcca3bdc2685a1742e8beb3d464df1c18379be13b94ce5d8b06371e57e3daf
2c6fcbd0ab37687245c871d7c0913e10968f5ba3cb06b52851d9d57653ab7188
82256ff0c5aecee8fbb242f0f35a8089635565035b23731b377f765021313321
be04f77550be98e3f91da64fb528f825cd963e05ce6ff925cbecb0d9e2f750cc
5242db7e9da3cd213131211d87f33b2139219d469a2efb3a7463bfde62c738ad
20f9b06b687848cf3f61ce67ddcc0820a945b0127c2133332103076510c1b9f0
722ed5649e21313021213133217a01620e6a2e102131322168f6c65d1513d169
a68f4a3d10be23449cde58d121313221efd621313021264425eb06085d844fed
16b2083d6d5de2055458a572b1adf2a77a37a3a52c1e7ca8f0c5cee226313b38
532bacfbe0087405f2845cb56ff9bfae119fec7d9bbb15f2957e72f519bdbb03
f3b5b3835bdf8c9db1f618d2d53653eceb07aae2a4ae9de02efb156a11861dbe
f7bc5f7140d770af2a98ab36fa89eebb5fefdc592506eeb99bafddbcb87a429a
a9b9ed1fb538075eaaccfa4a534abdb93395d85e4a7dbd66dff910fcb2ef563b
10cb418028d6d5fae8ba982ec5f647adbf2130215ae9ec5ca2d2bcf89bf57fc1
8b43abfe7701bd9f7abb9a7296281b57cdacc49389a15744361cfb46cef119e0
332e21333921b9d23cd8b6f776453159ec79acbeff21313021969ccdcb3369d3
2b24df01c53f923da814c50e61fbd24f83bee0723e21333421796d65b8a825d8
69bcd9637b5b50ff03cc85f92b982b99dc21313021be968a566b6a20888ec225
2061eb4f4a86037d2307e8fa90151ac097e5d9a7fa3466a42b213021fa13b2a8
b31eae932bc056754499aa3243141821392174cd8afea7ee04d1d49608e70f48
9e358f257980772c4f46d02bc521313630215aa747e336395d604310fffd720f
57ec209203d2efc4d211b72139213294254e4eb1dc7a9e6bae8aa13d714f6341
83e47718a8435b916b6b1764c767b059a8213334217db02659303d9421313021
33bbd719213021bc1ad1a8653412b0497e213334212139210491a861dc1efc4b
07b59821333421cc13935d79cad607df862131363021ea23dc2e5eb818592a7b
a906522130213ab4b0b0c56b55b0c26a04ac5872fea529c2d9bacd5d84062877
8cdfdfe08473463dc5d8d8d407a1428a47a7ed8eb88b53fea354e17445d3631a
40b503c0598b02833c2f3c745c6707d1598cc34a98791e21313221af4e66822c
bd761c04df21302136213136302118aea47edbbe260fdec22131363021213133
21b031ac6151976b5b785bd47732c27c12127b9356a253dc97f4f98216193258
07e48f9cd69d8c2b21333921dc5cbed95107ecf121313221b556406a7ebff1c8
bd159728f70f4a98879e8c213021c821313121bd8947aabf2d18d89221313021
d364b17fcbb859ba9ef049f2776b90f8c5e035544db99430ab78a9f3dc383c8f
26ea81b37e1a326b42b697ce9a7b459e6f28b189a27d456b3cfa2c175612d1be
77393b980501c65bb26b2ddd60213021af2131363021c8b3ee0141766a711f59
e4449043d3d2a89d1a1c2cb3d5c3e4b8d62fdecfff8680c26e5681361480dbe5
95f7bf7ccf87f9f5cb9fa69a9b6ee182a7f334ff455bbadb2030955443859f88
989f1fa5d8145e97caf0c0213334212131363021f59d938644066497ba154008
a5623660c707f450f04c307f7290d2f3fc51b5213131215f4f2693f064380f57
3af12d4d3b32762021313121204847d782db85769595722c8b9604cb9beea7fd
1d662f3e044bcab99358a48ce318a3da21313121a892ac0fc73cb6bf1dd62f80
f2dc6aa7101a1b8e949f68f1cecafa281ab812b7565207dde1d4f8034a3f3468
815f515333884a450fc00e8f973f55806b4314080f7f90c7606af1907638a54f
abc74d7ca8213133211ede5a1fa56b91b5dc6851133b6f6910b4c602476e5701
a134e12131332144914023614e6d7d1a43eb11903559f42a8019501e03238928
50bb5552fd77d3556a647998016cfe3d0f554add8ef42dbe20b121333321793c
9165394fa1213021f72685cabdef43d370b01dcaeb2ad32eadaba4673f7a4b59
5534126a8117e2bd76c952a9d4544434952f5d2a2854b3cde0ac56631c99ae9f
d821333921481f714b8bb7fe57e975b2e62f8d4ab8af24abb2ccb4a221313021
b1b91a7ed79bf7f6a756ede5a862742bdbc49f6e23442131322195530e05243c
c06052b7abc5a569aed77a81efdd808711807fdfa1c83eff9e16d43bc65469c2
3ca75143c5f4518e1193207cb3548df4a4d77b246d134118898fa8dec506d661
13f7787d2ad7b91bf5eaf6f515d317287d6a28cf80ba8a46eeace15749f4699c
200ee0f8dec261931cd547a49f1a21333921194a8af3473554a26f67b9d292db
7d5f503a21313021e52130211f7067e6b4e09448b41501f0af944b7b7da39350
d3a9f4db9a059204596dbbec1b4821313021d5416ad32cb88c96a9266a4a71d3
8bdeccc0213132216f6f7a8ddc816cc2bed6b02921313321b6269d435f65d2bf
f4eeeb145854f8b0745aad442131302189ec213334214451f999612d7f213339
219784977258343884603214f1259f8cf95c801655cee35ae341213136302112
438b30f2083190b06bf459d23fcc3d9ddb78e298e411542033dce16443213334
21ff2131302198e2542cc7d84eeaa701a796864c7bbe638ae5f43ebb249c5b49
f74718847342b0c13c6f1a65ac42213339219f5a4de99164ca16213333218ad1
f28439ae7b9921313121379f5f25dd318cc1a6725ed63ee7b6745d3bcd7e4241
883e6913aadaaf614389db3661c36c3447e3e6a672edd1ff2304f06818904ad1
ad58c93f213131218f2c9f3238827318e7c7e9213136302162be8ee0ce213136
302140561d57d2ec15304dbe5c06c8554cfd775153976ea71ab7f4192380d910
2c817bf7431847213136302156b44bd984b1bfcc8c57d5f23452a455b78dd91b
4e2131312144981a15859b83bfbf44ca9cc0629eef1eeac789f841a702fe91c1
dbd366a1b3975264358246e418a6f44d74cfaed92f18e985661be465f172e3df
99d990ecf7d6d778d298a4015075a81ebdd7136a3fbd89b6d5176501f4159a84
8f1f9fbd383a496df6aa64eb28b8e93c2133342162c5d424d01a499518b43a38
1221313021907dfb7c9faf338bed4073ee508911213921b718f4858cd55983f3
6c3cfab8593da9bd06f3ad257e63a82131302120898fc2d6b110e45c45da2133
39212139214257e858f80732058c0e7d1624b9b89a74e16772c875af6c2feb21
313121c31a763f81f3482f6cb9e0b93063c5cd41b9a31921313221afd5f6265b
935bd369c1239e509771f38a54ae2040f4b44bbf213333218717d9cc47b612cf
7fe2552133342145d62fea19add9dc7403a3b1a18a42d136622139217026414b
ad36a81820854dd78b3c8ed9366dbdba358afd59a61da7498001fd5953b86535
21313121018d2d8feb32f1a4166c9b296fd596e11ea9cb23c821392121313221
9590ad39b28e2cc4da59f5fabd47ba9cbb8c77dea1dbabb1603576ce3ad7336c
4fee14b53c5c41b73a6c213132213b3bbf21333921e30492904c2d45673685c3
06b1d6fdc9f921313021797a83f421313630213f3af81fff39aadfc602fee3d5
fade3388f54fbeb191d560316358ab636a21313221f7e35cc9d0fcfe77fb693f
bc21392179db17461829ea7fec19edb78da161b484c09dccd39721333321c6b4
c7ceaa83525b3d1a7b2b42c551bba4c01913213021ffc117f7925dac21302147
5a81213334216332c39f21313321c74e46428bb6ca2f957339de54b79cb08107
711b7362da196ed62580bde982b13ec52bcafbf0ea79844a66facb5d21313630
2166429f9c5c42f8cd455085a666d9d2f407c5746135483a507ccfba213021cd
79a61a6d873c2d213133219ad82ee3cdd043f0b2e7de91dbf7d11bf77a32a4a5
4c1d415646642cd360dff8327ac63cfad303aa6f6e86c530f9ae47bccda3ea75
9cf61ac3c1fbce5daef593a743b03e8a1bba46e5362876b977c2beaa34818340
ec18592133332121313221bcd7fed5ed75b3408449d1c4703aa7a7aae44a2b92
fe21313021c621313021145b89d25f87e9b9d518375191f4d054b0925815a484
01b9238f4146c0a2e017b3492c19ad175c8906191878ebcf319846713c2e2133
34216210c111eabd7c1253825caccdbdd492032ea63bd9e81a264f58d0412cf0
f1792fc5d824b4c6d43af9f764e6386610213133219ade9971116b86964e10aa
16ba99dcc39212cc6bf1d105501ae2a93bf6cc3bd7cfb34139f675481c89e1ba
d774f3aea1a9c09e315ab35ece8e0e125f6e6e464c5a5cb5f9533c4d6d4d2139
2176e771d37428975e2c99333dbd4b1867c5e16a5052a28c1912a3b3796a8058
e50e750fd4ca213921178bec75b71c505e2edaaabd8a40f159919561f1b9aecc
3021333321fd8a7b2caa6b73c529914b145fe57da1709fef9f241320249e5ef7
d6b23f77346386ede5178dcf057e741fda369d14ec5eac855f21313121286e71
21333921368ed11f2b4124dce0fec7dec13ef3e41389c4d03499a3c9b93dc1c1
497cd5a6d9dc1c4ef8576b5e357081b1627f817604bde3879ab379857932bd37
6cf8ba12791cf3568ee621313121ce6d63b64ba24cd5bd99201ec33f2cc2e7a5
b64d8ffd5b7602774c6aa8f91365fd7d83dbf7341644c8c725d06736b2d24db2
f8079f5c162cc8d067eb5632ef7ed408d2f3db6e4fdf9a901ec99932dfb4ffc1
42ecaf1c4753ff14f22131363021bee8606a72fa52906829213333214f213021
eb522d9ef0da5d1633cf565da7df2335fb065986395835fde26305c7a556cc4b
4eee4b058acdab21333421c474ded9df90bb11e221313630216591f8a7a4789b
0fbefa19071284ebf77e542131363021aa9cc602533ee23aadbb6a47ed15ef9d
6dd65b37cc06072c43f9515916b6125864f01721333421b43e18af7f36280826
29b1afb47d47cfcf8a5f7f7c213921de1c8e5e34b5a1658fc9b902b57862f4fc
a9cb55439dff213132217a511cf8ca54b6824e86aa52ba0f213921c9a844ead4
329246e68c9fd2da67325ad450a73a12e43ce3869b5dc7c53eb293f0b77584dd
7a5ba9196046c9f1deffbe21392140ab247a1cba213130214cd7b53203dcc3e1
6b5a32142c3628e880667694f783d444af03056502e0236cd461213133215f94
5346e2b6ddaa6635c11621313221a6402133342148af49d85bf4948b3d2e013d
7612f8c6ed4aafcb65a603188f3e0865409ee48f67db4f3f438732011c423f24
de3b43771721313021f891a3a4524c627cbaf85a3304213130217171ba69d220
fbe05868213339210354846230326a367c1f1c3a213334214f8d4b98e53cd591
4ed4f5bdfa73c92fa95047da91986a403b7ff2cadde7dfafc1d7e8d2d31085b3
7f7adeabade3daac21313021c2ae25df81b133da7a119503d256b3b13fda42c3
d307f7213130212f8835f48908faeb487dbff12131322154989142d673acdb2f
6fe34d3e45943aaf748fd946213132212b0669639ac8ba6429025843448f7506
23705ff8972d077c7101451252aa94854af33075d3ab14dee67a6adc6f3f0691
52b8deeacc49f287c6e661011c8e947c2139214d4a6a236cc8db55083818d921
3334212fe5137fe4a750d063bbee05dd134bce569598aa8ee9f186ca782836e8
dd54e4c0c1796021313121dd5ccda301d4b89f383c80676f2d8e713dec213130
21633834949deafbb030f3f19ee47d534b3cafc754d925cf46926d7b132eb25f
067f83454813301171b5d166e2efcee687a4213130216e26b2b5affe939f89ee
79538d8f7c052133392193d111ea4542ba8a0f6c16faa2715d620193f6e7d5bf
c024203916b19271e31ac046be68f2db76a4e59478bbd4746eee45ed3dafd4d4
4f6a7cded0cb6baa7f737a194ebf358cb817f6b53ca3ceb71e30b29717bfdf72
234aaffd786c1d68545776ea039d406a4b1aee8e712f97c479b6288e49504d6d
ee5021313121b832b7565840c8e1ac034047299d865061ae6dce398f167a07b7
f2c95472b5fa838cc8ea110e47c9dc372f1cba6fb1a34df711fefa12a8b3744e
82817355d06d7dcbda1f342001c2c1a6e01c3a6f74ecae488ba3e1fee37645b6
2131332121333421c7a1e792623f5ffb47bdef64d841bd213131212133342158
6be3926ff5d61511444a03c198250774602d1b39264aa29caf84b2124131e3d0
31b1bd9537213132212414908ccd7e8c3f6508bee20f3e5b13b9d555354462bc
543cff8997f2b4312af14d21333421ff3c3d514805e42be26ef2ca92aafcbc81
3e88ad21302123237a8537e2dae4efd3213136302107a2fb7adf96ea74675f59
992a213921a938367baf6e9af787a87273ae08d8b8a22819f39fe9541632029b
2bb698555f11ac427b981343fd57547c60c0c2bed78fb5a6cb4ce8d4c71b6b50
e4e54063f711e8ac549dea89148649a2176e67295cca8a29669e5447c4e6a7b5
44d4b9deeac6997ef5a225020fbc7b5b254ec67e566ee911ec48dc870425a221
333421969176ad29f0e8ce887a1eec53f1786fc0cb2bcc2f0e3b524df45ee4c1
78e89e9cac5fc64975e52ce3f4f49d8840acdb6c77a8b01804f0b5718b14b8ff
545183dc2fb9e13b78f11b60ed19dd3f38df8479c97733f33abcb294d3edcbdd
8387be953fbb70de8bf0151e9376bf5f4aa3cb7a213132215dd392fa45372130
213024c4197a70744e4989162c5fbe8034ffd3fdf8d0defb3293bf3d213921c8
f2b15e756af0f7d86316edb117815495830e8aaa45ee3aabac5e944a31d39fad
2cfc8a2131332164b5f5a10858b48be5076d7ed83e1ef532d3adadeccca85cb0
b5dd21313121f3917b389458941832c41ff8f02444d9213133215b594283f617
147df154941dfc3cc3b13290e5f1df475ad47c011014406bf09598851989160e
39d2ee7a14c636d17526c11e5ac6d53aa8ccfef7964ac2ea5845af5545061287
2131312159a3d8b33e65f1985b6cc4915a2131363021ae5665e7b133084346a6
4150a697bcf38e81a64996aa8ae72e264f8d79b3d1b720888e23213131214d3c
087a21333321f3d33665dd8cf46e69d95a629ba15f41478f87791e9921313321
13305a9bb81147308d03c2f45888988b13336b7c9957eb213339211b513cc587
854403c224b526a52e6925861d10b16cacfe78ffc0adf1a11e6a45ffd15ec453
398ff621333321fc5d634724a27c64850749da979be677e57fc0fbb4bc9c670e
e0616a2be17ac3f59acb6510b336213921146f2d7b1e5fa6c9259f1a2824932f
e44e8819a3eaf933f02139212db5bb322439ae076c6ae9b7b58db77bffc44713
ed282df2855a36f8213921109b5b6619771bfd47b23fce7ce04af07742f461c6
fa208c7d3307ad352131332114f4b7b0778afc2d8295a42139213d2131363021
9e73742ba9c330acc3ca5e7255734c03c14f62b3a6e0b673d41afd8fa7b15562
475cfe17327aefa98fa72f46a2dff808f23fe39e77991235857ea2a1ae76f896
4eb36ca6c9ffc388d1118efd9a03ef2c1af0213133215437483b798bafef36c2
a9b2f23d73c21f4d17b45334691f7e160844b11f7b6f463c4d90191bbd1013d9
654823d44b21333321e119213334217da421313321b9386924213136302113cc
8e2131363021cd72d6aa012131363021ce4d71e392db8ed198158d9460bba297
42c62133332185076845bb8f9008dbb6dae6b37721313321117d6a9d52fb6f21
313021c9ceb85d25bd903656034b46742ae504b5d075eaee5f12038b8ed793c7
641ec1fd508524b966e9b4ece7dfef9d17f4e28840823d6df8c1a59d20adcb5c
21392121313121d5a7f74df3c135b27477a75bb4638c611eee5c47b1903dbad3
0f1cb916323725a3b4cb140595ee02a39b73d05bd4213130212ad02b6dee9d35
7a3f38713255cbbddbb8dddf1e8f109fc58c448bc461027714af57213339219a
8f447417d33d35f3ce715377d23ee41ac3065792d382a582a6fff777b00edb68
bec9aac7834475ae346882e2598696d7c3aaeb3b38c171da2139217effd63e0f
6b58e2c5d1a74f4e213921069568dd13cfd53b65b6a46dbac2c5d723e871348b
a5b97b7910fe23331d424321313321b6efa84a175bf2dbccebd021333321bddd
66c0ff1568eeec0ee605732f8d21333321d099d3a83314043a72d98354c66a7c
90d9ecf7de8e95715a76b0d8429045f74f484e9e3307bf7b8441a85275213021
3dfd9559c25902812cf9e265468cffd947cfbbc250316469d4e8ab10debce1b2
5b5082899223b7f39046fc594c70e7c46363ac9938e7e92e2018dc56f11d66ef
95c25fc673de39a7b6830645bb21313121820e06ef68e277ab3d1eebcf83f2ec
97ab3c2133342110303d3ee4b2b61357c86a625d65b67ceb196f21333321f212
e019f331bbf45e884604f520d2678c646896cfa1499ac160ea3c76232a461cfb
1a9caf06c2c3e54bc9aee5ba776ee5fc932021313021322131363021e754f8a4
21313221251c81f9f260a3691a98d870d087580e501d574724c836ca512cb6f2
98e58eb74889d551f7c8b0679dd67a137875d65a41563e75fde680e13735fc23
39568116dbbf1ac1ccef213133216f2385bab9377956b9213021ab2021333421
65138a798fe77d4fe9085001d8cf5ff767281148f3e7adb58e95f57a10973302
f7eaeb5c40cb30f62133392146d5a4b82bfc32531fa12879296182f58519b037
41aa2eba4d3806dc8b66f6341b2a3ace85a4fdd9067e472d4c7a40b6c41dde7d
07e2c36ad0e2c46ab8fb7576213921c2eec8cf57eccf2131363021208eed6447
fbc6d6ffda4a6a8fbd8cb87cb9548c6619c4cd403d656fd13906f4c3046cff8b
3670b888c93c0ffea7915f6950c52fa276cc72c402fa1dd04531213334214947
ebe24ad3129476e6a7631d60dd28fc7634c78003f39bca24a7455160ca31d7f2
afc8e6166607b2bcb2246552829070ac6c42bc765b5ab7ea89ea11a2c8f16bf8
3666cc6fb3e24cf6fe03abb94c932f35f9ce6da69598ee4fc9de35ba0fdb9f89
8c116f47ef5731dce82b8ee962d87ca2f8d6e85cedf2a72131363021e26956c0
b29ef8c5f36dccb76ea8bcd2ad4d664263b65842c251755dc2447df5dd93ee19
21333321191c15c6025a213131217751b29aa593718af76290c48b859ba31367
6fca3b0621313321292139216b5e10e91e44dbc75dae8eded21f1d8e86512131
3121c6246e6dc8b8a423df7108b766ab993a0168fb8e8121313221ca06e7edd8
f1e510213921eea9213021e04078236434fabc1aa73c9c1d9c6892ef29213133
21fbbc7d8e3f213921591ccab7043a213136302154c340252d694aa72139213c
a48f3a2130212667a62d77d88f2139211cd49d4a5485b987466a1981d9459e89
f072a2330f49521d79b52d34e89552d32d9913067facdd848f42a1860efb2ef4
a8012f52ee734abf04e1b7118b833ba218696cbc2635488b582c0259d88ea437
1341141e59f5053860c7da5d77ba1ccb5bccee8c3116a921313021d8cc51c9fa
16bfc6a1d9b2af3c603d90688b4db76ff48789ff372889d3d4c4213334210188
e791f45865e9a53e834bcacdaca3ac8826ebd33ceeb3dc1a542b7a35107bbcd0
5a3134d66d591ac950d6373fb112b0842131363021c83b1e97a7eeb993213921
be6321333921d1ea54077731dd9ac99c347984302984b025d14d68bf98e487d9
64038677bd9b77213921b20639a2ba29d73d488cabfa02cc6b07c67db16ce147
d3d79cda078ae81f06a9182f6f194962cc596ec675d42bf7bce0a2fff87b5a9b
df2c70d46ec34bde202e658e4754161421333321c5f916f7175ab0ff6c6810e5
2c41344a02327406bfea6734ce21313321b542089d305874a8ae7f8f73213133
21cde92131302121333321f74583c54449153ab165748c328a60d907782f80ed
f8ca8c1179064691346e21313021ee998b26cc1cddcdbb8932839dc4a2fdf283
c6e4c1b538feebdc49c6c18bb84d1b6b01c9c3ff3d8aba8d579b0543882596ce
66b9f02133342174bf0ea8fe42ab2e384b8bb3bbb55eb9253f534c23b6f8e681
ee18989c334579f8565596e2c035de90d010524d29112133332188fb9ab17918
06fa243f213339212133392105982b37a193cee9c0d0c96c175ab13715e3f84d
4f55aea52133392142aab3e2be7f618935e5b22d213021af6881e76e4ffd63e2
fb01268f79163f522f21333421eabf207e3aeb184b715ed597735852f507b44a
c0e2aa92efa3e3364097f5d3a42340c80e92dd3910d491546bab049eacb6eb58
213333212139216abe2835139d5d213333216f03431df96f4033b42131363021
b51fd69685560f2131363021c52131363021dacdad964fd1a53f5e034ad604ac
e503b0ef9a6672bdeef90e21333321f31c4540558731ef6edf9ffa8312a6f4e7
8bf229beec99b19c161bc99669213334215121313221b69dff50fd62d3c9a770
b47958eb799b465f288e03b5417b8df5f6dfb25778873412fb1fb3234567ef18
e9fb38dd836c2441150384e139a2df3be940dc2133342125dc300f28f3889e73
cd443a9d6a59d3244b40804edfa54e1c424bbea492403ed2f501320e032e6e34
4813044e97de4719330fcfd91410dd47858a5761b08befec42e4b2484087edff
6253f171ea3a21313221ff061b511af6dcce34e753a3eb11a47f213339218f78
152a1bdd605e911f73c7fe23b0dadf3f5fb8ee213131217cfc80e1e6d9d12133
392118188ce8fbc8b620e4209fc223213136302138347821333421659c930770
a9f977213021898780ecd3e906e128d62f8201c9c9f95da45b6f528e689675c9
29dd46e0b4537a7cd11442d4b0bb8fa29911ff03c56f1a68ce28cb5360124633
820f3842fe130f7f9f9f5dd4a4e5515c55382cda04d5d283f39d0136f247812d
356bba166f213021854c052131363021c8138598037dfee3869337f7d0f09ae8
ddac089e01183accb04f067ed429a41dda7f776d1b6321313021b85086fa171e
2de030d3b0cde564e94e213131218a21313021d6c2d5f8bed87c50377d352133
3921c488d1cb63f8341c12ea2139214e69c5398482fbd42ed472cbd056736559
4992ea291914c7be42d0f0023c21313121435eaf1b3bee2131302148a2a1a904
528c213130214a94e7e430d27021313121e921333321181e6356bd9bbefac9bf
6d2b7043f8a246fdfe91b43ed0f82133392177cdb9ce3f8d744c28da868996d2
e952edfaedb6b5378ff74c21313121f062fa9c8f51346cdbc962fbd34743eb45
951791c8674264cfd182e05c8d4ab473c2934f98089ab5c7bc213021fe91e301
d03c873c9a5e719e846b21333921e1e64dc05ab15d7931c59b5114a34deb94aa
a1ffa25f57e257201fe2d650dabf18213334216d7ea5254fa38d84dc4e30ef64
7b91fd19d7df21313221468b992c6486fe1c63febe53335688975ec176c83d77
32fd41699e296c8bf11736a8481942bfc0f7cf5020213333219a712f31c3f559
2af412ce526d3098748f329855887d449215c84e3c94d1c92c06eea5ad954d24
c7e9fd213021de892bc38970213334213a4a92eb8473484d753a34deefb139ba
843148ad6febd8b1beca75901ff79795a161d24bb10fc2b1633dd8198d60ce14
87
Encrypted(4A19DA0ADD02D3315D1537B7F8B352ACCFDBEC51)
52a7032131312121313221862c213334219069b08757ceaa43bc799a1a46a970f1
9534259ed0f290b95cafaddc13bcf04fb28b1eb7ff213334211e21313321f2ab
213131213d2b5047f63cf5329cb4db2d7bf7b473baa1ad59e601684f12088ce9
9979daa12a032133342150d3d28b947be19aa58481e632291242b38821333921
b35142593021313021c459a2f5213339216bb8e81c779f5c4885b76528d09f8f
be1de84e7c7dc08921302185ccf721313321de57c0434d4708609079c317759c
21333421bc6a1dbaff7a790241102131302135da286d0e56106007721a2ca785
c64065ca5e2921333921369de8baded104e7b81aa2dbb7eca3412133332187fa
1f45774779475df464c0d7713acdee621447ebc36e4981aac884f2f88158ca72
602bb49b5147147c5444394bf6c4073d9da7fad214f824908320440401af4075
5ca92f6d3585be2ee9692133342199a131da48a6175c01ec252131312149f13a
ca37b2e753d321302199147518fd21333921d5b172069b9fb193079c8acdaa9b
1d33fae54041d6881346316e496270e0b77c67c77ea66e9f47715040cfc56d07
dc144e11a9b568e47b99144a9532dde5cc1cd4d338f981213334211fefbc04c0
08b966c7264f3cf32db6162e2d59248d8210213131217b80e8ea3c3497905444
d389c88ba1ecb488bb8a25961ec9a9240e5e2333faa36721302192599a4a8891
783188c19576a6c974862a389886e2d8c83ec914e9e5c5a19eb54bed794b8d2e
caa8e3bc4d8bd7ea8ff9d4d5ac29944093c910b88654e59b8a178e108c66446e
4255a6f696ddf046d0b30f4201df18ee064f6cabd578dbfefedb645abed7db2a
293351eeb6614705332131332155d9450fbecc8094fe051b90689abbcd501f3a
8653ea86f09ef67aab7b54a2122bb489cc49ab25bfe3f1e24886d53fd24eb69b
8fec4b4a984d67ff79bff0c279ea52d860b7bb06ea0517564ef174b810abf97b
0ed24429b3c2b7b3213131218ac8dc45c1ff21333421cbaed5775cf70214cb21
313321d6bd8f4df9ca463aeb6477213131211d7a5b8a90fa68ffd0b80854341a
2aa521313321b02359ae6172ac176f885ce8e1a9951fb6e9063fc6d1f570ade0
2131332107fe2097cc1eac29f1aada4f52c321313321322c5e6060255e82689e
7cb76792e377d708a8f98a956acdf2833ec77bca93d91f2557b18ac92445b0a2
face5e5528049b31669f5c4c085e77e2eb256b3f7763ea21313221575a6818b0
213130212131363021bb7edf46d93b15f99ea521333921935dea0e2cff75a488
9e7b10effa47f732376f7e4b7a8c8e7a21333921333c312b7b47dd8fc1e9c8b5
213130217fcdf9f2fa33a4932131363021e1e8bb82baf08ac0a7b4b75f946dee
70d4588c70d19261d9326dea
Encrypted(89013ED6600603DC4226AB482A4EE3538ABD0184)
a1dd578f4721333921785af9a8109d4350c3c4d5fabfd27486fe3f589a9cc4
Encrypted(FB846ACB0179C3F30FF02D8DBF0F784B7443D8E5)
a9df60c6f465bc4d3dbf10013d9ec6f53ed4b8f5707e42f6242133332121333921
bd
Encrypted(10EBB787FB71C52E30C892357A68FFE45C98A3CA)
6880921a71bf8a40fb8a4a59ab213021e2d2961221333321dbbb6e9da960b629c5
Type the text for 'Run6'
Encrypted(188F6A032CA5A2D4A63B218C6D2C5FE27CB5EAAD)
299290e103e80e21313321dbbadf1e3a73ddae6a9089bb05b15abf0e1efd50
!! Time history outputs
{{Table{
[img(100%,auto)[Run2/Picture1.png]]<br>1
[img(100%,auto)[Run2/Picture2.png]]<br>2
[img(100%,auto)[Run2/Picture3.png]]<br>3
[img(100%,auto)[Run2/Picture4.png]]<br>4
[img(100%,auto)[Run2/Picture5.png]]<br>5
[img(100%,auto)[Run2/Picture6.png]]<br>6
[img(100%,auto)[Run2/Picture7.png]]<br>7
[img(100%,auto)[Run2/Picture8.png]]<br>8
[img(100%,auto)[Run2/Picture9.png]]<br>9
[img(100%,auto)[Run2/Picture10.jpg]]<br>10
}}}
[img[numericalmethod|logomatlab.jpg]]
!!SE 102. Numerical, Computational, and Graphical Tools for Structural Engineering I (4)
@@color(darkred):Description:@@
Numerical methods for initial value problems. Errors, Taylor series. Convergence. Solutions of linear equations. Gaussian elimination, multiplicative decomposition. Matlab is used for programming exercises and projects.
!!OUTLINE 
#Introduction
#Numerical integration
#*Rectangular & trapezoidal rules 
#*Simpson’s Rule
#*Romberg integration
#*~Gauss-Legender integration
#Nonlinear equations
#*Linear iteration
#*~Newton-Raphson algorithm
#*Bisection method
#Nonlinear ordinary differential equations
#*Taylor and Euler algorithm
#*~Runge-Kutta algorithms
#*Stability analysis
#Linear systems of equations
#*Cramer’s rule
#*Elimination schemes
#*LU factorization
#*QR factorization
#*Jacobi’s method
#Partial differential equations
#*Elliptic PDE
#*Parabolic PDE
#*~Crank-Nicholson method
#*Hyperbolic PDE
#Interpolation and approximation of functions
#*Interpolating polynomials
#*Polynomials based on differences
#*Newton’s divided difference polynomials
#*Chebyshev polynomials
#*Legendre Polynomials
#*Least squares methods
[[Sample Matlab codes|Matlab Codes]]
!!Matlab 
[[What is MATLAB?]] (ref [[here|http://people.uncw.edu/hermanr/wiki/matlabwiki.html]])
[[Basic MATLAB]] (ref [[here|http://people.uncw.edu/hermanr/wiki/matlabwiki.html]])

@@color(darkred):Tutorials@@
Following is a list of different tutorials to Matlab.
{{alignBullets{
*@@color(blue):[[Union College|http://www.cyclismo.org/tutorial/matlab/]]@@
*@@color(blue):[[Southern Illinois University|http://www.math.siu.edu/matlab/tutorials.html]]@@
*@@color(blue):[[Michigan Tech|http://www.math.mtu.edu/~msgocken/intro/intro.html]]@@
*@@color(blue):[[Introduction to Computer Programming for Scientists and Engineers|http://jagger.berkeley.edu/~pack/e77/]]@@
}}}
More detailed tutorials are
{{alignBullets{
*@@color(blue):[[Advanced Programming with Matlab|http://jagger.berkeley.edu/~pack/e177/]]@@
*@@color(blue):[[MATLAB Programming|http://people.rit.edu/~pnveme/Matlab6/index.html]]@@
}}}
Also for more collections of favorite MATLAB sites, click [[here|http://www.ece.umaine.edu/mm/matweb.html#as-h3-1932233]]

There are many good pdf Matlab references available on the web. Here is a short list:
*@@color(blue):[[Matlab Primer (PDF) |http://personal.maths.surrey.ac.uk/st/D.J.Lloyd/teaching/MAT1017/matlab-primer.pdf]]@@ by Kermit Sigmon
*@@color(blue):[[Matlab Tutorial (PDF)|http://www.math.ohio-state.edu/~overman/matlab.pdf]]@@ by Ed Overman
*@@color(blue):[[An Introduction to Matlab (PDF)|http://www.maths.dundee.ac.uk/~ftp/na-reports/MatlabNotes.pdf]]@@ by David Griffiths
*@@color(blue):[[A Beginner's Guide to Matlab (PDF)|http://www.evergreen.loyola.edu/~cxenophontos/pubs/other/Beginners_guide_to_MATLAB.pdf]]@@ by Christos Xenophontos
|Name|SaveFromWebPluginInfo|
|Source|http://www.TiddlyTools.com/#SaveFromWebPlugin|
|Documentation|http://www.TiddlyTools.com/#SaveFromWebPluginInfo|
|Version|1.3.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for SaveFromWebPlugin|
Normally, when you are viewing a TiddlyWiki document over the web (i.e., not via {{{file://}}}) and you select the "save changes" (or "save to disk") command, an error message is displayed: //__"You need to save this TiddlyWiki to a file before you can save changes."__//  This plugin extends the use of {{{<<saveChanges>>}}} so that when you are viewing and/or editing a remote TiddlyWiki document, instead of receiving this somewhat confusing and unhelpful message, you can still click the "save changes" (or "save to disk") command to ''store a copy of the remote document directly onto your local filesystem'', //including any unsaved tiddler changes/additions you have made while working on-line.//
!!!!!Usage


<<<
When you select <<saveChanges>> while viewing a remote document (i.e., a URL starting with http: rather than file:), the plugin first ''retrieves the TiddlyWiki core source code from the original document'' file stored on the remote server.  Then, it ''combines that core source with the tiddlers'' contained in the currently loaded document, ''including any changes you have made.''

While the next step //should// be to simply write the merged core+tiddler data directly to your hard drive, certain JavaScript features, such as reading/writing directly to the local filesystem, require expanded "cross-domain" privileges that are normally restricted for use only with ''signed'' scripts.  Although some browsers will let you grant filesystem permissions to a remotely-loaded script, this usually involves either a series of popup confirmation messages or manually re-configuring (and/or disabling) your browser's built-in security protections, which often include settings and options that most users find difficult to understand and inconvenient to access.

To avoid these security complications, the "save from web" processing requires just a few additional steps to prepare the modified document and deliver it to your browser: rather than writing the document data directly to the local filesystem, the plugin ''sends the merged core+tiddler data to a small companion script installed on the remote server'' (see savefromweb.php, below).  This simple "reflector" script then immediately ''downloads the new document data back to the browser'', which prompts you to either open the downloaded document for viewing or save it to your local hard drive.  Once the document has been stored on your filesystem, you can open that copy in your browser and work offline with full access to all TiddlyWiki features.

Important note for users of Internet Explorer's Popup Blocker feature...
>{{block{
//The default security settings of IE's "Popup Blocker" feature will warn you whenever an attempt is made to download a file in response to a scripted action such as the internal javascript processing performed by SaveFromWebPlugin.  However, if you then click IE's yellow warning message and select the 'download this file...' menu command, this will also cause IE to attempt a 'page transition' away from the currently loaded TiddlyWiki document... but, because there are unsaved changes in the document, you will first receive a confirmation message, allowing you to cancel the page transition.  Regrettably, this also prevents the download from succeeding.  Unfortunately, if you permit the page transition to occur, then your TiddlyWiki document is immediately reloaded and all the unsaved tiddler changes are discarded... and the download still fails to complete!//

''__To permit SaveFromWebPlugin to function properly with Internet Explorer, you will need to adjust the "download" security setting...__''
#From the ''Tools > Internet Options > Security'' tab,
#Select the "Internet" security zone (or what ever zone you are using to view the remote document)
#Press the "Custom level..." button
#In the "Settings" listbox, scroll to the "Downloads" section
#''ENABLE "automatic prompting for downloads"''(the first setting in the section)
#Press OK to accept the new settings.
}}}


<<<
!!!!!Configuration
> see [[SaveFromWebConfig]]
!!!!! Server script installation
<<<
On your web server, in the same directory as your published document, create a file called ''{{{savefromweb.php}}}'', containing the following PHP server-side script.  //(note: you can actually give this script any name you like, and place it at //any// URL, even one that is on a different domain from the document you are saving.  However, to do so you must specify the server-side script location using the plugin's configuration settings//
//{{{
<?php
// savefromweb.php
// Author: Eric L. Shulman / ELS Design Studios
// Source: http://www.TiddlyTools.com/savefromweb.php
// License: http://www.TiddlyTools.com/#LegalStatements
// Usage: install the php script on the server in the same directory as your TiddlyWiki document(s)

// This script acts as a 'reflector', so that any contents sent to it (via form POST) will
// be sent back to the browser as a binary file.  The browser then prompts you to
// save the content to a local file.  Because this process uses the browser's built-in
// download-and-save/open handler, it does not require security permissions to access
// the local filesystem.

$args=$_POST;
header('Pragma: private');
header('Cache-control: private, must-revalidate');
header('Content-type: application/binary; charset="UTF-8"');
header('Content-disposition: attachment; filename="'.$args['filename'].'"');
$c=$args['contents'];
$c=str_replace("\\'","'",$c); // decode single-quotes
$c=str_replace("\\\"","\"",$c); // decode double-quotes
$c=str_replace("\\\\","\\",$c); // decode backslashes
$c=str_replace("\r\n","\n",$c); // change CRLF to LF
print $c;
?>

//}}}
<<<
!!!!!Direct filesystem access (browser security permissions)
<<<
Although sending the merged document data from browser to server and back again allows it to be saved to your filesystem without requiring you to extensively re-configure your browser's built-in security protections, it also increases the overall processing time because the document's data is actually being transmitted //three// times: it is first retrieved from the remote server to get the TiddlyWiki core source; then, after merging with the updated tiddler data, it is sent back to the server, which immediately 'reflects' it back to the browser for final handling by the built-in "file download" interface.

However, ''if you are accessing a "trusted site"'' (perhaps on a server within a secure private network), depending upon the specific options provided by your browser, ''you may be able to eliminate the round-trip processing by authorizing the appropriate filesystem security permissions in your browser''.  When filesystem access has been permitted, instead of making the round trip with the merged core+tiddler data, the plugin will directly prompt you for a destination path/file, using your computer's "native" path/file selection interface, and then write new the TiddlyWiki document data directly to the indicated location on your local file system.

FireFox users: please see [[FAQ_BrowserSecurity]] for information on configuring your browser to permit remote filesystem access from trusted sites
<<<
!!!!!Revisions
<<<

2008.09.29 [1.3.1] in saveFromWeb(), do NOT convert UTF8 to Unicode when merging retrieved source for submission to server-side reflector script.  Fixes mangling of international characters and symbols.
2008.01.08 [*.*.*] plugin size reduction: documentation moved to SaveFromWebPluginInfo
2007.08.08 [1.3.0] added caching of the downloaded TW core source code so it only has to be retrieved once.
2007.08.08 [1.2.5] added an option to 'pre-fetch' the TW core when plugin is initialized, so that the download-and-cache will be performed, in background, each time the document is loaded/re-loaded.  Also, added option to allow attempt to use direct filesystem access (bypassing the round-trip through the server-side reflector script) so you can save a remote file to your local filesystem, even if the connection to the network is dropped after the document was loaded into the browser.  If local filesystem permissions are not granted, the plugin will still attempt to use the server-side reflector script as a fallback.
2007.08.07 [1.2.0] removed 'download only' optimization: when a document is unchanged, instead of performing a simple download from server, the plugin now performs a full 'round-trip' process (i.e., download the TW source from a server, merge with current tiddlers, and then upload merged document and reflect back as a binary file).  Although the round-trip takes longer, it does permit the reflector script to be located ANYWHERE on the net, at ANY valid URL, rather than having to be placed on the same server and in the same directory as the remote document.  This should permit online services such as TiddlySpot to support SaveFromWebPlugin using a single hosted copy of the reflector script that can be shared by all users.
2007.07.27 [1.1.1] new documentation and code cleanup
2007.07.26 [1.1.0] re-wrote to support savefromweb.php remote "reflector" script.  Allows use of browser's native download dialog to receive file as a fallback alternative to using local filesystem I/O (which would require additional security permissions)
2007.06.27 [1.0.1] in saveFromWeb(), pass content from server through convertUnicodeToUTF8() before writing to file.
2007.06.26 [1.0.0] initial release

<<<
One can type full lines of code in the command window. However, when asession is closed, everything is lost. A better method is to type all of the commands into a file and run that file. This set of commands is called a script. Scripts do not need inputs nor produce outputs like functions do. Of course, one can provide an {{{input}}} command and print computed infomration to the screen, to a data file, or to a figure. 

Typically scripts and functions are saved to what are called //m-files//. They are simple text files with a list of commands. You can work on the code at home and they run it in MATLAB when you are on a machine which has MATLAB. 

MATLAB searches for files in its path. You should place your files under the MATLAB subdirectory ''work''. You can view all of the files in the path by typing

{{{>>what}}}

You will also see the current directory. There are ways to change directories, or even to add a directory, like an external drive, by using MATLAB's {{{path}}} statement. For now we can leave that for more advanced work. For now you should just plan to write scripts and functions that you intend to save to the ''work'' folder.

In order to write scripts, you can use a simple text editor, or MATLAB's Editor - Just type 

{{{>>editor}}}

You can start a new file, or call up an old one. If you know the filename, then you could also type 

{{{>>editor filename}}}

As an example, you could take the sine plot example under 2D plots:

{{{
x=linspace(0,10,20);
y=sin(x);
X=linspace(0,10,200);
Y=sin(X);
plot(x,y,'ro',X,Y,'b')
title('Plot of sin(x)')
xlabel('x')
xlabel('sin(x)')
}}}

Copy and paste these lines into a blank document in the editor. Save it in the ''work'' subfolder as plotsin.m. Now you can type in the MATLAB window 

{{{>>plotsin}}}

This will bring up the m-file and run it, providing MATLAB can find it and there are no errors in the script. 

You can modify the script be changing the sine to a cosine, or any other function. You could change the //x//-values. You can design very complicated scripts to accomplish many tasks. This requires a little knowledge of basic programming techiques:

*Input/Output
*Variable Types
*For Loops
*Conditional Statements
*Functions
*Advance Plotting

MATLAB comes with a large library of functions and scripts. Also, you can find many script these days on the web depending what you wish to accomplish. Several examples will be provided under the ''Examples'' section of this site.
[[Ratchet|Run1]]
[[Insect Fly|Run2]]
[[DolphinDraft|Run3]]
[[RBC|Run4]]
[[Fish School|Run5]]
[[Piezo |Run6]]
[[Stability|Run7]]
[[Squid|Run8]]

/***
|Name|SinglePageModePluginInfo|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.9.5|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||

|Description|Documentation for SinglePageModePlugin|
Normally, as you click on the links in TiddlyWiki, more and more tiddlers are displayed on the page. The order of this tiddler display depends upon when and where you have clicked. Some people like this non-linear method of reading the document, while others have reported that when many tiddlers have been opened, it can get somewhat confusing.  SinglePageModePlugin allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one item displayed at a time.
!!!!!Usage
<<<
When the plugin is enabled, only one tiddler will be displayed at a time and the browser window's titlebar is updated to include the current tiddler title.  The browser's location URL is also updated with a 'permalink' for the current tiddler so that it is easier to create a browser 'bookmark' for the current tiddler.  Alternatively, even when displaying multiple tiddlers //is// permitted, you can still reduce the potential for confusion by forcing  tiddlers to always open at the top (or bottom) of the page instead of being displayed following the tiddler containing the link that was clicked.
<<<
!!!!!Configuration

<<<
<<option chkSinglePageMode>> Display one tiddler at a time

><<option chkSinglePagePermalink>> Automatically permalink current tiddler
><<option chkSinglePageKeepFoldedTiddlers>> Don't close tiddlers that are folded
><<option chkSinglePageKeepEditedTiddlers>> Don't close tiddlers that are being edited
<<option chkTopOfPageMode>> Open tiddlers at the top of the page
<<option chkBottomOfPageMode>> Open tiddlers at the bottom of the page

<<option chkSinglePageAutoScroll>> Automatically scroll tiddler into view (if needed)

Notes:
* {{block{
The "display one tiddler at a time" option can also be //temporarily// set/reset by including a 'paramifier' in the document URL: {{{#SPM:true}}} or {{{#SPM:false}}}. You can also use {{{SPM:expression}}}, where 'expression' is any javascript statement that evaluates to true or false.  This allows you to create hard-coded links in other documents that can selectively enable/disable the use of this option based on various programmatic conditions, such as the current username. For example, using

&nbsp;&nbsp;&nbsp;{{{#SPM:config.options.txtUserName!="SomeName"}}}
enables 'one tiddler at a time' display for all users //other than// "~SomeName")}}}
* If more than one display mode is selected, 'one at a time' display takes precedence over both 'top' and 'bottom' settings, and if 'one at a time' setting is not used, 'top of page' takes precedence over 'bottom of page'.
* When using Apple's Safari browser, automatically setting the permalink causes an error and is disabled.
<<<
!!!!!Revisions
<<<
2008.06.12 [2.9.5] corrected 'scroll to top of page' logic in auto-scroll handling
2008.06.11 [2.9.4] added chkSinglePageKeepEditedTiddlers option
2008.06.05 [2.9.3] in displayTiddler(), bypass single/top/bottom mode handling if startingUp.  Allows multiple tiddlers to be displayed during startup processing (e.g., #story:DefaultTiddlers), even if single/top/bottom mode is enabled.
2008.04.18 [2.9.2] in displayTiddler() and checkLastURL(), handling for Unicode in tiddler titles (remove explicit conversion between Unicode and UTF, as this is apparently done automatically by encode/decodeURIComponent, resulting in double-encoding!
2008.04.08 [2.9.1] don't automatically add options to AdvancedOptions shadow tiddler
2008.04.02 [2.9.0] in displayTiddler(), when single-page mode is in use and a tiddler is being edited, ask for permission to save-and-close that tiddler, instead of just leaving it open.
2008.03.29 [2.8.3] in displayTiddler(), get title from tiddler object (if needed).  Fixes errors caused when calling function passes a tiddler *object* instead of a tiddler *title*
2008.03.14 [2.8.2] in displayTiddler(), if editing specified tiddler, just move it to top/bottom of story *without* re-rendering (prevents discard of partial edits).
2008.03.06 [2.8.1] in paramifier handler, start 'checkURL' timer if chkSinglePageMode is enabled
2008.03.06 [2.8.0] added option, {{{config.options.chkSinglePageKeepFoldedTiddlers}}}, so folded tiddlers won't be closed when using single-page mode.  Also, in checkURL(), if hash is a ''permaview'' (e.g., "#foo bar baz"), then display multiple tiddlers rather than attempting to display "foo bar baz" as a single tiddler
2008.03.05 [2.7.0] added support for "SPM:" URL paramifier
2008.03.01 [2.6.0] in hijack of displayTiddler(), added 'title' argument to closeAllTiddlers() so that target tiddler isn't closed-and-reopened if it was already displayed.  Also, added config.options.chkSinglePageAutoScrolloption to bypass automatic 'scroll into view' logic (note: core still does it's own ensureVisible() handling)
2007.12.22 [2.5.3] in checkLastURL(), use decodeURIComponent() instead of decodeURI so that tiddler titles with commas (and/or other punctuation) are correctly handled.
2007.10.26 [2.5.2] documentation cleanup
2007.10.08 [2.5.1] in displayTiddler(), when using single-page or top-of-page mode, scrollTo(0,0) to ensure that page header is in view.
2007.09.13 [2.5.0] for TPM/BPM modes, don't force tiddler to redisplay if already shown.  Allows transition between view/edit or collapsed/view templates, without repositioning displayed tiddler.
2007.09.12 [2.4.0] added option to disable automatic permalink feature.  Also, Safari is now excluded from permalinking action to avoid bug where tiddlers don't display after hash is updated.
2007.03.03 [2.3.1] fix typo when adding BPM option to AdvancedOptions (prevented checkbox from appearing)
2007.03.03 [2.3.0] added support for BottomOfPageMode (BPM) based on request from DaveGarbutt
2007.02.06 [2.2.3] in Story.prototype.displayTiddler(), use convertUnicodeToUTF8() for correct I18N string handling when creating URL hash string from tiddler title (based on bug report from BidiX)
2007.01.08 [2.2.2] use apply() to invoke hijacked core functions
2006.07.04 [2.2.1] in hijack for displayTiddlers(), suspend TPM as well as SPM so that DefaultTiddlers displays in the correct order.
2006.06.01 [2.2.0] added chkTopOfPageMode (TPM) handling
2006.02.04 [2.1.1] moved global variable declarations to config.* to avoid FireFox 1.5.0.1 crash bug when assigning to globals
2005.12.27 [2.1.0] hijack displayTiddlers() so that SPM can be suspended during startup while displaying the DefaultTiddlers (or #hash list).  Also, corrected initialization for undefined SPM flag to "false", so default behavior is to display multiple tiddlers
2005.12.27 [2.0.0] Update for TW2.0
2005.11.24 [1.1.2] When the back and forward buttons are used, the page now changes to match the URL.  Based on code added by Clint Checketts
2005.10.14 [1.1.1] permalink creation now calls encodeTiddlyLink() to handle tiddler titles with spaces in them
2005.10.14 [1.1.0] added automatic setting of window title and location bar ('auto-permalink').  feature suggestion by David Dickens.
2005.10.09 [1.0.1] combined documentation and code in a single tiddler
2005.08.15 [1.0.0] Initial Release


<<<

@@color(darkblue):font-size(1.8em):Kourosh Shoele@@
/*{{{*/
body{
 background: #f9f9f9 url(kouroshweb.png) no-repeat top left;
}

#titleLine{
 display: block;
 background: transparent url() no-repeat 18px -7px;
 _background: transparent;
 height: 120px;
 _height: 135px;
 width: 150px;

color:#000;
 border: 1px;
 padding: 60px;
 margin: 0;
}

* html #titleLine{
 filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='wiki.png',sizingMethod='scale');
}

#contentWrapper #siteTitle a{
 display: inline;
 font-weight: bold;
color:#000;
 font-size: 13px;
}



#siteTitle, #mainMenu{
 position: static;
}

#contentWrapper #sidebar{
 top: 0;
 left: 0;
}

#displayArea {
 margin: 0 0 0 17em;
}

#messageArea{
 position: fixed;
 top: 0;
 right: 0;
 font-size: 10px;
 border: 1px solid #aaa;
 background: #fff;
 z-index: 25;
}

#messageArea a:link{
color:#002bb8;
 text-decoration: none;
}

#messageArea a:hover{
 text-decoration: underline;
}

.viewer{
 background: #fff;
 border: 1px solid #aaa;
 padding: 1em;
margin: 0;
}

.body{
 padding: 1px;
}

.title{
 background: #fff;
 border: 1px solid #aaa;
 display: inline;
 margin-left: .65em;
 padding: 2px .5em;
 border-bottom: 0;
 font-weight: bold;
 color: #002bb8;
 font-size: 1.3em;
}

.toolbar{
 visibility: hidden;
 display: inline;
 padding: 0;
 font-family: sans-serif;
}

.toolbar a.button:link,.toolbar a.button:visited{
 background: #fff;
 border: 1px solid #aaa;
 color:#002bb8;
 font-size: 11px;
 padding-bottom: 0;
 margin-right: .25em;
}

.selected .toolbar {
 visibility: visible;

} 

/* TiddlyPedia was Created by Clinton Checketts based on the Monobook skin of Wikipedia */

#contentWrapper .toolbar .button:hover{
 border-bottom: 1px solid #fff;
 background: #fff;
 color:#002bb8;
}

.toolbar a.button:hover{
 border-bottom: 1px solid #fff;
 background: #fff;
 color:#000;
}

#displayArea .viewer a,a.button:link,a.button:visited,
a.tiddlyLink:link,a.tiddlyLink:visited,
#sidebarOptions .sliderPanel a{
color:#002bb8;
background: transparent;
 border: 0;
}

.viewer a:hover,a.button:hover,a.button:active,
a.tiddlyLink:hover,a.tiddlyLink:active,
.viewer a.button:hover,
#sidebarOptions .sliderPanel a:hover{
color:#002bb8;
 background: transparent;
 text-decoration: underline;
}

.viewer div.centeredTable {
	text-align: center;
}

.viewer div.centeredTable table {
	margin: 0 auto;
	text-align: left;
}

.viewer table.borderless,
.viewer table.borderless * {
	border: 0;
}

#mainMenu{
 font-family: sans-serif;
 text-align: left;
 font-size: 17px;
 width: 100%;
 margin: 0;
 padding: 0;
}

#mainMenu h1{
 font-size: 17px;
 font-weight: normal;
 padding: 0;
 margin: 0;
 background: transparent;
}

#mainMenu ul{
 font-size: 15px;
 border: 1px solid #aaa;
 padding: .25em 0;
 margin: 0;
 list-style-type: square;
 list-style-image: url(bullet.gif);
 background: #fff;
 width: 100%;
}

#mainMenu li{
 margin: 0 0 0 2em;
 padding: 0;
}

#contentWrapper #mainMenu a:link,#contentWrapper #mainMenu a:visited{
color:#002bb8;
 padding: 0;
 margin: 0;
 background: transparent;
}

#mainMenu .externalLink {
 text-decoration: none;
}

#mainMenu .externalLink:hover {
 text-decoration: underline;
}

#sidebar{
 padding: .5em;
 font-family: sans-serif;
}

#sidebarOptions{
 border: 1px solid #aaa;
 background: #fff;
 margin-top: .5em;
 width: 100%;

}

#sidebar .sliderPanel{
 margin: 0;
}

#contentWrapper #sidebarOptions .button,#contentWrapper #sidebarOptions .button:hover{
color:#002bb8;
 padding: .1em 0 .1em 2em;
 background: transparent url(bullet.gif) 10px -2px no-repeat;
}

#sidebarOptions input{
 width: 80%;
 margin: 0 .5em;
}

#sidebarTabs{
 background: #fff;
 margin-top: .5em;
 width: 100%;
}

#sidebarTabs .tabContents,#sidebarTabs .tabContents .tabContents{
 border: 1px solid #aaa;
 background: #fff;
}

#sidebarTabs .tabSelected,#sidebarTabs .tabcontents .tabSelected {
 background: #fff;
 border: 1px solid #aaa;
 border-bottom: 0;
 cursor: default;
 padding-bottom: 3px;
 color: #000;
}

#sidebarTabs .tabUnselected,#sidebarTabs .tabContents .tabUnselected{
 background: #aaa;
 padding-bottom: 0;
 color: #000; 
}

#contentWrapper #sidebarTabs .tiddlyLink,#contentWrapper #sidebarTabs .button,
#contentWrapper #sidebarTabs a.tiddlyLink:hover,#contentWrapper #sidebarTabs a.button:hover{
 background: transparent;
color:#002bb8;
}

.footer{
 margin: -1em 0 1em 0; 
}

.footer .button:hover,.editorFooter .button:hover{
background: transparent;
color:#002bb8;
 border-bottom: 1px solid #002bb8;
}

#popup{
 background: #e9e9e9;
 color: #000;
}

#popup hr{
 border-color: #aaa;
 background-color: #aaa;
}

#popup a{
 color: #000;
}

#popup a:hover,#contentWrapper #sidebarTabs #popup a:hover{
 background: #666;
 color: #fff;
 text-decoration: none;
}

#displayArea .tiddler a.tiddlyLinkNonExisting{
 color: #ba0000;
}

#displayArea .tiddler a.externalLink{
 text-decoration: none;
color:#002bb8;
 padding-right: 0;
 background: transparent url(external.png) 100% 50% no-repeat;
}

#displayArea .tiddler a.externalLink:hover{
 text-decoration: underline;
}

.viewer pre{
 background: #e9e9e9;
 border: 1px solid #666;
}

.viewer h1, .viewer h2, .viewer h3, .viewer h4, .viewer h5, .viewer h6{
 background: transparent;
 border-bottom: .2em solid #aaa;
}

#sidebar .sliderPanel{
 background: #e9e9e9;
}

#sidebar .sliderPanel input{width: auto;}

.tagged, .tagging, .listTitle{
 float: none;
 display: inline;
}

.tagged li, .tagging li,
.tagged ul, .tagging ul{
 display: inline;
}

.firstletter{ float:left; width:0.75em; font-size:400%; font-family:times,arial; line-height:60%; } 

.textcenter {text-align:center;}
.textright {text-align:right;}
.textjustify {text-align:justify;}
.textleft {text-align:left;}

/*}}}*/
/***
|Name|TiddlerEncryptionPlugin|
|Author|Lyall Pearce|
|Source|http://www.Remotely-Helpful.com/TiddlyWiki/TiddlerEncryptionPlugin.html|
|License|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|Version|3.2.1|
|~CoreVersion|2.4.0|
|Requires|None|
|Overrides|store.getSaver().externalizeTiddler(), store.getTiddler() and store.getTiddlerText()|
|Description|Encrypt/Decrypt Tiddlers with a Password key|

!!!!!Usage
<<<
* Tag a tiddler with Encrypt(prompt)
** Consider the 'prompt' something to help you remember the password with. If multiple tiddlers can be encrypted with the same 'prompt' and you will only be asked for the password once.
* Upon save, the Tiddler will be encrypted and the tag replaced with Decrypt(prompt).
** Failure to encrypt (by not entering a password) will leave the tiddler unencrypted and will leave the Encrypt(prompt) tag in place. This means that the next time you save, you will be asked for the password again.
** To have multiple tiddlers use the same password - simply use the same 'prompt'.
** Tiddlers that are encrypted may be automatically tagged 'excludeSearch' as there is no point in searching encrypted data - this is configurable by an option - you still may want to search the titles of encrypted tiddlers
** Tiddlers that are encrypted may be automatically tagged 'excludeLists', if you have them encrypted, you may also want to keep them 'hidden' - this is configurable by an option.
** Automatic removal of excludeLists and excludeSearch tags is performed, if the above two options are set, only if these two tags are the last 2 tags for a tiddler, if they are positioned somewhere else in the tags list, they will be left in place, meaning that the decrypted tiddler will not be searchable and/or will not appear in lists.
** Encrypted tiddlers are stored as displayable hex, to keep things visibly tidy, should you display an encrypted tiddler. There is nothing worse than seeing a pile of gobbledy gook on your screen. Additionally, the encrypted data is easily cut/paste/emailed if displayed in hex form.
* Tiddlers are decrypted only if you click the decrypt button or the decryptAll button, not when you load the TiddlyWiki
** If you don't display a tiddler, you won't have the option to decrypt it (unless you use the {{{<<EncryptionDecryptAll>>}}} macro)
** Tiddlers will re-encrypt automatically on save.
** Decryption of Tiddlers does not make your TiddlyWiki 'dirty' - you will not be asked to save if you leave the page.
* Errors are reported via diagnostic messages.
** Empty passwords, on save, will result in the tiddler being saved unencrypted - this should only occur with new tiddlers, decrypted tiddlers or with tiddlers who have had their 'prompt' tag changed.
** Encrypted tiddlers know if they are decrypted successfully - failure to decrypt a tiddler will ''not'' lose your data.
** Editing of an encrypted (that has not been unencrypted) tiddler will result in loss of that tiddler as the SHA1 checksums will no longer match, upon decryption. To this end, it is best that you do not check the option. You can, however edit an encrypted tiddler tag list - just do ''not'' change the tiddler contents.
** To change the password on a Tiddler, change the Encrypt('prompt') tag to a new prompt value, after decrypting the tiddler.
** You can edit the tags of an encrypted tiddler, so long as you do not edit the text.
** To change the password for all tiddlers of a particular prompt, use the {{{<<EncryptionChangePassword ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro.
** To decrypt all tiddlers of a particular "prompt string", use the {{{<<EncryptionDecryptAll ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro - this will make tiddlers encrypted with "prompt string" searchable - or prompt for all 'prompt strings', if none is supplied.
<<<
!!!!!Configuration
<<<
Useful Buttons: 
<<EncryptionChangePassword>> - Change passwords of encrypted tiddlers.
<<EncryptionDecryptAll>> - Decrypt ALL tiddlers - enables searching contents of encrypted tiddlers.
<<option chkExcludeEncryptedFromSearch>> - If set, Encrypted Tiddlers are excluded from searching by tagging with excludeSearch. If Clear, excludeSearch is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Searching of Encrypted Tiddlers is only meaningful for the Title and Tags.
<<option chkExcludeEncryptedFromLists>> - If set, Encrypted Tiddlers are excluded from lists by tagging with excludeLists. If Clear, excludeLists is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Preventing encrypted tiddlers from appearing in lists effectively hides them.
<<option chkShowDecryptButtonInContent>> - If set, Encrypted Tiddlers content is replaced by <<EncryptionDecryptThis>> button. This has consequences, in the current version as, if you edit the tiddler without decrypting it, you lose the contents.
<<<
!!!!!Revision History
<<<
* 3.2.1 - Returned the <<EncryptionDecryptThis>> button as an option.
* 3.2.0 - Ditched the 'Decrypt' button showing up in the tiddler contents if the tiddler is encrypted. It caused too much pain if you edit the tiddler without decrypting it - you lost your data as it was replaced by a Decrypt Macro call!  Additionally, a 'decrypt' button will now appear in the toolbar, just before the edit button, if the tiddler is encrypted. This button only appears if using core TiddlyWiki version 2.4 or above.
* 3.1.1 - Obscure bug whereby if an encrypted tiddler was a certain length, it would refuse to decrypt.
* 3.1.0 - When creating a new Encrypt(prompt) tiddler and you have not previously decrypted a tiddler with the same prompt, on save, you will be prompted for the password to encrypt the tiddler. Prior to encrypting, an attempt to decrypt all other tiddlers with the same prompt, is performed. If any tiddler fails to decrypt, the save is aborted - this is so you don't accidentally have 2 (or more!) passwords for the same prompt. Either you enter the correct password, change the prompt string and try re-saving or you cancel (and the tiddler is saved unencrypted).
* 3.0.1 - Allow Enter to be used for password entry, rather than having to press the OK button.
* 3.0.0 - Major revamp internally to support entry of passwords using forms such that passwords are no longer visible on entry. Completely backward compatible with old encrypted tiddlers. No more using the javascript prompt() function.
<<<
!!!!!Additional work

***/
//{{{
version.extensions.TiddlerEncryptionPlugin = {major: 3, minor: 2, revision: 1, date: new Date(2008,10,26)};

// where I cache the passwords - for want of a better place.
config.encryptionPasswords = new Array();
config.encryptionReEnterPasswords = false;

if(config.options.chkExcludeEncryptedFromSearch == undefined) config.options.chkExcludeEncryptedFromSearch = false;
if(config.options.chkExcludeEncryptedFromLists == undefined) config.options.chkExcludeEncryptedFromLists = false;
if(config.options.chkShowDecryptButtonInContent == undefined) config.options.chkShowDecryptButtonInContent = true;

config.macros.EncryptionChangePassword = {};
config.macros.EncryptionChangePassword.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Change Passwords", 
				       (params[1] && params[1].length > 0) ? params[1] : "Change Passwords" + (params[2] ? " for prompt "+params[2] : ""), 
				       onClickEncryptionChangePassword,
				       null,
				       null,
				       params[3]);
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("promptString", params[2]);
    }
};

config.macros.EncryptionDecryptAll = {};
config.macros.EncryptionDecryptAll.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Decrypt All", 
				       (params[1] && params[1].length > 0) ? params[1] : "Decrypt All Tiddlers" + ((params[2] && params[2].length > 0) ? " for prompt "+params[2] : " for a given 'prompt string'"), 
				       onClickEncryptionDecryptAll,
				       null,
				       null,
				       params[3]);
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("promptString", params[2]);
    }
};

config.macros.EncryptionDecryptThis = {};
config.macros.EncryptionDecryptThis.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Decrypt", 
				       (params[1] && params[1].length > 0) ? params[1] : "Decrypt this Tiddler", 
				       onClickEncryptionDecryptThis,
				       null,
				       null,
				       params[3]);
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("theTiddler", params[2]);
    }
};
// toolbar button to decrypt tiddlers.
config.commands.decryptThis = {
  text: "decrypt",
  tooltip: "Decrypt this tiddler",
  isEnabled : function(tiddler) {
	// Only show decrypt button if tiddler is tagged as Decrypt(
	if(tiddler.tags.join().indexOf('Decrypt(') == -1)  {
	    return false;
	} else {
	    return true;
	}
    },	
  handler: function(event, src, title) {
	encryptionGetAndDecryptTiddler(title);
	return false; 
    }
};
// core version 2.4 or above get a 'decrypt' button in the toolbar.
if(config.shadowTiddlers && config.shadowTiddlers.ToolbarCommands  && config.shadowTiddlers.ToolbarCommands.indexOf('decryptThis') == -1) {
    // put our toolbar button in before the edit button.
    // won't work if editTiddler is not the default item (prefixed with plus)
    config.shadowTiddlers.ToolbarCommands.replace(/\+editTiddler/,'decryptThis +editTiddler');
}


// Called by the EncryptionChangePassword macro/button
// Also invoked by the callback for password entry
function onClickEncryptionChangePassword(eventObject) {
    var promptString;
    if(!promptString && this.getAttribute) {
	promptString = this.getAttribute("promptString");
    }
    // I do call this function directly
    if(!promptString && typeof(eventObject) == "string") {
	promptString = eventObject;
    }
    if(!promptString) {
	promptString = prompt("Enter 'prompt string' to change password for:","");
    }
    if(!promptString) {
	return;
    }
    if(! config.encryptionPasswords[promptString]) {
	var changePasswordContext = {changePasswordPromptString: promptString,
				     callbackFunction: MyChangePasswordPromptCallback_TiddlerEncryptionPlugin};
	MyPrompt_TiddlerEncryptionPlugin(promptString,"",changePasswordContext);
	return;
	// Callback function will re-invoke this function
    }

    // Decrypt ALL tiddlers for that prompt
    onClickEncryptionDecryptAll(promptString);
    // Now ditch the cached password, this will force the re-request for the new password, on save.
    displayMessage("Save TiddlyWiki to set new password for '"+promptString+"'");
    config.encryptionPasswords[promptString] = null;
    // mark store as dirty so a save will be requrested.
    store.setDirty(true);
    autoSaveChanges(); 
    return;
};
// Called by the password entry form when the user clicks 'OK' button.
function MyChangePasswordPromptCallback_TiddlerEncryptionPlugin(context) {
    config.encryptionPasswords[context.passwordPrompt] = context.password;
    onClickEncryptionChangePassword(context.changePasswordPromptString);
    return;
}
// Called by the EncryptionDecryptThis macro/button
function onClickEncryptionDecryptThis() {
    var theTiddler = this.getAttribute("theTiddler");
    if(!theTiddler) {
	return;
    }
    encryptionGetAndDecryptTiddler(theTiddler);
    return;
};

function encryptionGetAndDecryptTiddler(title) {
    config.encryptionReEnterPasswords = true;
    try {
	theTiddler = store.getTiddler(title);
	config.encryptionReEnterPasswords = false;
	story.refreshAllTiddlers();
    } catch (e) {
	if(e == "DecryptionFailed") {
	    displayMessage("Decryption failed");
	    return;
	}
    } // catch
    return;
};

// called by the EncryptionDecryptAlll macro/button
// Also called by the callback after the user clicks 'OK' button on the password entry form
function onClickEncryptionDecryptAll(eventObject) {
    var promptString;
    if(!promptString && this.getAttribute) {
	promptString = this.getAttribute("promptString");
    }

    // I do call this function directly
    if(!promptString && typeof(eventObject) == "string") {
	promptString = eventObject;
    }
    if(!promptString) {
	promptString = "";
    }

    // Loop through all tiddlers, looking to see if there are any Decrypt(promptString) tagged tiddlers
    // If there are, check to see if their password has been cached.
    // If not, ask for the first one that is missing, that we find
    // the call back function will store that password then invoke this function again, 
    // which will repeat the whole process. If we find all passwords have been cached
    // then we will finally do the decryptAll functionality, which will then
    // be able to decrypt all the required tiddlers, without prompting.
    // We have to do this whole rigmarole because we are using a 'form' to enter the password
    // rather than the 'prompt()' function - which shows the value of the password.
    var tagToSearchFor="Decrypt("+promptString;
    config.encryptionReEnterPasswords = true; 
    var promptGenerated = false;
    store.forEachTiddler(function(store,tiddler) {
	    // Note, there is no way to stop the forEachTiddler iterations
	    if(!promptGenerated && tiddler && tiddler.tags) {
		for(var ix=0; ix<tiddler.tags.length && !promptGenerated; ix++) {
		    if(tiddler.tags[ix].indexOf(tagToSearchFor) == 0) {
			var tag = tiddler.tags[ix];
			var lastBracket=tag.lastIndexOf(")");
			if(lastBracket >= 0) {
			    // Ok, tagged with Encrypt(passwordPrompt)
			    // extract the passwordPrompt name
			    var passwordPromptString=tag.substring(8,lastBracket);
			    if(!config.encryptionPasswords[passwordPromptString]) {
				// no password cached, prompt and cache it, rather than decryptAll
				// callback from prompting form will resume decryptAll attempt.
				var decryptAllContext = {decryptAllPromptString: promptString,
							 callbackFunction: MyDecryptAllPromptCallback_TiddlerEncryptionPlugin};
				MyPrompt_TiddlerEncryptionPlugin(passwordPromptString,"",decryptAllContext);
				promptGenerated = true;
			    } // if(!config.encryptionPasswords
			} // if(lastBracket
		    } // if(tiddler.tags[ix]..
		} // for
	    } // if
	}); // store.forEachTiddler
    // If we get here, all passwords have been cached.
    if(!promptGenerated) {
	config.encryptionReEnterPasswords = false;
	// Now do the decrypt all functionality
	try {
	    store.forEachTiddler(function(store,tiddler) {
		    // Note, there is no way to stop the forEachTiddler iterations
		    if(tiddler && tiddler.tags) {
			for(var ix=0; ix<tiddler.tags.length; ix++) {
			    if(tiddler.tags[ix].indexOf(tagToSearchFor) == 0) {
				try {
				    CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler);
				} catch (e) {
				    displayMessage("Decryption of '"+tiddler.title+"' failed.");
				    // throw e;
				}
			    } // if(tiddler.tags
			} // for
		    } // if
		}); // store.forEachTiddler
	    displayMessage("All tiddlers" + (promptString != "" ? " for '"+promptString+"'" : "") + " have been decrypted");
	} catch (e) {
	    if(e == "DecryptionFailed") {
		return;
	    }
	} // catch
    }
    return;
};

function MyDecryptAllPromptCallback_TiddlerEncryptionPlugin(context) {
    config.encryptionPasswords[context.passwordPrompt] = context.password;
    // restart the decryptAll process again after the user has entered a password.
    onClickEncryptionDecryptAll(context.decryptAllPromptString);
    return;
}

saveChanges_TiddlerEncryptionPlugin = saveChanges;
saveChanges = function(onlyIfDirty,tiddlers) {
    // Loop through all tiddlers, looking to see if there are any Encrypt(string) tagged tiddlers
    // If there are, check to see if their password has been cached.
    // If not, ask for the first one that is missing, that we find
    // the call back function will store that password then invoke this function again, 
    // which will repeat the whole process. If we find all passwords have been cached
    // then we will finally call the original saveChanges() function, which will then
    // be able to save the tiddlers.
    // We have to do this whole rigmarole because we are using a 'form' to enter the password
    // rather than the 'prompt()' function - which shows the value of the password.
    config.encryptionReEnterPasswords = true; 
    var promptGenerated = false;
    store.forEachTiddler(function(store,tiddler) {
	    if(!promptGenerated && tiddler && tiddler.tags) {
		for(var ix=0; ix<tiddler.tags.length && !promptGenerated; ix++) {
		    if(tiddler.tags[ix].indexOf("Encrypt(") == 0) {
			var tag = tiddler.tags[ix];
			var lastBracket=tag.lastIndexOf(")");
			if(lastBracket >= 0) {
			    // Ok, tagged with Encrypt(passwordPrompt)
			    // extract the passwordPrompt name
			    var passwordPrompt=tag.substring(8,lastBracket);
			    if(!config.encryptionPasswords[passwordPrompt]) {
				// no password cached, prompt and cache it, rather than save
				var saveContext = {onlyIfDirty: onlyIfDirty, 
						   tiddlers: tiddlers, 
				                   callbackFunction: MySavePromptCallback_TiddlerEncryptionPlugin};
				MyPrompt_TiddlerEncryptionPlugin(passwordPrompt,"",saveContext);
				promptGenerated = true;
			    } // if(!config.encryptionPasswords
			} // if(lastBracket
		    } // if(tiddler.tags[ix]..
		} // for
	    } // if
	}); // store.forEachTiddler
    // If we get here, all passwords have been cached.
    if(!promptGenerated) {
	config.encryptionReEnterPasswords = false;
	saveChanges_TiddlerEncryptionPlugin(onlyIfDirty,tiddlers);
    }
    return;
}

function MySavePromptCallback_TiddlerEncryptionPlugin(context) {
    config.encryptionPasswords[context.passwordPrompt] = context.password;
    // validate the password entered by attempting to decrypt all tiddlers
    // with the same encryption prompt string.
    onClickEncryptionDecryptAll(context.passwordPrompt);

    // restart the save process again
    saveChanges(context.onlyIfDirty, context.tiddlers);
    return;
}

store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin = store.getSaver().externalizeTiddler;
store.getSaver().externalizeTiddler = function(store, tiddler) {
    // Ok, got the tiddler, track down the passwordPrompt in the tags.
    // track down the Encrypt(passwordPrompt) tag
    if(tiddler && tiddler.tags) {
	for(var g=0; g<tiddler.tags.length; g++) {
	    var tag = tiddler.tags[g];
	    if(tag.indexOf("Encrypt(") == 0) {
		var lastBracket=tag.lastIndexOf(")");
		if(lastBracket >= 0) {
		    // Ok, tagged with Encrypt(passwordPrompt)
		    // extract the passwordPrompt name
		    var passwordPrompt=tag.substring(8,lastBracket);
		    // Ok, Encrypt this tiddler!
		    var decryptedSHA1 = Crypto.hexSha1Str(tiddler.text);
		    var password =  GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(passwordPrompt);
		    if(password) {
			var encryptedText = TEAencrypt(tiddler.text, password);
			encryptedText = StringToHext_TiddlerEncryptionPlugin(encryptedText);
			tiddler.text = "Encrypted("+decryptedSHA1+")\n"+encryptedText;
			// Replace the Tag with the Decrypt() tag
			tiddler.tags[g]="Decrypt("+passwordPrompt+")";
			// let the store know it's dirty
			store.setDirty(tiddler.title, true);
			// prevent searches on encrypted tiddlers, still nice to search on title though.
			if(config.options.chkExcludeEncryptedFromSearch == true) {
			    tiddler.tags.push("excludeSearch");
			}
			// prevent lists of encrypted tiddlers
			if(config.options.chkExcludeEncryptedFromLists == true) {
			    tiddler.tags.push("excludeLists");
			}
		    } else {
			// do not encrypt - no password entered
		    }
		    break;
		} // if (lastBracket...
	    } // if(tag.indexOf(...
	} // for(var g=0;...
    } // if(tiddler.tags...
    
    // Then, finally, do the save by calling the function we override.

    return store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin(store, tiddler);
};

function CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler) {
    if(tiddler && tiddler.tags) {
	for(var g=0; g<tiddler.tags.length; g++) {
	    var tag = tiddler.tags[g];
	    if(tag.indexOf("Decrypt(") == 0) {
		var lastBracket=tag.lastIndexOf(")");
		if(lastBracket >= 0) {
		    if(tiddler.text.substr(0,10) == "Encrypted(") {
			var closingSHA1Bracket = tiddler.text.indexOf(")");
			var decryptedSHA1 = tiddler.text.substring(10, closingSHA1Bracket);
			// Ok, tagged with Decrypt(passwordPrompt)
			// extract the passwordPrompt name
			var passwordPrompt=tag.substring(8,lastBracket);
			// Ok, Decrypt this tiddler!
			var decryptedText = tiddler.text.substr(closingSHA1Bracket+2);
			decryptedText = HexToString_TiddlerEncryptionPlugin(decryptedText);
                        // prompt("Decryption request for Tiddler '"+tiddler.title+"'");
			var password = GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(passwordPrompt);
			if(password) {
			    decryptedText = TEAdecrypt(decryptedText, password );
			    var thisDecryptedSHA1 = Crypto.hexSha1Str(decryptedText);
			    if(decryptedSHA1 == thisDecryptedSHA1) {
				tiddler.text = decryptedText;
				// Replace the Tag with the Encrypt() tag
				tiddler.tags[g]="Encrypt("+passwordPrompt+")";
				if(tiddler.tags[tiddler.tags.length-1] == 'excludeLists') {
				    // Remove exclude lists only if it's the last entry
				    // as it's automatically put there by encryption
				    tiddler.tags.length--;
				}
				if(tiddler.tags[tiddler.tags.length-1] == 'excludeSearch') {
				    // Remove exclude search only if it's the last entry
				    // as it's automatically put there by encryption
				    tiddler.tags.length--;
				}
			    } else {
				// Did not decrypt, discard the password from the cache
				config.encryptionPasswords[passwordPrompt] = null;
				config.encryptionReEnterPasswords = false;
				throw "DecryptionFailed";
			    }
			} else {
			    // no password supplied, dont bother trying to decrypt
			    config.encryptionReEnterPasswords = false;
			    throw "DecryptionFailed";
			}
		    } else {
			// Tagged as encrypted but not expected format, just leave it unchanged
		    }
		    break; // out of for loop
		} // if (lastBracket...
	    } // if(tag.indexOf(...
	} // for(var g=0;...
    } // if (tiddler && tags)
    return tiddler;
};

store.getTiddler_TiddlerEncryptionPlugin = store.getTiddler;
store.getTiddler = function(title) {
    var tiddler = store.getTiddler_TiddlerEncryptionPlugin(title);
    if(tiddler) { // shadow tiddlers are not expected to be encrypted.
	try {
	    return CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler);
	} catch (e) {
	    if (config.options.chkShowDecryptButtonInContent == true) {
		if(e == "DecryptionFailed") {
		    var tiddler = store.getTiddler("DecryptionFailed");
		    if(!tiddler) {
			tiddler = new Tiddler();
			tiddler.set(title,
				    "<<EncryptionDecryptThis \"Decrypt\" \"Decrypt this tiddler\" \""+title+"\">>",
				    config.views.wikified.shadowModifier,
				    version.date,[],version.date);
		    } 
		    return tiddler;
		} // if(e)
	    }
	    return(tiddler);
	} // catch
    } // if(tiddler) {
    return null;
};

store.getTiddlerText_TiddlerEncryptionPlugin = store.getTiddlerText;
store.getTiddlerText = function(title,defaultText) {
    // Simply retrieve the tiddler, normally, if it requires decryption, it will be decrypted
    var decryptedTiddler = store.getTiddler(title);
    if(decryptedTiddler) {
	return decryptedTiddler.text;
    }
    //Ok, rather than duplicate all the core code, the above code should fail if we reach here
    // let the core code take over.
    return  store.getTiddlerText_TiddlerEncryptionPlugin(title,defaultText);
};

// Given a prompt, search our cache to see if we have already entered the password.
// Can return null if the user enters nothing.
function MyPrompt_TiddlerEncryptionPlugin(promptString,defaultValue,context) {
    if(!context) {
	context = {};
    }
    context.passwordPrompt = promptString;
    PasswordPrompt.prompt(MyPromptCallback_TiddlerEncryptionPlugin, context);
    return;
}

function MyPromptCallback_TiddlerEncryptionPlugin(context) {
    if(context.callbackFunction) {
	context.callbackFunction(context);
    } else {
	config.encryptionPasswords[context.passwordPrompt] = context.password;
	story.refreshAllTiddlers(true);
    }
    return;
}

function GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString) {
    if(!config.encryptionPasswords[promptString]) {
	config.encryptionPasswords[promptString] = MyPrompt_TiddlerEncryptionPlugin(promptString, "");
    }
    return config.encryptionPasswords[promptString]; // may be null, prompt can be cancelled.
}

function GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(promptString) {
    if(config.encryptionReEnterPasswords) {
	return GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString);
    } else {
	return config.encryptionPasswords[promptString];
    }
}

// Make the encrypted tiddlies look a little more presentable.
function StringToHext_TiddlerEncryptionPlugin(theString) {
    var theResult = "";
    for(var i=0; i<theString.length; i++) {
	var theHex = theString.charCodeAt(i).toString(16);
	if(theHex.length<2) {
	    theResult += "0"+theHex;
	} else {
	    theResult += theHex;
	}
	if(i && i % 32 == 0)
	    theResult += "\n";
    }
    return theResult;
}

function HexToString_TiddlerEncryptionPlugin(theString) {
    var theResult = "";
    for(var i=0; i<theString.length; i+=2) {
	if(theString.charAt(i) == "\n") {
	    i--;	// cause us to skip over the newline and resume
	    continue;
	}
	theResult += String.fromCharCode(parseInt(theString.substr(i, 2),16));
    }
    return theResult;
}
//
// Heavily leveraged from http://trac.tiddlywiki.org/browser/Trunk/contributors/SaqImtiaz/verticals/Hesperian/PasswordPromptPlugin.js  Revision 5635
//
PasswordPrompt ={
  prompt : function(callback,context){
	if (!context) {
	    context = {};
	}
	var box = createTiddlyElement(document.getElementById("contentWrapper"),'div','passwordPromptBox');
	box.innerHTML = store.getTiddlerText('PasswordPromptTemplate');
	box.style.position = 'absolute';
	this.center(box);
	document.getElementById('promptDisplayField').value = context.passwordPrompt;
	var passwordInputField = document.getElementById('passwordInputField');
	passwordInputField.onkeyup = function(ev) {
	    var e = ev || window.event;
	    if(e.keyCode == 10 || e.keyCode == 13) { // Enter
		PasswordPrompt.submit(callback, context);
	    }
	};
	passwordInputField.focus();
	document.getElementById('passwordPromptSubmitBtn').onclick = function(){PasswordPrompt.submit(callback,context);};
	document.getElementById('passwordPromptCancelBtn').onclick = function(){PasswordPrompt.cancel(callback,context);};
    },     
 	       
  center : function(el){
	var size = this.getsize(el);
	el.style.left = (Math.round(findWindowWidth()/2) - (size.width /2) + findScrollX())+'px';
	el.style.top = (Math.round(findWindowHeight()/2) - (size.height /2) + findScrollY())+'px';
    },
 	       
  getsize : function (el){
	var x = {};
	x.width = el.offsetWidth || el.style.pixelWidth;
	x.height = el.offsetHeight || el.style.pixelHeight;
	return x;
    },
 	       
  submit : function(cb,context){
	context.passwordPrompt = document.getElementById('promptDisplayField').value;
	context.password = document.getElementById('passwordInputField').value;
	var box = document.getElementById('passwordPromptBox');
	box.parentNode.removeChild(box);
	cb(context);
	return false;
    },

  cancel : function(cb,context){
	var box = document.getElementById('passwordPromptBox');
	box.parentNode.removeChild(box);
	return false;
    },
 	       
  setStyles : function(){
	setStylesheet(
	    "#passwordPromptBox dd.submit {margin-left:0; font-weight: bold; margin-top:1em;}\n"+
	    "#passwordPromptBox dd.submit .button {padding:0.5em 1em; border:1px solid #ccc;}\n"+
	    "#passwordPromptBox dt.heading {margin-bottom:0.5em; font-size:1.2em;}\n"+
	    "#passwordPromptBox {border:1px solid #ccc;background-color: #eee;padding:1em 2em;}",'passwordPromptStyles');
    },
 	       
  template : '<form action="" onsubmit="return false;" id="passwordPromptForm">\n'+
  '    <dl>\n'+
  '        <dt class="heading">Please enter the password:</dt>\n'+
  '        <dt>Prompt:</dt>\n'+
  '        <dd><input type="text" readonly id="promptDisplayField" class="display"/></dd>\n'+
  '        <dt>Password:</dt>\n'+
  '        <dd><input type="password" tabindex="1" class="input" id="passwordInputField"/></dd>\n'+
  '        <dd class="submit">\n'+
  '            <a tabindex="2" href="javascript:;" class="button" id="passwordPromptSubmitBtn">OK</a>\n'+
  '            <a tabindex="3" href="javascript:;" class="button" id="passwordPromptCancelBtn">Cancel</a>\n'+
  '        </dd>\n'+
  '    </dl>\n'+
  '</form>',
 	                         
  init : function(){
	config.shadowTiddlers.PasswordPromptTemplate = this.template;
	this.setStyles();
    }
};
 	
PasswordPrompt.init();

// http://www.movable-type.co.uk/scripts/tea-block.html
//
// TEAencrypt: Use Corrected Block TEA to encrypt plaintext using password
//             (note plaintext & password must be strings not string objects)
//
// Return encrypted text as string
//
function TEAencrypt(plaintext, password)
{
    if (plaintext.length == 0) return('');  // nothing to encrypt
    // 'escape' plaintext so chars outside ISO-8859-1 work in single-byte packing, but keep
    // spaces as spaces (not '%20') so encrypted text doesn't grow too long (quick & dirty)
    var asciitext = escape(plaintext).replace(/%20/g,' ');
    var v = strToLongs(asciitext);  // convert string to array of longs
    if (v.length <= 1) v[1] = 0;  // algorithm doesn't work for n<2 so fudge by adding a null
    var k = strToLongs(password.slice(0,16));  // simply convert first 16 chars of password as key
    var n = v.length;

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = 0;

    while (q-- > 0) {  // 6 + 52/n operations gives between 6 & 32 mixes on each word
        sum += delta;
        e = sum>>>2 & 3;
        for (var p = 0; p < n; p++) {
            y = v[(p+1)%n];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
            z = v[p] += mx;
        }
    }

    var ciphertext = longsToStr(v);

    return escCtrlCh(ciphertext);
}

//
// TEAdecrypt: Use Corrected Block TEA to decrypt ciphertext using password
//
function TEAdecrypt(ciphertext, password)
{
    if (ciphertext.length == 0) return('');
    var v = strToLongs(unescCtrlCh(ciphertext));
    var k = strToLongs(password.slice(0,16)); 
    var n = v.length;

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = q*delta;

    while (sum != 0) {
        e = sum>>>2 & 3;
        for (var p = n-1; p >= 0; p--) {
            z = v[p>0 ? p-1 : n-1];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
            y = v[p] -= mx;
        }

        sum -= delta;
    }

    var plaintext = longsToStr(v);

    // strip trailing null chars resulting from filling 4-char blocks:
    plaintext = plaintext.replace(/\0+$/,'');

    return unescape(plaintext);
}


// supporting functions

function strToLongs(s) {  // convert string to array of longs, each containing 4 chars
    // note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
    var l = new Array(Math.ceil(s.length/4));
    for (var i=0; i<l.length; i++) {
        // note little-endian encoding - endianness is irrelevant as long as 
        // it is the same in longsToStr() 
        l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) + 
               (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
    }
    return l;  // note running off the end of the string generates nulls since 
}              // bitwise operators treat NaN as 0

function longsToStr(l) {  // convert array of longs back to string
    var a = new Array(l.length);
    for (var i=0; i<l.length; i++) {
        a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF, 
                                   l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
    }
    return a.join('');  // use Array.join() rather than repeated string appends for efficiency
}

function escCtrlCh(str) {  // escape control chars etc which might cause problems with encrypted texts
    return str.replace(/[\0\t\n\v\f\r\xa0'"!]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
}

function unescCtrlCh(str) {  // unescape potentially problematic nulls and control characters
    return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
}

//}}}
/***
|Name|TiddlerEncryptionPlugin|
|Author|Lyall Pearce|
|Source|http://www.Remotely-Helpful.com/TiddlyWiki/TiddlerEncryptionPlugin.html|
|License|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|Version|2.0.1|
|~CoreVersion|2.3.0|
|Requires|None|
|Overrides|store.getSaver().externalizeTiddler(), store.getTiddler() and store.getTiddlerText()|
|Description|Encrypt/Decrypt Tiddlers with a Password key|

!!!!!Usage
<<<
* Tag a tiddler with Encrypt(prompt)
** Consider the 'prompt' something to help you remember the password with. If multiple tiddlers can be encrypted with the same 'prompt' and you will only be asked for the password once.
* Upon save, the Tiddler will be encrypted and the tag replaced with Decrypt(prompt).
** Failure to encrypt (by not entering a password) will leave the tiddler unencrypted and will leave the Encrypt(prompt) tag in place. This means that the next time you save, you will be asked for the password again.
** To have multiple tiddlers use the same password - simply use the same 'prompt'.
** Tiddlers that are encrypted may be tagged 'excludeSearch' as there is no point in searching encrypted data - this is configurable by an option - you still may want to search the titles of encrypted tiddlers
** Tiddlers that are encrypted may be tagged 'excludeLists', as activities that list tiddlers may trigger password prompting when none was desired - this is configurable by an option.
** Automatic removal of excludeLists and excludeSearch tags is performed, if the above two options are set, only if these two tags are the last 2 tags for a tiddler.
** Encrypted tiddlers are stored as displayable hex, to keep things visibly tidy, should you display an encrypted tiddler. There is nothing worse than seeing a pile of gobbledy gook on your screen. Additionally, the encrypted data is easily cut/paste/emailed if displayed in hex form.
* Tiddlers are decrypted on initial display, not when you load the TiddlyWiki
** If you don't display a tiddler, you won't decrypt it (unless you use the {{{<<EncryptionDecryptAll>>}}} macro)
** Tiddlers will re-encrypt automatically on save.
** Decryption of Tiddlers does not make your TiddlyWiki 'dirty' - you will not be asked to save if you leave the page.
* Errors are reported via diagnostic messages.
** Empty passwords, on save, will result in the tiddler being saved unencrypted - this should only occur with new tiddlers, decrypted tiddlers or with tiddlers who have had their 'prompt' tag changed.
** Encrypted tiddlers know if they are decrypted successfully - failure to decrypt a tiddler will ''not'' lose your data.
** Editing of an encrypted (that has not been unencrypted) tiddler will result in loss of that tiddler as the SHA1 checksums will no longer match, upon decryption. To this end, it is best that you do not check the option.
** To change the password on a Tiddler, change the Encrypt('prompt') tag to a new prompt value, after decrypting the tiddler.
** You can edit the tags of an encrypted tiddler, so long as you do not edit the text.
** To change the password for all tiddlers of a particular prompt, use the {{{<<EncryptionChangePassword ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro.
** To decrypt all tiddlers of a particular "prompt string", use the {{{<<EncryptionDecryptAll ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro - this will make tiddlers encrypted with "prompt string" searchable - or prompt for all 'prompt strings', if none is supplied.
<<<
!!!!!Configuration
<<<
Useful Buttons: 
<<EncryptionChangePassword>> - Change passwords of encrypted tiddlers.
<<EncryptionDecryptAll>> - Decrypt ALL tiddlers - enables searching contents of encrypted tiddlers.
<<option chkExcludeEncryptedFromSearch>> - If set, Encrypted Tiddlers are excluded from searching by tagging with excludeSearch. If Clear, excludeSearch is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Searching of Encrypted Tiddlers is only meaningful for the Title and Tags.
<<option chkExcludeEncryptedFromLists>> - If set, Encrypted Tiddlers are excluded from lists by tagging with excludeLists. If Clear, excludeLists is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Preventing encrypted tiddlers from appearing in lists effectively hides them.
<<option chkCachePasswords>> - If unchecked, do not cache passwords. This means you will be prompted for the password every time you display an encrypted tiddler (not forgetting that once they are displayed, they stay decrypted until the next save).
<<<
!!!!!Revision History
<<<
* 2.0.1 - Fixed the obscure decryption problem if an encrypted tiddler was a certain length.
* 2.0.0 - No longer display encrypted tiddler contents, display a button which will decrypt the tiddler. Additionally, do not automatically prompt for passwords - rely on either the Decrypt or DecryptAll buttons to intitiate a prompt for passwords. This is the only change in behaviour, if you don't like this behaviour, don't upgrade from 1.10.2
<<<
!!!!!Additional work

***/
//{{{
version.extensions.TiddlerEncryptionPlugin = {major: 2, minor: 0, revision: 1, date: new Date(2008,10,6)};

// where I cache the passwords - for want of a better place.
config.encryptionPasswords = new Array();
config.encryptionReEnterPasswords = false;

if(config.options.chkExcludeEncryptedFromSearch == undefined) config.options.chkExcludeEncryptedFromSearch = false;
if(config.options.chkExcludeEncryptedFromLists == undefined) config.options.chkExcludeEncryptedFromLists = false;
if(config.options.chkCachePasswords == undefined) config.options.chkCachePasswords = true;


config.macros.EncryptionChangePassword = {};
config.macros.EncryptionChangePassword.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Change Passwords", 
				       (params[1] && params[1].length > 0) ? params[1] : "Change Passwords" + (params[2] ? " for prompt "+params[2] : ""), 
				       onClickEncryptionChangePassword,
				       null,
				       null,
				       params[3]);
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("promptString", params[2]);
    }
};

config.macros.EncryptionDecryptAll = {};
config.macros.EncryptionDecryptAll.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Decrypt All", 
				       (params[1] && params[1].length > 0) ? params[1] : "Decrypt All Tiddlers" + ((params[2] && params[2].length > 0) ? " for prompt "+params[2] : " for a given 'prompt string'"), 
				       onClickEncryptionDecryptAll,
				       null,
				       null,
				       params[3]);
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("promptString", params[2]);
    }
};

config.macros.EncryptionDecryptThis = {};
config.macros.EncryptionDecryptThis.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Decrypt", 
				       (params[1] && params[1].length > 0) ? params[1] : "Decrypt this Tiddler", 
				       onClickEncryptionDecryptThis,
				       null,
				       null,
				       params[3]);
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("theTiddler", params[2]);
    }
};

function onClickEncryptionChangePassword() {
    // Prompt for 'prompt string'
    
    var promptString = this.getAttribute("promptString");
    if(!promptString) {
	promptString = prompt("Enter 'prompt string' to change password for:","");
    }
    if(!promptString) {
	return;
    }
    // Prompt for 'old password'
    var oldPassword = GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString);
    if(!oldPassword) {
	return;
    }
    // Decrypt ALL tiddlers for that prompt
    var decryptTag = "Decrypt("+promptString+")";
    var tiddlersToDecrypt = store.getTaggedTiddlers(decryptTag);
    try {
	for(var ix=0; ix<tiddlersToDecrypt.length; ix++) {
	    CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddlersToDecrypt[ix]);
	}
    } catch (e) {
	if(e == "DecryptionFailed") {
	    displayMessage("Password incorrect.");
	    return;
	} else {
	    throw e;
	}
    }
    var newPassword = MyPrompt_TiddlerEncryptionPlugin("Enter new password for '"+promptString+"'", "");
    if(newPassword) {
	var newPasswordAgain = MyPrompt_TiddlerEncryptionPlugin("Enter new password, again, for '"+promptString+"'", "");
	if(newPasswordAgain && newPassword == newPasswordAgain) {
	    if(config.optionsDesc.chkCachePasswords == false) {
		config.encryptionPasswords[promptString] = newPasswordAgain;
	    }
	    displayMessage("Password for '"+promptString+"' updated.");
	}
    }
    store.setDirty(true);
    autoSaveChanges();
    return;
};

function onClickEncryptionDecryptThis() {
    var theTiddler = this.getAttribute("theTiddler");
    if(!theTiddler) {
	return;
    }
    config.encryptionReEnterPasswords = true;
    try {
	theTiddler = store.getTiddler(theTiddler);
	config.encryptionReEnterPasswords = false;
	story.refreshAllTiddlers();
    } catch (e) {
	if(e == "DecryptionFailed") {
	    displayMessage("Decryption failed");
	    return;
	}
    } // catch
    return;
};

function onClickEncryptionDecryptAll() {
    var promptString = this.getAttribute("promptString");
    if(!promptString) {
	promptString = "";
    }
    var tagToSearchFor="Decrypt("+promptString;
    config.encryptionReEnterPasswords = true; 
    try {
	store.forEachTiddler(function(store,tiddler) {
		if(tiddler && tiddler.tags) {
		    for(var ix=0; ix<tiddler.tags.length; ix++) {
			if(tiddler.tags[ix].indexOf(tagToSearchFor) == 0) {
			    try {
				CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler);
			    } catch (e) {
				displayMessage("Decryption of '"+tiddler.title+"' failed.");
				throw e;
			    }
			} // if(tiddler.tags
		    } // for
		} // if
	    }); // store.forEachTiddler
	displayMessage("All encrypted tiddlers have been decrypted" + (promptString != "" ? "for '"+promptString+"'" : ""));
    } catch (e) {
	if(e == "DecryptionFailed") {
	    return;
	}
    } // catch
    return;
};

store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin = store.getSaver().externalizeTiddler;
store.getSaver().externalizeTiddler = function(store, tiddler) {
    // Ok, got the tiddler, track down the passwordPrompt in the tags.
    // track down the Encrypt(passwordPrompt) tag
    if(tiddler && tiddler.tags) {
	for(var g=0; g<tiddler.tags.length; g++) {
	    var tag = tiddler.tags[g];
	    if(tag.indexOf("Encrypt(") == 0) {
		var lastBracket=tag.lastIndexOf(")");
		if(lastBracket >= 0) {
		    // Ok, tagged with Encrypt(passwordPrompt)
		    // extract the passwordPrompt name
		    var passwordPrompt=tag.substring(8,lastBracket);
		    // Ok, Encrypt this tiddler!
		    var decryptedSHA1 = Crypto.hexSha1Str(tiddler.text);
		    var password =  GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(passwordPrompt);
		    if(password) {
			var encryptedText = TEAencrypt(tiddler.text, password);
			encryptedText = StringToHext_TiddlerEncryptionPlugin(encryptedText);
			tiddler.text = "Encrypted("+decryptedSHA1+")\n"+encryptedText;
			// Replace the Tag with the Decrypt() tag
			tiddler.tags[g]="Decrypt("+passwordPrompt+")";
			// let the store know it's dirty
			store.setDirty(tiddler.title, true);
			// prevent searches on encrypted tiddlers, still nice to search on title though.
			if(config.options.chkExcludeEncryptedFromSearch == true) {
			    tiddler.tags.push("excludeSearch");
			}
			// prevent lists of encrypted tiddlers
			if(config.options.chkExcludeEncryptedFromLists == true) {
			    tiddler.tags.push("excludeLists");
			}
		    } else {
			// do not encrypt - no password entered
		    }
		    break;
		} // if (lastBracket...
	    } // if(tag.indexOf(...
	} // for(var g=0;...
    } // if(tiddler.tags...
    
    // Then, finally, do the save by calling the function we override.

    return store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin(store, tiddler);
};

function CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler) {
    if(tiddler && tiddler.tags) {
	for(var g=0; g<tiddler.tags.length; g++) {
	    var tag = tiddler.tags[g];
	    if(tag.indexOf("Decrypt(") == 0) {
		var lastBracket=tag.lastIndexOf(")");
		if(lastBracket >= 0) {
		    if(tiddler.text.substr(0,10) == "Encrypted(") {
			var closingSHA1Bracket = tiddler.text.indexOf(")");
			var decryptedSHA1 = tiddler.text.substring(10, closingSHA1Bracket);
			// Ok, tagged with Decrypt(passwordPrompt)
			// extract the passwordPrompt name
			var passwordPrompt=tag.substring(8,lastBracket);
			// Ok, Decrypt this tiddler!
			var decryptedText = tiddler.text.substr(closingSHA1Bracket+2);
			decryptedText = HexToString_TiddlerEncryptionPlugin(decryptedText);
                        // prompt("Decryption request for Tiddler '"+tiddler.title+"'");
			var password = GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(passwordPrompt);
			if(password) {
			    decryptedText = TEAdecrypt(decryptedText, password );
			    var thisDecryptedSHA1 = Crypto.hexSha1Str(decryptedText);
			    if(decryptedSHA1 == thisDecryptedSHA1) {
				tiddler.text = decryptedText;
				// Replace the Tag with the Encrypt() tag
				tiddler.tags[g]="Encrypt("+passwordPrompt+")";
				if(tiddler.tags[tiddler.tags.length-1] == 'excludeLists') {
				    // Remove exclude lists only if it's the last entry
				    // as it's automatically put there by encryption
				    tiddler.tags.length--;
				}
				if(tiddler.tags[tiddler.tags.length-1] == 'excludeSearch') {
				    // Remove exclude search only if it's the last entry
				    // as it's automatically put there by encryption
				    tiddler.tags.length--;
				}
			    } else {
				// Did not decrypt, discard the password from the cache
				config.encryptionPasswords[passwordPrompt] = null;
				config.encryptionReEnterPasswords = false;
				throw "DecryptionFailed";
			    }
			} else {
			    // no password supplied, dont bother trying to decrypt
			    config.encryptionReEnterPasswords = false;
			    throw "DecryptionFailed";
			}
		    } else {
			// Tagged as encrypted but not expected format, just leave it unchanged
		    }
		    break; // out of for loop
		} // if (lastBracket...
	    } // if(tag.indexOf(...
	} // for(var g=0;...
    } // if (tiddler && tags)
    return tiddler;
};

store.getTiddler_TiddlerEncryptionPlugin = store.getTiddler;
store.getTiddler = function(title) {
    var tiddler = store.getTiddler_TiddlerEncryptionPlugin(title);
    if(tiddler) { // shadow tiddlers are not expected to be encrypted.
	try {
	    return CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler);
	} catch (e) {
	    if(e == "DecryptionFailed") {
		var tiddler = store.getTiddler("DecryptionFailed");
		if(!tiddler) {
		    tiddler = new Tiddler();
		    tiddler.set(title,
				"<<EncryptionDecryptThis \"Decrypt\" \"Decrypt this tiddler\" \""+title+"\">>",
				config.views.wikified.shadowModifier,
				version.date,[],version.date);
		} 
		return tiddler;
	    } // if(e)
	} // catch
    } // if(tiddler) {
    return null;
};

store.getTiddlerText_TiddlerEncryptionPlugin = store.getTiddlerText;
store.getTiddlerText = function(title,defaultText) {
    // Simply retrieve the tiddler, normally, if it requires decryption, it will be decrypted
    var decryptedTiddler = store.getTiddler(title);
    if(decryptedTiddler) {
	return decryptedTiddler.text;
    }
    //Ok, rather than duplicate all the core code, the above code should fail if we reach here
    // let the core code take over.
    return  store.getTiddlerText_TiddlerEncryptionPlugin(title,defaultText);
};

// Given a prompt, search our cache to see if we have already entered the password.
// Can return null if the user enters nothing.
function MyPrompt_TiddlerEncryptionPlugin(promptString,defaultValue) {
    var thePassword = defaultValue;
    return prompt(promptString, defaultValue);
}

function GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString) {
    if(!config.encryptionPasswords[promptString]) {
	config.encryptionPasswords[promptString] = MyPrompt_TiddlerEncryptionPlugin("Enter password for '"+promptString+"' :", "");
    }
    return config.encryptionPasswords[promptString]; // may be null, prompt can be cancelled.
}

function GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(promptString) {
    if(config.encryptionReEnterPasswords) {
	if(config.options.chkCachePasswords == true) {
	    return GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString);
	} else {
	    config.encryptionPasswords[promptString] = MyPrompt_TiddlerEncryptionPlugin("Enter password for '"+promptString+"' :", "");
	    return config.encryptionPasswords[promptString];
	}
    } else {
	return;
    }
}

// Make the encrypted tiddlies look a little more presentable.
function StringToHext_TiddlerEncryptionPlugin(theString) {
    var theResult = "";
    for(var i=0; i<theString.length; i++) {
	var theHex = theString.charCodeAt(i).toString(16);
	if(theHex.length<2) {
	    theResult += "0"+theHex;
	} else {
	    theResult += theHex;
	}
	if(i && i % 32 == 0)
	    theResult += "\n";
    }
    return theResult;
}
function HexToString_TiddlerEncryptionPlugin(theString) {
    var theResult = "";
    for(var i=0; i<theString.length; i+=2) {
	if(theString.charAt(i) == "\n") {
	    i--;	// cause us to skip over the newline and resume
	    continue;
	}
	theResult += String.fromCharCode(parseInt(theString.substr(i, 2),16));
    }
    return theResult;
}

// http://www.movable-type.co.uk/scripts/tea-block.html
//
// TEAencrypt: Use Corrected Block TEA to encrypt plaintext using password
//             (note plaintext & password must be strings not string objects)
//
// Return encrypted text as string
//
function TEAencrypt(plaintext, password)
{
    if (plaintext.length == 0) return('');  // nothing to encrypt
    // 'escape' plaintext so chars outside ISO-8859-1 work in single-byte packing, but keep
    // spaces as spaces (not '%20') so encrypted text doesn't grow too long (quick & dirty)
    var asciitext = escape(plaintext).replace(/%20/g,' ');
    var v = strToLongs(asciitext);  // convert string to array of longs
    if (v.length <= 1) v[1] = 0;  // algorithm doesn't work for n<2 so fudge by adding a null
    var k = strToLongs(password.slice(0,16));  // simply convert first 16 chars of password as key
    var n = v.length;

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = 0;

    while (q-- > 0) {  // 6 + 52/n operations gives between 6 & 32 mixes on each word
        sum += delta;
        e = sum>>>2 & 3;
        for (var p = 0; p < n; p++) {
            y = v[(p+1)%n];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
            z = v[p] += mx;
        }
    }

    var ciphertext = longsToStr(v);

    return escCtrlCh(ciphertext);
}

//
// TEAdecrypt: Use Corrected Block TEA to decrypt ciphertext using password
//
function TEAdecrypt(ciphertext, password)
{
    if (ciphertext.length == 0) return('');
    var v = strToLongs(unescCtrlCh(ciphertext));
    var k = strToLongs(password.slice(0,16)); 

    var n = v.length;

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = q*delta;

    while (sum != 0) {
        e = sum>>>2 & 3;
        for (var p = n-1; p >= 0; p--) {
            z = v[p>0 ? p-1 : n-1];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
            y = v[p] -= mx;
        }
        sum -= delta;
    }

    var plaintext = longsToStr(v);

    // strip trailing null chars resulting from filling 4-char blocks:
    plaintext = plaintext.replace(/\0+$/,'');

    return unescape(plaintext);
}


// supporting functions

function strToLongs(s) {  // convert string to array of longs, each containing 4 chars
    // note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
    var l = new Array(Math.ceil(s.length/4));
    for (var i=0; i<l.length; i++) {
        // note little-endian encoding - endianness is irrelevant as long as 
        // it is the same in longsToStr() 
        l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) + 
               (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
    }
    return l;  // note running off the end of the string generates nulls since 
}              // bitwise operators treat NaN as 0

function longsToStr(l) {  // convert array of longs back to string
    var a = new Array(l.length);
    for (var i=0; i<l.length; i++) {
        a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF, 
                                   l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
    }
    return a.join('');  // use Array.join() rather than repeated string appends for efficiency
}

function escCtrlCh(str) {  // escape control chars etc which might cause problems with encrypted texts
    return str.replace(/[\0\t\n\v\f\r\xa0'"!]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
}

function unescCtrlCh(str) {  // unescape potentially problematic nulls and control characters
    return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
}

//}}}
<!--{{{-->
<div class='title' macro='view title'></div>
<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler  jump'></div>

<!--<div class='tagging' macro='tagging'></div>-->
<!--<div class='tagged' macro='tags'></div>-->
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>

<!--}}}-->
/%
|Name|VisitCounter|
|Source|http://www.TiddlyTools.com/#VisitCounter|
|Version|2.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|use cookies to track/show private, personal visit counter and timestamp of last visit|

This script tracks and displays a personal, private counter and the timestamps for your first visit, your most recent visit, and the total number of times you have visited a document.  This information is stored in local cookies, and is ONLY available for display in YOUR browser.  This data is not NOT tracked or aggregated across users, nor relayed or reported to anyone other than yourself, EVER.

Usage:
{{{<<tiddler VisitCounter with: counterID firsttimegreeting>>}}}
where:
* counterID (optional) - specifies a suffix to add to the visit tracking cookies for this document (enables tracking of multiple documents on a single domain, such as file://).  
* firsttimegreeting (optional) - message to display upon first visit to the document.  Subsequent visits report last visit timestamp and total visit count.

Cookies used to track your visit information:
	txtFirstVisit+id, txtLastVisit+id, txtVisitCount+id

The script also defines global config values that may be referenced later by other scripts:
	config.firstVisit, config.lastVisit, config.visitCount

!!!!!Revisions
<<<
2008.07.01 [2.1.0] simplified to inline script
2007.07.26 [2.0.0] re-written as plugin
2007.05.02 [1.0.0] initial release (as inline script, VisitCounter)
!end revisions

!outputFormat
This is your <html><hide linebreaks><a href="javascript:;"
	title="Reset personal visit counter"

	onclick="if (!confirm('Are you sure you want to reset your personal visit counter?')) return false;
		config.visitCount=config.options['txtVisitCount%0']=1;
		config.firstVisit=config.options['txtFirstVisit%0']=new Date();
		config.lastVisit=config.options['txtLastVisit%0']=new Date();
		saveOptionCookie('txtVisitCount%0');
		saveOptionCookie('txtFirstVisit%0');
		saveOptionCookie('txtLastVisit%0');
		var t=story.findContainingTiddler(this);
		if(t)story.refreshTiddler(t.getAttribute('tiddler'),null,true);
	">''%1 visit''</a></html> since %2. Your last visit was on %3.
!end outputFormat

%/<script>
	var out="";
	var id="";
	if ("$1"!="$"+"1") id="_$1";
	var greeting="";
	if ("$2"!="$"+"2") greeting="$2";

	if (config.firstVisit==undefined) { // only do this once per session
		// create the 'first visit' timestamp cookie
		if (!config.options["txtFirstVisit"+id] || !config.options["txtFirstVisit"+id].length) {
			config.options["txtFirstVisit"+id]=new Date();
			saveOptionCookie("txtFirstVisit"+id);
		}
		config.firstVisit=config.options["txtFirstVisit"+id];
	}

	if (config.lastVisit==undefined) { // only do this once per session
		config.lastVisit=config.options["txtLastVisit"+id];
		if (config.lastVisit==undefined) config.lastVisit="";
		config.options["txtLastVisit"+id]=new Date();
		saveOptionCookie("txtLastVisit"+id);
		var c=config.options["txtVisitCount"+id]?parseInt(config.options["txtVisitCount"+id]):0;
		config.visitCount=config.options["txtVisitCount"+id]=c+1;
		saveOptionCookie("txtVisitCount"+id);
	}

	// get and format # of visits
	var count=config.options["txtVisitCount"+id]; if (!count) count=1;
	var wordmap=['---','first','second','third','fourth','fifth','sixth','seventh','eighth','ninth'];
	var suffixmap=['th','st','nd','rd','th','th','th','th','th','th'];
	var digits=count.toString().substr(count.toString().length-2,2);
	if (count<10) count=wordmap[count];
	else if (digits>=10&&digits<=13) count=count+'th';
	else count=count+suffixmap[digits.substr(1,1)];

	var out=greeting; // initial greeting for first visit only
	if (config.lastVisit.length) {
		var first=new Date(config.firstVisit).formatString("MMM DDth YYYY");
		var last=new Date(config.lastVisit).formatString("MMM DDth YYYY at 0hh12:0mm:0ss am");

		out=store.getTiddlerText("VisitCounter##outputFormat").format([id,count,first,last])
	}
	return out;


</script>
{{textcenter{
[img(100%,auto)[Wave-body interactions| icon3b.jpg][Wave structure interaction, Cable Dynamics and Offshore Eng.]]<br>Wave-body interactions, Highly-flexible mooring systems, Offshore structures 
}}}

''MATLAB'' stands for Matrix Laboratory. It was originially developed by Cleve Moller in the 1970s. It was designed to do numerical computations and only recently has the capability of doing symbolic computation either through an added toolbox, the student version, or by talking to programs like Maple. 

One can use ''MATLAB'' as a simple calculator. It has many of the standard functions plus many other functions for matrix manipulation, plotting, linear algebra, programming and solving both algebraic and  differential equations. One can even design nice ~GUIs (Graphic User Interfaces), though this is generally a more advanced feature.

''MATLAB'' has a powerful scripting feature and users can define their own functions using the basic programming capabilities of ''MATLAB''.

<html><p>Use the tiddler's toolbar to edit this text with :</p><ul><li><p>EasyEditPlugin : click on <b>write</b> button.</p></li><li><p>FCKeditorPlugin : click on <b>wysiwyg</b> button.</p></li><li><p>ExternalizePlugin : click on <b>externalize</b> button<span style="font-weight: bold;">.&nbsp; </span><span style="color: rgb(255, 102, 0); font-weight: bold;">This requires :</span></p><ul><li><p><span style="font-weight: bold;">Firefox <br></span></p></li><li><p><span style="font-weight: bold;">"it's all text!"</span> Firefox extension and configuration (editor and hotkey)</p></li><li><p>[[plugin	configuration|ExternalizePlugin]], enter <span style="font-style: italic;">hotkey</span> and check <span style="font-style: italic;">file Extensions</span> is starting with .html (for this demo)</p></li></ul></li><li>Standard <span style="font-weight: bold;">edit </span>button to look at the resulting code.</li></ul><p>By example, you can use the following formats :</p><ul><li><p>Bullets list</p></li><li><p>Orderer list</p></li><li><p>Font <font color="#ff0000">color</font>, <font face="Times New Roman, serif">name</font>,	<font style="font-size: 15pt;" size="4">size</font>, ...</p></li><li><p><b>Bold</b>, <i>italic</i>, <u>underline</u>, <strike>strikethrough</strike></p></li><li><p>[[Links|EasyEditPlugin]]</p></li></ul></html>
renamed FCKeditorPlugin
/***
|!''Name:''|!easyFormat|
|''Description:''|the format command format selection according to your choice|
|''Version:''|0.1.0|
|''Date:''|13/01/2007|
|''Source:''|[[TWkd|http://yann.perrin.googlepages.com/twkd.html#easyFormat]]|
|''Author:''|[[Yann Perrin|YannPerrin]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.x|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
|''Requires:''|@@color:red;''E.A.S.E''@@|
***/
//{{{
config.commands.format = new TWkd.Ease('Format','format selection accordingly to chosen mode');
config.commands.format.addMode({
 name:'Bold',
 tooltip:'turns selection into bold text',
 operation:function(){
 config.commands.format.putInPlace("''"+TWkd.context.selection.content+"''",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Italic',
 tooltip:'turns selection into italic text',
 operation:function(){
 config.commands.format.putInPlace("//"+TWkd.context.selection.content+"//",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Underlined',
 tooltip:'turns selection into underlined text',
 operation:function(){
 config.commands.format.putInPlace("__"+TWkd.context.selection.content+"__",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Strikethrough',
 tooltip:'turns selection into striked text',
 operation:function(){
 config.commands.format.putInPlace("--"+TWkd.context.selection.content+"--",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Superscript',
 tooltip:'turns selection into superscript',
 operation:function(){
 config.commands.format.putInPlace("^^"+TWkd.context.selection.content+"^^",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Subscript',
 tooltip:'turns selection into subscript',
 operation:function(){
 config.commands.format.putInPlace("~~"+TWkd.context.selection.content+"~~",TWkd.context.selection);
 }
});
config.commands.format.addMode({
 name:'Highlight',
 tooltip:'highlight selection',
 operation:function(){
 config.commands.format.putInPlace("@@"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
//}}}