/***\n!Metadata:\n|''Name:''|ArchivedTimeline|\n|''Description:''|Timeline archived monthly.|\n|''Version:''|0.7.0|\n|''Date:''|Aug 25, 2007|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|\n|''~CoreVersion:''|2.0.11|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0|\n\n!Syntax:\n{{{<<timeline [modified|created [maxentries [dateFormate]]]>>}}}\n!Examples:\n{{{<<timeline>>}}}\n{{{<<timeline created 10>>}}}\n{{{<<timeline modified 10 "MMM DD, YYYY">>}}}\n\n!Revision History:\n|''Version''|''Date''|''Note''|\n|0.7.0|Jul 25, 2006|Accept a date format parameter|\n|0.6.3|Jan 14, 2007|Cleaned codes, Removed config.macros.timeline.slider and config.macros.timeline.onClickSlider|\n|0.6.2|Dec 10, 2006|Add monthFormat to display month format for Chinese|\n|0.6.1|Aug 12, 2006|A great effect on config.macros.timeline.slider for Firefox, thanks Bob McElrath|\n|0.6.0|Jul 25, 2006|Runs compatibly with TW 2.1.0 (rev #403+)|\n|0.5.2|Jun 21, 2006|Fixed bugs for dateFormat of TW 2.1|\n|~|~|Change default dateFormat to "0DD MMM, YYYY"|\n|0.5.1|Jun 04, 2006|Added config.macros.archivedTimeline.orderBy for localization|\n|0.5.0|Apr 19, 2006|Fixed bug for twice records of the same date ()|\n|~|~|Added Date.prototype.convertToLocalYYYYMMDDHHMM<<br>>in order to backward compatible with 2.0.6-|\n|0.4.0|Apr 03, 2006|Added new parameter, {{{<<timeline [sortfield] [maxentries]>>}}}|\n|~|~|Added config.options.txtTimelineMaxentries|\n|0.3.1|Feb 04, 2006|JSLint checked|\n|0.3.0|Feb 04, 2006|Fixed several missing variable declarations|\n|0.2.0|Dec 26, 2005|changed for the new feature of Macro timeline of TW 2.0.0 beta 6|\n|0.1.0|Nov 3, 2005|Initial release|\n\n!Code section:\n***/\n//{{{\nversion.extensions.archivedTimeline = {major: 0, minor: 7, revision: 0,\n date: new Date("Aug 26, 2007"),\n name: "ArchivedTimeline",\n type: "Macro",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n};\nconfig.options.txtTimelineMaxentries=0;\nconfig.macros.archivedTimeline = {\n tooltips: "Archives sorted by ",\n orderBy:{modified: "modified", created: "created"},\n monthFormat: "0DD MMM YYYY",\n dateFormat: "0DD MMM YYYY"\n};\nconfig.macros.timeline = config.macros.archivedTimeline;\n\nconfig.macros.timeline.handler = function(place,macroName,params) {\n var field = params[0] ? params[0] : "modified";\n\n place.appendChild(document.createTextNode(this.tooltips + this.orderBy[field]));\n var tiddlers = store.reverseLookup("tags","excludeLists",false,field);\n var lastMonth = ""; var lastDay = ""; var theText = "----\sn"; var i = 0;\n var last = (params[1])?params[1]:config.options.txtTimelineMaxentries;\n last = (isNaN(last)||last<1) ? 0:tiddlers.length-Math.min(tiddlers.length,parseInt(last));\n var dateFormat = params[2] ? params[2] : this.dateFormat;\n var cookie; var archives;\n for (var t=tiddlers.length-1; t>=last; t--) {\n var tiddler = tiddlers[t];\n var theMonth = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,6);\n var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);\n if(theMonth != lastMonth) {\n if (lastMonth === "") {\n lastMonth = theMonth;\n }\n else {\n place.appendChild(document.createElement('hr'));\n cookie = 'chktimeline'+(i++);\n archives = this.formatString(this.monthFormat, lastMonth);\n var panel = config.macros.slider.createSlider(place,cookie,archives,this.tooltips + archives);\n wikify(theText,panel);\n lastMonth = theMonth; theText = '----\sn';\n }\n }\n if(theDay != lastDay){\n theText += tiddler[field].formatString(dateFormat) + '\sn';\n lastDay = theDay; \n }\n theText += '* [[' + tiddler.title + ']]\sn';\n }\n place.appendChild(document.createElement('hr'));\n cookie = 'chktimeline'+(i++);\n archives = this.formatString(this.monthFormat, lastMonth);\n var panel = config.macros.slider.createSlider(place,cookie,archives,this.tooltips + archives);\n wikify(theText,panel);\n place.appendChild(document.createElement('hr'));\n};\n\nconfig.macros.timeline.formatString = function(template, yyyymm)\n{\n var dateString = new Date(yyyymm.substr(0,4)+'/'+yyyymm.substr(4,2)+'/01');\n template = template.replace(/DDD|0DD|DD/g,'');\n return dateString.formatString(template);\n};\nif (!Date.prototype.convertToLocalYYYYMMDDHHMM){\n Date.prototype.convertToLocalYYYYMMDDHHMM = function(){\n return(String.zeroPad(this.getFullYear(),4) + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + String.zeroPad(this.getHours(),2) + String.zeroPad(this.getMinutes(),2));\n }\n}\n//}}}\n
/***\n|''Name:''|CommentPlugin|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|Tim Morgan (modified by Bram Chen|\n|''Version:''|1.0.0|\n|''Date:''|Aug 25, 2007|\n|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|\n|''~CoreVersion:''|2.0.11|\n|''Description:''|Adds "comments" to any TiddlyWiki or adaptation.|\n|~|Used in conjunction with the RecentPlugin, one can have a decent forum environment.|\n\n''Translation sample 1:''\n{{{\nconfig.CommentPlugin.CPlingo = {\n dateFormat: "YYYY年0MM月0DD日 0hh:0mm:0ss",\n CommentInTitle: " 迴響 ",\n comments:"迴響",\n add:"回應 »",\n edit:"編輯",\n tooltips:"發表關於此文的相關意見",\n Title: "%0 迴響 %1",\n CommenteditTemplate: {yourName: "請簽名:", nickName: "(中英文暱稱)", comments: "留言內容:"}\n};\n}}}\n''Translation sample 2:''\n{{{\nconfig.CommentPlugin = {\n CPlingo:{\n dateFormat: "DD MMM YYYY 0hh:0mm:0ss",\n CommentInTitle: " Comment ",\n comments: "comments",\n add: "New Comment Here...",\n edit: "Edit",\n tooltips:" Create a new comment tiddler associated with this tiddler",\n Title: "%0 Comment %1",\n CommenteditTemplate: {yourName: "Your Name: ", nickName: "(nick name)", comments: "Comment: "}\n };\n}}}\n\n''Revision history:''\n* v1.0.0\n** Fixed bug, those tiddlers tagging with some other tiddlers and not tagged with only_on_tags would also be created a comment links with count 0.\n* v0.8.0 (Jan 17, 2007)\n** Some minor changes and bugs fixed (Bram)\n* v0.7.0 (Nov 09, 2006)\n** Minor changes, more easier to be translated (Bram)\n* v0.6.0 (Nov 09, 2006)\n** Runs compatibly with TW 2.1.0+ (Bram)\n* v0.5.0 (Jun 15, 2006)\n** Fixed bug for feature of CommentEditTemplate (bug reported by MilchFlasche, fixed by Bram)\n** Fixed bug in redefined TiddlyWiki.prototype.saveTiddler (Bram)\n* v0.4.0 (Jun 03, 2006) Added CommentEditTemplate (Bram)\n* v0.3.0 (Jun 01, 2006) Some minor changes for readOnly mode (Bram)\n* v0.2.0 (Apr 04, 2006) Fixed bug for only_on_tags (Bram)\n* v0.1.0 (Mar 13, 2006) Modified by Bram Chen.\n***/\n// //''Code section:''\n//{{{\nconfig.CommentPlugin = {\n CPlingo:{\n dateFormat: "DD MMM YYYY 0hh:0mm:0ss",\n CommentInTitle: " Comment ",\n comments: "comments",\n add: "New Comment Here...",\n edit: "Edit",\n tooltips: "Create a new comment tiddler associated with this tiddler",\n Title: "%0 Comment %1",\n CommenteditTemplate: {yourName: "Your Name: ", nickName: "(nick name)", comments: "Comment: "}\n },\n only_on_tags: ['Public'],\n not_on_tags: ['about'],\n // "true" or "false"...\n fold_comments: true,\n default_fold: true,\n max_comment_count: 500\n};\n\nvar CPlingo = config.CommentPlugin.CPlingo;\nconfig.CommentPlugin.only_on_tags.push(CPlingo.comments);\n\nfunction get_parent(tiddler){\n while(tiddler.isTagged(CPlingo.comments)){\n tiddler=store.fetchTiddler(tiddler.tags[0]);\n }\n return tiddler\n};\n\nfunction count_comments(title){\n var tagged=store.getTaggedTiddlers(title);\n var count=0;\n for(var i=0;i<tagged.length;i++){\n if(tagged[i].tags.contains(CPlingo.comments)){\n count+=count_comments(tagged[i].title)+1;\n }\n }\n return count\n};\nconfig.shadowTiddlers.ViewTemplate += "\sn<div class='comments' macro='comments'></div>";\n\nconfig.shadowTiddlers.CommentEditTemplate="<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler wikibar'></div><div class='title' macro='view title'></div><div class='editor' macro='edit tags' style='display:none;'></div><div class='GuestSign' >" + CPlingo.CommenteditTemplate.yourName + "<span macro='option txtUserName'></span>" + CPlingo.CommenteditTemplate.nickName + "<br />" + CPlingo.CommenteditTemplate.comments + "</div><div class='editor' macro='edit text'></div>";\nconfig.tiddlerTemplates[3]="CommentEditTemplate"; \nvar COMMENT_EDIT_TEMPLATE = 3;\n\nconfig.shadowTiddlers.CommentPluginStyle = '\sn/*{{{*/\sn.commentTags ul {list-style:none; padding-left:0px; margin: 0 0 3px 0;}\sn.commentTags li {display:inline; color:#999;}\sn.commentTags li a.button {color:#999;}\sn.comment {border-left:1px solid #ccc; margin-top:10px; margin-left:10px; padding:5px;}\sn.newCommentLink {padding-top:10px}\sn.tagging, .selected .tagging, .tiddler .tagging {display:none;}\sn.comment a.button {padding:0px; font-size:smaller; background-color:lightgray;}\sn.comments a.button {background-color:lightgray;}\sn/*}}}*/';\nconfig.shadowTiddlers.StyleSheet += '\sn[[CommentPluginStyle]]';\nconfig.macros.newCommentLink = {\n label: CPlingo.add,\n prompt: CPlingo.tooltips,\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n if(tiddler && store.tiddlerExists(tiddler.title) && !readOnly && (!window.zw || zw.loggedIn || zw.anonEdit)) {\n if(tiddler.tags.containsAny(config.CommentPlugin.not_on_tags) || !tiddler.tags.containsAny(config.CommentPlugin.only_on_tags))\n return;\n var onclick = function(e) {\n var e = (e)?e:window.event;\n var theTarget = resolveTarget(e);\n var tagxs = tiddler.title.split(CPlingo.CommentInTitle);\n var title = (tiddler.title.indexOf(CPlingo.CommentInTitle)!=-1)? tagxs[0] : tiddler.title;\n title = CPlingo.Title.format([title,(new Date()).formatString(CPlingo.dateFormat)]);\n var comment = store.createTiddler(title);\n comment.text = '';\n comment.tags = [tiddler.title, CPlingo.comments,'excludeLists'];\n readOnly = false;\n story.displayTiddler(theTarget, title, COMMENT_EDIT_TEMPLATE);\n readOnly = (window.location.protocol == "file:") ? false : config.options.chkHttpReadOnly;\n story.focusTiddler(title,"text");\n return false;\n }\n createTiddlyButton(place, this.label, this.prompt, onclick);\n }\n }\n};\nconfig.macros.comments = {\n dateFormat: CPlingo.dateFormat,\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n if(tiddler.title==CPlingo.comments) return;\n var comments = store.getTaggedTiddlers(tiddler.title, 'created');\n var count = count_comments(tiddler.title);\n if(count>0 && !tiddler.tags.contains(CPlingo.comments) && config.CommentPlugin.fold_comments) {\n var show = createTiddlyElement(place, 'p');\n show.innerHTML = '<a href="#" onclick="var e=document.getElementById(\s'comments'+tiddler.title+'\s');e.style.display=e.style.display==\s'block\s'?\s'none\s':\s'block\s';return false;">' + CPlingo.comments +'('+count+') »</a>';\n }\n var place = createTiddlyElement(place, 'div', 'comments'+tiddler.title, 'comments');\n if(count>0 && !tiddler.tags.contains(CPlingo.comments) && config.CommentPlugin.fold_comments && config.CommentPlugin.default_fold)\n place.style.display = 'none';\n else\n place.style.display = 'block';\n for(var i=0; i<comments.length; i++) {\n if(!comments[i].tags.contains(CPlingo.comments))continue;\n var container = createTiddlyElement(place, 'div', null, 'comment');\n var title = createTiddlyElement(container, 'strong');\n var link = createTiddlyLink(title, comments[i].modifier, true);\n createTiddlyElement(title, 'span', null, null, ', '+comments[i].created.formatString(this.dateFormat));\n/* ## remove editable option for security concern\n if(comments[i].modifier == config.options.txtUserName) {\n createTiddlyElement(title, 'span', null, null, ' (');\n var edit = createTiddlyLink(title, comments[i].title);\n edit.innerHTML = CPlingo.edit;\n createTiddlyElement(title, 'span', null, null, ')');\n }\n*/\n wikify('\sn'+comments[i].text+'\sn',container);\n config.macros.comments.handler(container,null,null,null,null,comments[i]);\n }\n readOnly = false;\n config.macros.newCommentLink.handler(place,null,null,null,null,tiddler);\n// wikify('<'+'<newCommentLink>>',place);\n readOnly = (window.location.protocol == "file:") ? false : config.options.chkHttpReadOnly;\n }\n};\nvar CPCloseTiddlers = [];\nTiddlyWiki.prototype.CommentPlugin_saveTiddler = TiddlyWiki.prototype.saveTiddler;\nTiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags) {\n tags=(!window.zw && typeof tags == "string") ? tags.readBracketedList() : tags;\n if(tags.contains(CPlingo.comments)){\n newBody=newBody.htmlDecode(); // comment this line, for working with HTMLAreaPackage\n newBody=newBody.substr(0,config.CommentPlugin.max_comment_count);\n newBody=newBody.htmlEncode(); // comment this line, for working with HTMLAreaPackage\n }\n var t = this.CommentPlugin_saveTiddler(title,newTitle,newBody,modifier,modified,tags);\n if(tags.contains(CPlingo.comments)) {\n var original = config.CommentPlugin.default_fold;\n config.CommentPlugin.default_fold = false;\n// story.refreshTiddler(get_parent(t).title, DEFAULT_VIEW_TEMPLATE, true);\n story.refreshTiddler(t.tags[0].split(CPlingo.CommentInTitle)[0], DEFAULT_VIEW_TEMPLATE, true);\n config.CommentPlugin.default_fold = original;\n CPCloseTiddlers.push(newTitle);\n setTimeout("story.closeTiddler(CPCloseTiddlers.pop(), true)", 500);\n }\n return t;\n};\nStory.prototype.chooseTemplateForTiddler = function(title,template)\n{\n if(!template)\n template = DEFAULT_VIEW_TEMPLATE;\n if(template == DEFAULT_VIEW_TEMPLATE\n || template == DEFAULT_EDIT_TEMPLATE\n || template == COMMENT_EDIT_TEMPLATE)\n template = config.tiddlerTemplates[template];\n return template;\n};\n//}}}
/***\n|''Name:''|CommentTabPlugin|\n|''Source:''|[[TiddlyWiki-zh|http://tiddlywiki-zh.googlecode.com/svn/trunk/contributors/BramChen/locales/plugins/]]|\n|''Requires:''|[[CommentPlugin|http://sourceforge.net/project/showfiles.php?group_id=150646]]|\n|''Descriptions:''|Breaks the Timeline tab into "Tiddlers" and "Comments".|\n***/\n//{{{\nfunction in_array(item, arr){for(var i=0;i<arr.length;i++)if(item==arr[i])return true};\nfunction get_parent(tiddler){while(tiddler && in_array(config.CommentPlugin.CPlingo.comments, tiddler.tags)) tiddler=store.fetchTiddler(tiddler.tags[0]);return tiddler};\nconfig.options.txtTimelineTab = 'timelineTab'; // huh?\nconfig.shadowTiddlers.TabTimelineTiddlers = config.shadowTiddlers.TabTimeline;\nconfig.shadowTiddlers.TabTimeline = "<<tabs txtTimelineTab Tiddlers Tiddlers TabTimelineTiddlers "+ config.CommentPlugin.CPlingo.comments + config.CommentPlugin.CPlingo.CommentInTitle + " TabTimelineComments>>";\nconfig.shadowTiddlers.TabTimelineComments = "<<tiddlerComments>>";\n\nconfig.macros.tiddlerComments = {\n dateFormat: 'DD MMM YYYY',\n handler: function(place,macroName,params)\n {\n var field = params[0] ? params[0] : "modified";\n var comments = store.reverseLookup("tags",CPlingo.comments,true,field);\n var lastDay = "";\n for (var c=comments.length-1; c>=0; c--)\n {\n if(comments[c].tags.length == 0) continue;\n var tiddler = get_parent(comments[c]);\n if(!tiddler) continue;\n var theDay = comments[c][field].convertToLocalYYYYMMDDHHMM().substr(0,8);\n if(theDay != lastDay)\n {\n var theDateList = document.createElement("ul");\n place.appendChild(theDateList);\n createTiddlyElement(theDateList,"li",null,"listTitle",comments[c][field].formatString(this.dateFormat));\n lastDay = theDay;\n }\n var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);\n var link = createTiddlyLink(place,comments[c].title);\n link.innerHTML = comments[c].modifier + ' on ' + tiddler.title;\n link.setAttribute("tiddlyLink",tiddler.title);\n theDateListItem.appendChild(link);\n }\n }\n};\n//}}}
/***\n''Name:'' GenRssPlugin\n''Source:'' http://www.sourceforge.net/projects/ptw/\n''Author:'' BramChen\n''Type:'' Plugin\n''Description:''\n<<<\n*This plugin add a "xml-stylesheet" processing to the rss file generated by TW.\n*Required: \n** rssfeed.xsl\n** rssfeed.css\n** xsl.css\n*if 'config.options.txtGenRssTags' is empty then the outputs limited to 'config.numRssItems' except tiddlers taged with 'excludeLists'.\n*you can add the macro {{{<<option txtGenRssTags>>}}} to some configure tiddler, eg 'AdvancedOptions' for changing the tag list,\n*and add {{{<<option txtRssItems>>}}} to change number of rsfeed item.\n<<<\n''Revision History:''\n<<<\nv0.2.0 (Mar 30 2006)\n* add a new feature that rssfeed limited to tiddlers taged with the tag list specified in 'config.options.txtGenRssTags'.\n* add config.options.txtRssItems.\n* if it's empty then the outputs limited to 'config.numRssItems' except tiddlers taged with 'excludeLists'.\n* you can add the macro {{{<<option txtGenRssTags>>}}} to some configure tiddler, eg 'AdvancedOptions' for changing the tag list.\nv0.1.1 (Feb 04 2006)\n* JSLint checked\nv0.1.0 (Feb 1, 2006) \n* initial release\n<<<\n***/\n// //''Code section:''\n//{{{\nversion.extensions.genRss = {major: 0, minor: 2, revision: 0,\n date: new Date("Mar 30, 2006"),\n info: {\n type: "Macro",\n name: "GenRssPlugin",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n }\n};\n\nwindow.generateRss_ori = window.generateRss;\n\nconfig.options.txtGenRssTags = "";\nconfig.options.txtRssItems = "20";\n\nwindow.generateRss = function () {\n var rssTags = config.options.txtGenRssTags.readBracketedList();\n var numRssItems = config.options.txtRssItems;\n var s = [];\n var d = new Date();\n var u = store.getTiddlerText("SiteUrl",null);\n // Assemble the header\n s.push("<" + "?xml version=\s"1.0\s" encoding=\s"utf-8\s"?" + ">");\n s.push("<" + "?xml-stylesheet type=\s"text/xsl\s" href=\s"rss/rssfeed.xsl\s"?" +">");\n s.push("<" + "?xml-stylesheet type=\s"text/css\s" href=\s"rss/rssfeed.css\s"?" +">");\n s.push("<" + "rss version=\s"2.0\s">");\n s.push("<channel>");\n s.push("<title>" + wikifyPlain("SiteTitle").htmlEncode() + "</title>");\n if(u)\n s.push("<link>" + u.htmlEncode() + "</link>");\n s.push("<description>" + wikifyPlain("SiteSubtitle").htmlEncode() + "</description>");\n s.push("<language>en-us</language>");\n s.push("<copyright>Copyright " + d.getFullYear() + " " + config.options.txtUserName.htmlEncode() + "</copyright>");\n s.push("<pubDate>" + d.toGMTString() + "</pubDate>");\n s.push("<lastBuildDate>" + d.toGMTString() + "</lastBuildDate>");\n s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");\n s.push("<generator>TiddlyWiki " + version.major + "." + version.minor + "." + version.revision + "</generator>");\n // The body\n var tiddlers = store.getTiddlers("modified","excludeLists");\n var n = numRssItems > tiddlers.length ? 0 : tiddlers.length-numRssItems;\n for (var t=tiddlers.length-1; t>=n; t--){\n var f=(rssTags.length===0);\n for (var i = 0; i<rssTags.length; i++){\n if (tiddlers[t].tags.find(rssTags[i])!=null){f=true;break;}\n }\n if (f){s.push(tiddlers[t].saveToRss(u));}\n }\n // And footer\n s.push("</channel>");\n s.push("</rss>");\n // Save it all\n return s.join("\sn");\n};\n//}}}
/***\n|''Name:''|LoadExtPlugin|\n|''Description:''|LoadExtPlugin allows you to load external extensions from the file lists (named .js) within those tiddlers taged with "ExtList".|\n|''Version:''|1.8.0|\n|''Date:''|Apr 30, 2007|\n|''Source:''|http://www.sourceforge.net/projects/ptw/|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License]]|\n|''CoreVersion:''|2.1.0|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0|\n\n+++!^[Revision History:]\nv1.8.0 (Apr 30 2007)\n*config.macros.loadExt support to load singgle external script by using {{{<<loadExt '/pathto/scriptfile.js'>>}}}\n*Ensure LoadExtPlugin loading itself and/or loadling scripts after core has been loaded with external core js and itself|\nv1.7.2 (Sep 28 2006)\n*Fixed bugs on IE\nv1.7.1 (30 Aug 2006)\n* Changed rule check of ExtList\nv1.7.0 (20 Jul 2006)\n* Runs compatibly with TW 2.1.0 (rev #403+)\nv1.6.0 (13 Jul 2006)\n* Fixed bugs in refreshCode and config.macros.loadExt.loadScripts on IE\n* Runs compatibly with TW 2.1.0 (rev #359+)\nv1.5.2 (21 Jun 2006)\n* minor changes for XHTML compliant\nv1.5.1 (26 Feb 2006)\n* JSLint checked\nv1.5.0 (02 Feb 2006)\n* add new function config.macros.loadExt.LoadScripts(), keep all variables to be local, thanks Udo.\n* Fixed several missing variable declarations\nv1.4.0 (20 Jan 2006)\n* refreshCode() improved.\nv1.3.0 (14 Jan 2006) \n* strip startup error massage for IE\nv1.2.0 (13 Jan 2006) \n* TiddlyWiki version 2.0.0 or above required.\n* refreshCode() improved.\nv1.1.0 (10 Jan 2006)\n* To make the extensions list handling more robust, thanks Udo.\n* Fix bugs for multi-tiddlers tagged with ExtList\nv1.0.0 (07 Jan 2006) \n* Combine the RefreshExt code and LoadExtPlugin, and also make TW 1.2 to be backward compatible, thanks Udo.\n* Globle function refreshCode() added, and reserve the refreshExt macro.\n* Fix a minor bug for variable "scriptfile".\nv0.3.0 (29 Dec 2005)\n* macro refreshExt modified to refresh formatter\nv0.2.0 (24 Nov 2005)\n* macro refreshExt modified for TW 1.2.39 beta 2 and above\nv0.1.0 (25 Sep 2005) \n* initial release\n===\n\n!''Code section:''\n***/\n//{{{\nversion.extensions.loadExt = {major: 1, minor: 8, revision: 0,\n date: new Date("Apr 30, 2007"),\n name: "LoadExtPlugin",\n type: "Plugin",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n};\n\nconfig.macros.loadExt = {};\nconfig.macros.loadExt.handler = function(place,macroName,params){\n if (params[0])\n this.loadScriptFile(params[0]);\n else\n this.loadScripts();\n};\n\nconfig.macros.loadExt.loadScriptFile = function(scriptfile){\n var scriptfile = scriptfile.trim();\n if (scriptfile.length < 2 || scriptfile.substr(0,2) == "//" || scriptfile.indexOf(".js") == -1){\n return;\n }\n // displayMessage("loaded: "+ scriptfile);\n var n = document.createElement("script");\n n.type = "text/javascript";\n n.src = scriptfile;\n document.getElementsByTagName("head")[0].appendChild(n);\n};\n\nconfig.macros.loadExt.loadScripts = function() {\n var extTag = "ExtList";\n var str = ""; var scripts = [];\n var tiddlers = store.getTaggedTiddlers(extTag);\n for(var s=0 ; s<tiddlers.length; s++){\n str += store.getRecursiveTiddlerText(tiddlers[s].title)+"\sn";\n }\n scripts = str.replace(/[;\sr]/mg,"\sn").split("\sn");\n for (var i=0; i<scripts.length-1; i++) {\n this.loadScriptFile(scripts[i]);\n }\n\n if (config.browser.isIE){\n// setTimeout(function(){window.refreshCode();return false;},500);\n var lerInterval = setInterval(function(){if(formatter) {clearInterval(lerInterval); window.refreshCode();};},100);\n }\n else {\n var theCodes = "//<![CDATA[\snwindow.refreshCode();//]]>";\n n = document.createElement("script");\n n.type = "text/javascript";\n n.appendChild(document.createTextNode(theCodes));\n document.getElementsByTagName("head")[0].appendChild(n);\n this.refreshCodeInserted = true;\n }\n};\n\nwindow.refreshCode = function (){\n formatter = new Formatter(config.formatters);\n story.forEachTiddler(function(title,e){story.refreshTiddler(title,DEFAULT_VIEW_TEMPLATE,true);});\n refreshDisplay();\n return false;\n}\n\n// setTimeout(function(){config.macros.loadExt.loadScripts();return false;},500);\nvar loadextpluginInterval = setInterval(function(){if(formatter) {clearInterval(loadextpluginInterval); if(!config.macros.loadExt.refreshCodeInserted) config.macros.loadExt.loadScripts();}},100);\n//}}}
/***\n|Name|NestedSlidersPlugin|\n|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|\n|Version|2.3.1|\n|Author|Eric Shulman - ELS Design Studios|\n|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides|Slider.prototype.stop|\n|Description|show content in nest-able 'slider' or 'floating' panels, without needing to create separate tiddlers for each panel|\n\n!!!!!Configuration\n<<<\nEnable animation for slider panels\n<<option chkFloatingSlidersAnimate>> allow sliders to animate when opening/closing\n>(note: This setting is in //addition// to the general option for enabling/disabling animation effects:\n><<option chkAnimate>> enable animations (entire document)\n>For slider animation to occur, you must also allow animation in general.\n\nDebugging messages for 'lazy sliders' deferred rendering:\n<<option chkDebugLazySliderDefer>> show debugging alert when deferring slider rendering\n<<option chkDebugLazySliderRender>> show debugging alert when deferred slider is actually rendered\n<<<\n!!!!!Usage\n<<<\nWhen installed, this plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content. Use {{{+++}}} and {{{===}}} to delimit the slider content. You can also 'nest' these sliders as deep as you like (see complex nesting example below), so that expandable 'tree-like' hierarchical displays can be created. This is most useful when converting existing in-line text content to create in-line annotations, footnotes, context-sensitive help, or other subordinate information displays.\n\nAdditional optional syntax elements let you specify\n*default to open\n*cookiename\n*heading level\n*floater (with optional CSS width value)\n*transient display (clicking elsewhere closes panel)\n*custom class/label/tooltip/accesskey\n*alternate label/tooltip (displayed when panel is open)\n*panelID (for later use with {{{<<DOM>>}}} macro. See [[DOMTweaksPlugin]])\n*automatic blockquote style on panel\n*deferred rendering of panel content\nThe complete syntax, using all options, is:\n//{{{\n++++(cookiename)!!!!!^width^*{{class{[label=key|tooltip][altlabel|alttooltip]}}}#panelID:>...\ncontent goes here\n===\n//}}}\nwhere:\n* {{{+++}}} (or {{{++++}}}) and {{{===}}}<br>marks the start and end of the slider definition, respectively. When the extra {{{+}}} is used, the slider will be open when initially displayed.\n* {{{(cookiename)}}}<br>saves the slider opened/closed state, and restores this state whenever the slider is re-rendered.\n* {{{!}}} through {{{!!!!!}}}<br>displays the slider label using a formatted headline (Hn) style instead of a button/link style\n* {{{^width^}}} (or just {{{^}}})<br>makes the slider 'float' on top of other content rather than shifting that content downward. 'width' must be a valid CSS value (e.g., "30em", "180px", "50%", etc.). If omitted, the default width is "auto" (i.e., fit to content)\n* {{{"*"}}} //(without the quotes)//<br>denotes "transient display": when a click occurs elsewhere in the document, the slider/floating panel will be automatically closed. This is useful for creating 'pulldown menus' that automatically go away after they are used.\n* """{{class{[label=key|tooltip][altlabel|alttooltip]}}}"""<br>uses label/tooltip/accesskey. """{{class{...}}}""", """=key""", """|tooltip""" and """[altlabel|alttooltip]""" are optional. 'class' is any valid CSS class name, used to style the slider label text. 'key' must be a ''single letter only''. altlabel/alttooltip specifiy alternative label/tooltip for use when slider/floating panel is displayed.\n* {{{#panelID:}}}<br>defines a unique DOM element ID that is assigned to the panel element used to display the slider content. This ID can then be used later to reposition the panel using the {{{<<DOM move id>>}}} macro (see [[DOMTweaksPlugin]]), or to access/modify the panel element through use of {{{document.getElementById(...)}}}) javascript code in a plugin or inline script.\n* {{{">"}}} //(without the quotes)//<br>automatically adds blockquote formatting to slider content\n* {{{"..."}}} //(without the quotes)//<br>defers rendering of closed sliders until the first time they are opened. //Note: deferred rendering may produce unexpected results in some cases. Use with care.//\n\n//Note: to make slider definitions easier to read and recognize when editing a tiddler, newlines immediately following the {{{+++}}} 'start slider' or preceding the {{{===}}} 'end slider' sequence are automatically supressed so that excess whitespace is eliminated from the output.//\n<<<\n!!!!!Examples\n<<<\nsimple in-line slider: \n{{{\n+++\n content\n===\n}}}\n+++\n content\n===\n----\nuse a custom label and tooltip: \n{{{\n+++[label|tooltip]\n content\n===\n}}}\n+++[label|tooltip]\n content\n===\n----\ncontent automatically blockquoted: \n{{{\n+++>\n content\n===\n}}}\n+++>\n content\n===\n----\nall options combined //(default open, cookie, heading, sized floater, transient, class, label/tooltip/key, blockquoted, deferred)//\n{{{\n++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...\n content\n===\n}}}\n++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...\n content\n===\n----\ncomplex nesting example:\n{{{\n+++[get info...=I|click for information or press Alt-I]\n put some general information here,\n plus a floating panel with more specific info:\n +++^10em^[view details...|click for details]\n put some detail here, which could in turn contain a transient panel,\n perhaps with a +++^25em^*[glossary definition]explaining technical terms===\n ===\n===\n}}}\n+++[get info...=I|click for information or press Alt-I]\n put some general information here,\n plus a floating panel with more specific info:\n +++^10em^[view details...|click for details]\n put some detail here, which could in turn contain a transient panel,\n perhaps with a +++^25em^*[glossary definition]explaining technical terms===\n ===\n===\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''NestedSlidersPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2007.07.26 - 2.3.1'' in document.onclick(), propagate return value from hijacked core click handler to consume OR bubble up click as needed. Fixes "IE click disease", whereby nearly every mouse click causes a page transition.\n''2007.07.20 - 2.3.0'' added syntax for setting panel ID (#panelID:). This allows individual slider panels to be repositioned within tiddler content simply by giving them a unique ID and then moving them to the desired location using the {{{<<DOM move id>>}}} macro.\n''2007.07.19 - 2.2.0'' added syntax for alttext and alttip (button label and tooltip to be displayed when panel is open)\n''2007.07.14 - 2.1.2'' corrected use of 'transient' attribute in IE to prevent (non-recursive) infinite loop\n''2007.07.12 - 2.1.0'' replaced use of "*" for 'open/close on rollover' (which didn't work too well). "*" now indicates 'transient' panels that are automatically closed if a click occurs somewhere else in the document. This permits use of nested sliders to create nested "pulldown menus" that automatically disappear after interaction with them has been completed. Also, in onClickNestedSlider(), use "theTarget.sliderCookie", instead of "this.sliderCookie" to correct cookie state tracking when automatically dismissing transient panels.\n''2007.06.10 - 2.0.5'' add check to ensure that window.adjustSliderPanel() is defined before calling it (prevents error on shutdown when mouse event handlers are still defined)\n''2007.05.31 - 2.0.4'' add handling to invoke adjustSliderPanel() for onmouseover events on slider button and panel. This allows the panel position to be re-synced when the button position shifts due to changes in unrelated content above it on the page. (thanks to Harsha for bug report)\n''2007.03.30 - 2.0.3'' added chkFloatingSlidersAnimate (default to FALSE), so that slider animation can be disabled independent of the overall document animation setting (avoids strange rendering and focus problems in floating panels)\n''2007.03.01 - 2.0.2'' for TW2.2+, hijack Morpher.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends\n''2007.03.01 - 2.0.1'' in hijack for Slider.prototype.stop, use apply() to pass params to core function\n|please see [[NestedSlidersPluginHistory]] for additional revision details|\n''2005.11.03 - 1.0.0'' initial public release\n<<<\n!!!!!Credits\n<<<\nThis feature was implemented by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]] with initial research and suggestions from RodneyGomes, GeoffSlocock, and PaulPetterson.\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.nestedSliders = {major: 2, minor: 3, revision: 1, date: new Date(2007,7,26)};\n//}}}\n\n//{{{\n// options for deferred rendering of sliders that are not initially displayed\nif (config.options.chkDebugLazySliderDefer==undefined) config.options.chkDebugLazySliderDefer=false;\nif (config.options.chkDebugLazySliderRender==undefined) config.options.chkDebugLazySliderRender=false;\nif (config.options.chkFloatingSlidersAnimate==undefined) config.options.chkFloatingSlidersAnimate=false;\n\n// default styles for 'floating' class\nsetStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \s\n background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");\n//}}}\n\n//{{{\nconfig.formatters.push( {\n name: "nestedSliders",\n match: "\s\sn?\s\s+{3}",\n terminator: "\s\ss*\s\s={3}\s\sn?",\n lookahead: "\s\sn?\s\s+{3}(\s\s+)?(\s\s([^\s\s)]*\s\s))?(\s\s!*)?(\s\s^(?:[^\s\s^\s\s*\s\s[\s\s>]*\s\s^)?)?(\s\s*)?(?:\s\s{\s\s{([\s\sw]+[\s\ss\s\sw]*)\s\s{)?(\s\s[[^\s\s]]*\s\s])?(\s\s[[^\s\s]]*\s\s])?(?:\s\s}{3})?(\s\s#[^:]*\s\s:)?(\s\s>)?(\s\s.\s\s.\s\s.)?\s\ss*",\n handler: function(w)\n {\n lookaheadRegExp = new RegExp(this.lookahead,"mg");\n lookaheadRegExp.lastIndex = w.matchStart;\n var lookaheadMatch = lookaheadRegExp.exec(w.source)\n if(lookaheadMatch && lookaheadMatch.index == w.matchStart)\n {\n // var defopen=lookaheadMatch[1]\n // var cookiename=lookaheadMatch[2]\n // var header=lookaheadMatch[3]\n // var panelwidth=lookaheadMatch[4]\n // var transient=lookaheadMatch[5]\n // var class=lookaheadMatch[6]\n // var label=lookaheadMatch[7]\n // var openlabel=lookaheadMatch[8]\n // var panelID=lookaheadMatch[9]\n // var blockquote=lookaheadMatch[10]\n // var deferred=lookaheadMatch[11]\n\n // location for rendering button and panel\n var place=w.output;\n\n // default to closed, no cookie, no accesskey, no alternate text/tip\n var show="none"; var cookie=""; var key="";\n var closedtext=">"; var closedtip="";\n var openedtext="<"; var openedtip="";\n\n // extra "+", default to open\n if (lookaheadMatch[1]) show="block";\n\n // cookie, use saved open/closed state\n if (lookaheadMatch[2]) {\n cookie=lookaheadMatch[2].trim().slice(1,-1);\n cookie="chkSlider"+cookie;\n if (config.options[cookie]==undefined)\n { config.options[cookie] = (show=="block") }\n show=config.options[cookie]?"block":"none";\n }\n\n // parse label/tooltip/accesskey: [label=X|tooltip]\n if (lookaheadMatch[7]) {\n var parts=lookaheadMatch[7].trim().slice(1,-1).split("|");\n closedtext=parts.shift();\n if (closedtext.substr(closedtext.length-2,1)=="=") \n { key=closedtext.substr(closedtext.length-1,1); closedtext=closedtext.slice(0,-2); }\n openedtext=closedtext;\n if (parts.length) closedtip=openedtip=parts.join("|");\n else { closedtip="show "+closedtext; openedtip="hide "+closedtext; }\n }\n\n // parse alternate label/tooltip: [label|tooltip]\n if (lookaheadMatch[8]) {\n var parts=lookaheadMatch[8].trim().slice(1,-1).split("|");\n openedtext=parts.shift();\n if (parts.length) openedtip=parts.join("|");\n else openedtip="hide "+openedtext;\n }\n\n var title=show=='block'?openedtext:closedtext;\n var tooltip=show=='block'?openedtip:closedtip;\n\n // create the button\n if (lookaheadMatch[3]) { // use "Hn" header format instead of button/link\n var lvl=(lookaheadMatch[3].length>6)?6:lookaheadMatch[3].length;\n var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,lookaheadMatch[6],title);\n btn.onclick=onClickNestedSlider;\n btn.setAttribute("href","javascript:;");\n btn.setAttribute("title",tooltip);\n }\n else\n var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,lookaheadMatch[6]);\n btn.innerHTML=title; // enables use of HTML entities in label\n\n // set extra button attributes\n btn.setAttribute("closedtext",closedtext);\n btn.setAttribute("closedtip",closedtip);\n btn.setAttribute("openedtext",openedtext);\n btn.setAttribute("openedtip",openedtip);\n btn.sliderCookie = cookie; // save the cookiename (if any) in the button object\n btn.defOpen=lookaheadMatch[1]!=null; // save default open/closed state (boolean)\n btn.keyparam=key; // save the access key letter ("" if none)\n if (key.length) {\n btn.setAttribute("accessKey",key); // init access key\n btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus\n }\n btn.onmouseover=function(event) // mouseover on button aligns floater position with button\n { if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this,this.sliderPanel,this.sliderPanel.className); }\n\n // create slider panel\n var panelClass=lookaheadMatch[4]?"floatingPanel":"sliderPanel";\n var panelID=lookaheadMatch[9]; if (panelID) panelID=panelID.slice(1,-1); // trim off delimiters\n var panel=createTiddlyElement(place,"div",panelID,panelClass,null);\n panel.button = btn; // so the slider panel know which button it belongs to\n btn.sliderPanel=panel; // so the button knows which slider panel it belongs to\n panel.defaultPanelWidth=(lookaheadMatch[4] && lookaheadMatch[4].length>2)?lookaheadMatch[4].slice(1,-1):"";\n panel.setAttribute("transient",lookaheadMatch[5]=="*"?"true":"false");\n panel.style.display = show;\n panel.style.width=panel.defaultPanelWidth;\n panel.onmouseover=function(event) // mouseover on panel aligns floater position with button\n { if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this.button,this,this.className); }\n\n // render slider (or defer until shown) \n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n if ((show=="block")||!lookaheadMatch[11]) {\n // render now if panel is supposed to be shown or NOT deferred rendering\n w.subWikify(lookaheadMatch[10]?createTiddlyElement(panel,"blockquote"):panel,this.terminator);\n // align floater position with button\n if (window.adjustSliderPos) window.adjustSliderPos(place,btn,panel,panelClass);\n }\n else {\n var src = w.source.substr(w.nextMatch);\n var endpos=findMatchingDelimiter(src,"+++","===");\n panel.setAttribute("raw",src.substr(0,endpos));\n panel.setAttribute("blockquote",lookaheadMatch[10]?"true":"false");\n panel.setAttribute("rendered","false");\n w.nextMatch += endpos+3;\n if (w.source.substr(w.nextMatch,1)=="\sn") w.nextMatch++;\n if (config.options.chkDebugLazySliderDefer) alert("deferred '"+title+"':\sn\sn"+panel.getAttribute("raw"));\n }\n }\n }\n }\n)\n\n// TBD: ignore 'quoted' delimiters (e.g., "{{{+++foo===}}}" isn't really a slider)\nfunction findMatchingDelimiter(src,starttext,endtext) {\n var startpos = 0;\n var endpos = src.indexOf(endtext);\n // check for nested delimiters\n while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {\n // count number of nested 'starts'\n var startcount=0;\n var temp = src.substring(startpos,endpos-1);\n var pos=temp.indexOf(starttext);\n while (pos!=-1) { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }\n // set up to check for additional 'starts' after adjusting endpos\n startpos=endpos+endtext.length;\n // find endpos for corresponding number of matching 'ends'\n while (startcount && endpos!=-1) {\n endpos = src.indexOf(endtext,endpos+endtext.length);\n startcount--;\n }\n }\n return (endpos==-1)?src.length:endpos;\n}\n//}}}\n\n//{{{\nwindow.onClickNestedSlider=function(e)\n{\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n var theLabel = theTarget.firstChild.data;\n var theSlider = theTarget.sliderPanel\n var isOpen = theSlider.style.display!="none";\n\n // toggle label\n theTarget.innerHTML=isOpen?theTarget.getAttribute("closedText"):theTarget.getAttribute("openedText");\n // toggle tooltip\n theTarget.setAttribute("title",isOpen?theTarget.getAttribute("closedTip"):theTarget.getAttribute("openedTip"));\n\n // deferred rendering (if needed)\n if (theSlider.getAttribute("rendered")=="false") {\n if (config.options.chkDebugLazySliderRender)\n alert("rendering '"+theLabel+"':\sn\sn"+theSlider.getAttribute("raw"));\n var place=theSlider;\n if (theSlider.getAttribute("blockquote")=="true")\n place=createTiddlyElement(place,"blockquote");\n wikify(theSlider.getAttribute("raw"),place);\n theSlider.setAttribute("rendered","true");\n }\n // show/hide the slider\n if(config.options.chkAnimate && (theSlider.className!='floatingPanel' || config.options.chkFloatingSlidersAnimate))\n anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n theSlider.style.display = isOpen ? "none" : "block";\n // reset to default width (might have been changed via plugin code)\n theSlider.style.width=theSlider.defaultPanelWidth;\n // align floater panel position with target button\n if (!isOpen && window.adjustSliderPos) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider,theSlider.className);\n // if showing panel, set focus to first 'focus-able' element in panel\n if (theSlider.style.display!="none") {\n var ctrls=theSlider.getElementsByTagName("*");\n for (var c=0; c<ctrls.length; c++) {\n var t=ctrls[c].tagName.toLowerCase();\n if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")\n { ctrls[c].focus(); break; }\n }\n }\n var cookie=theTarget.sliderCookie;\n if (cookie && cookie.length) {\n config.options[cookie]=!isOpen;\n if (config.options[cookie]!=theTarget.defOpen)\n saveOptionCookie(cookie);\n else { // remove cookie if slider is in default display state\n var ex=new Date(); ex.setTime(ex.getTime()-1000);\n document.cookie = cookie+"=novalue; path=/; expires="+ex.toGMTString();\n }\n }\n return false;\n}\n//}}}\n\n//{{{\n// click in document background closes transient panels \ndocument.nestedSliders_savedOnClick=document.onclick;\ndocument.onclick=function(ev) { if (!ev) var ev=window.event; var target=resolveTarget(ev);\n // call original click handler\n if (document.nestedSliders_savedOnClick)\n var retval=document.nestedSliders_savedOnClick.apply(this,arguments);\n // if click was inside transient panel (or something contained by a transient panel)... leave it alone\n var p=target;\n while (p)\n if ((p.className=="floatingPanel"||p.className=="sliderPanel")&&p.getAttribute("transient")=="true") break;\n else p=p.parentNode;\n if (p) return retval;\n // otherwise, find and close all transient panels...\n var all=document.all?document.all:document.getElementsByTagName("DIV");\n for (var i=0; i<all.length; i++) {\n // if it is not a transient panel, or the click was on the button that opened this panel, don't close it.\n if (all[i].getAttribute("transient")!="true" || all[i].button==target) continue;\n // otherwise, if the panel is currently visible, close it by clicking it's button\n if (all[i].style.display!="none") window.onClickNestedSlider({target:all[i].button}) \n }\n return retval;\n};\n//}}}\n\n//{{{\n// adjust floating panel position based on button position\nif (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel,panelClass) {\n if (panelClass=="floatingPanel") {\n var left=0;\n var top=btn.offsetHeight; \n if (place.style.position!="relative") {\n var left=findPosX(btn);\n var top=findPosY(btn)+btn.offsetHeight;\n var p=place; while (p && p.className!='floatingPanel') p=p.parentNode;\n if (p) { left-=findPosX(p); top-=findPosY(p); }\n }\n if (findPosX(btn)+panel.offsetWidth > getWindowWidth()) // adjust position to stay inside right window edge\n left-=findPosX(btn)+panel.offsetWidth-getWindowWidth()+15; // add extra 15px 'fudge factor'\n panel.style.left=left+"px"; panel.style.top=top+"px";\n }\n}\n\nfunction getWindowWidth() {\n if(document.width!=undefined)\n return document.width; // moz (FF)\n if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )\n return document.documentElement.clientWidth; // IE6\n if(document.body && ( document.body.clientWidth || document.body.clientHeight ) )\n return document.body.clientWidth; // IE4\n if(window.innerWidth!=undefined)\n return window.innerWidth; // IE - general\n return 0; // unknown\n}\n//}}}\n\n//{{{\n// TW2.1 and earlier:\n// hijack Slider animation handler 'stop' handler so overflow is visible after animation has completed\nSlider.prototype.coreStop = Slider.prototype.stop;\nSlider.prototype.stop = function()\n { this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }\n\n// TW2.2+\n// hijack Morpher animation handler 'stop' handler so overflow is visible after animation has completed\nif (version.major+.1*version.minor+.01*version.revision>=2.2) {\n Morpher.prototype.coreStop = Morpher.prototype.stop;\n Morpher.prototype.stop = function()\n { this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }\n}\n//}}}
/***\n!Metadata:\n|''Name:''|RecentTiddlersPlugin|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''Version:''|1.1.1|\n|''Date:''|Aug 28, 2007|\n|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|\n|''~CoreVersion:''|2.1.0|\n|''Description:''|Display DefaultTiddlers and recently modified tiddlers at startup.|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0; Opera|\n!Usage:\n>Just to set the options by changing the slice values in RecentTiddlersOptions, if needed.\n!Revision History:\n|''Version''|''Date''|''Note''|\n|1.1.1|Aug 28, 2007|No more hijeck core restart()|\n|1.1.0|Aug 25, 2007|Easy to change the options by using tiddler slices, defined in RecentTiddlersOptions|\n|1.0.0|Apr 18, 2007|Initial release, codes reworked from Tim Morgan's RecentPlugin |\n!Code section:\n***/\n//{{{\nversion.extensions.recentTiddlers = {major: 1, minor: 1, revision: 1, date: new Date("Aug 28, 2007")};\n\nconfig.recentTiddlers = {\n maxNums: 5,\n includeTags: ['*'],\n excludeTags: ['systemConfig','systemTiddlers', 'excludeLists']\n};\n\nconfig.shadowTiddlers.RecentTiddlersOptions = 'maxNums: 5\snincludeTags: *\snexcludeTags: systemConfig,systemTiddlers,excludeLists';\n\nconfig.recentTiddlers.getRecents = function (){\n var c = store.getTiddlerSlices('RecentTiddlersOptions',['maxNums','includeTags','excludeTags']);\n var maxNums = (c.maxNums) ? parseInt(c.maxNums) : config.recentTiddlers.maxNums;\n var includeTags = (c.includeTags) ? c.includeTags.split(',') : config.recentTiddlers.includeTags;\n var excludeTags = (c.excludeTags) ? c.excludeTags.split(',') : config.recentTiddlers.excludeTags;\n var CPlingo = (config.CommentPlugin !== undefined)?config.CommentPlugin.CPlingo:null;\n var rs = store.getTiddlerText("DefaultTiddlers").readBracketedList();\n var tiddlers = store.getTiddlers("modified");\n var n = tiddlers.length -1 - maxNums;\n\n for (var t=tiddlers.length-1; t>n && t>0; t--){\n if(CPlingo !== null && tiddlers[t].isTagged(CPlingo.comments)) {\n var tt = tiddlers[t].title.split(CPlingo.CommentInTitle)[0];\n if(store.tiddlerExists(tt))\n rs.pushUnique(tt);\n }\n else {\n if (tiddlers[t].tags.containsAny(excludeTags))\n n--;\n else {\n if (includeTags.length == 0 || includeTags[0] == '*' || tiddlers[t].tags.containsAny(includeTags))\n rs.pushUnique(tiddlers[t].title);\n }\n }\n }\n return rs;\n};\n\nif(!window.location.hash)\n var recentInterval = setInterval(function(){if(story) {clearInterval(recentInterval); story.closeAllTiddlers();story.displayTiddlers(null,config.recentTiddlers.getRecents());};},100);\n\n//}}}
/***\n\n''This plugin was previously called StyleChooser.''\n\n|Name|SelectThemePlugin|\n|Created by|SimonBaird and SaqImtiaz|\n|Location|http://tw.lewcid.org/#SelectThemePlugin|\n|Version|1.2.5|\n|Requires|~TW2.x|\n!Description\n*An alternative style switcher, can be used to switch just stylesheets and/or pagetemplates, or a combination of both (a theme)\n*you can add your own stylesheets and pagetemplates, or use a ThemePack, like BigThemePack.\n\n!Usage\n* You have to have fetch or create some styleSheets and pageTemplates to use this plugin.\n**You can either get a ThemePack like BigThemePack which automatically adds themes to ThemeSelect.\n**or create tiddlers with styleSheets and pageTemplates and tag them styleSheets and pageTemplates respectively.\n* Put {{{<<themeSelect style 'Select theme'>>}}} in your SideBarOptions.\n\n!Creating Theme Packs\n*You can create your own theme pack if you like. Instructions can be found [[here.|CreateThemePack]]\n\n!History\n*20-Dec-06, v 1.2.5, fixed horizontal rules for IE (thanks Clint), compatibility fix with HoverMenuPlugin\n* 08-Sept-06, v1.2.4, fixed bug with TW2.1\n* 15-May-06, v1.2.3, added paramifier so you can put theme on url, eg http://www.somewhere.com/twfile.html#theme:Berry2, thanks Clint (Simon).\n* 28-Apr-o6, v1.2.2, fixed bug with opening TW after deleting themepacks. (Saq)\n* 26-Apr-06, v1.2.1, more code optimization, dropdowns now updated on the fly. (Saq)\n* 25-Apr-06, v1.2.0, added 3rd party ThemePack support, and made various other improvements.(Simon & Saq)\n* 24-Apr-06, v1.1.0, added: no styles and default styles options,<<br>>support for ThemePack, support for tag variations(Saq)\n* 21-Apr-06, v1.0.0, Reworked dropdowns to include option for pagetemplates (Saq)\n* 21-Apr-06, v0.9.0, Rewrote and added Saq's lovely dropdown select (Simon)\n* 20-Apr-06, v0.0.1, Basic switcher working (Simon)\n\n!Examples\n|!Source|!Output|h\n|{{{<<themeSelect style>>}}} for a dropdown with StyleSheets|<<themeSelect style>>|\n|{{{<<themeSelect pagetemplate>>}}} for a dropdown with PageTemplates|<<themeSelect pagetemplate>>|\n|{{{<<themeSelect style customlabel>>}}} to use a customlabel|<<themeSelect style customlabel>>|\n* When applying a stylesheet or template, it also looks for a template or stylesheet respectively based on naming convention, eg MyFunkyStyleSheet and MyFunkyPageTemplate.\n\n!Notes\n* See also http://www.tiddlytools.com/#SelectStyleSheetPlugin for a more feature-rich style sheet switcher\n\n! Ideas\n* do ViewTemplate also?\n* Pretty up the [x] bit\n\n!Code\n***/\n//{{{\n// for compatibility with TW <2.0.9\nif (!Array.prototype.contains)\n Array.prototype.contains = function(item)\n {\n return this.find(item) != null;\n };\n\n// for compatibility with TW <2.0.9\nif (!Array.prototype.containsAny)\n Array.prototype.containsAny = function(items)\n {\n for(var i=0; i<items.length; i++)\n if (this.contains(items[i]))\n return true;\n return false;\n };\n//}}}\n\n//{{{\nversion.extensions.SelectTheme = { major: 1, minor: 2, revision: 5, date: new Date(2006,12,20),\n source: "http://tw.lewcid.org/#SelectThemePlugin"\n};\n\nconfig.SelectTheme = {\n things: {\n style: {\n tag: ["StyleSheets","StyleSheet","styleSheet","styleSheets","stylesheet","stylesheets"],\n theDefault: "StyleSheet",\n suffix: "StyleSheet",\n notify: refreshStyles,\n cookie: "txtStyleSheet",\n otherThing: "pagetemplate",\n label: "Choose StyleSheet: ",\n tooltip: "Choose a StyleSheet",\n caseNone: { text:"None", title:"NoStyleSheet"},\n caseDefault: { text:"Default", title:"StyleSheet" }\n\n },\n pagetemplate: {\n tag: ["PageTemplates","PageTemplate","pageTemplates","pageTemplate","pagetemplate","pagetemplates"],\n theDefault: "PageTemplate",\n suffix: "PageTemplate",\n notify: refreshPageTemplate,\n cookie: "txtPageTemplate",\n otherThing: "style",\n label: "Choose PageTemplate: ",\n tooltip: "Choose a PageTemplate",\n caseNone: { text:"None", title:"NoPageTemplate"},\n caseDefault: { text:"Default", title:"PageTemplate" }\n }\n\n },\n\n specialCases: ["caseNone","caseDefault"]\n\n};\n\nTiddlyWiki.prototype.removeNotification = function(title,fn) {\n for (var i=0;i<this.namedNotifications.length;i++)\n if((this.namedNotifications[i].name == title) && (this.namedNotifications[i].notify == fn))\n this.namedNotifications.splice(i,1); // counting on it only being there once\n}\n\n\nvar things = config.SelectTheme.things;\nvar specialCases=config.SelectTheme.specialCases;\n\nfor (var zz in things) {\n // make sure we have a value\n if (!config.options[things[zz].cookie])\n config.options[things[zz].cookie] = things[zz].theDefault;\n\n // remove core notify\n store.removeNotification(things[zz].theDefault,things[zz].notify);\n\n // and add our one\n store.addNotification(config.options[things[zz].cookie],things[zz].notify);\n\n}\n\n//checks to see if a tiddler exists in store or as a shadow.\nTiddlyWiki.prototype.isTiddler= function (title)\n {return store.tiddlerExists(title) || store.isShadowTiddler(title)}\n\n//hijack core function & make sure template exists\nwindow.applyPageTemplate_themeSelect=window.applyPageTemplate;\nwindow.applyPageTemplate=function(title){\n if(!store.isTiddler(title))\n {title = things.pagetemplate.theDefault;}\n applyPageTemplate_themeSelect(title);\n }\n\nTiddlyWiki.prototype.makeActiveTheme = function(what,title,alsoCheckOtherThing) {\n\n var thing = things[what];\n if (!store.isTiddler(title))\n title = thing.theDefault;\n\n var oldTitle = config.options[thing.cookie];\n\n if (what == "style") {\n // remove old style element from DOM\n var oldStyleElement = document.getElementById(oldTitle);\n if (oldStyleElement) oldStyleElement.parentNode.removeChild(oldStyleElement);\n }\n\n store.removeNotification(oldTitle,thing.notify);\n store.addNotification(title,thing.notify);\n store.notify(title);\n\n config.options[thing.cookie] = title;\n saveOptionCookie(thing.cookie);\n if (alsoCheckOtherThing)\n this.makeActiveTheme(thing.otherThing,\n title.replace(new RegExp(thing.suffix+"$"),"") + things[thing.otherThing].suffix,\n false);\n};\n\nif (config.hoverMenu)\n {\n old_hovermenu_makeActiveTheme = TiddlyWiki.prototype.makeActiveTheme;\n TiddlyWiki.prototype.makeActiveTheme = function(what,title,alsoCheckOtherThing)\n {\n old_hovermenu_makeActiveTheme.apply(this,arguments);\n if (!alsoCheckOtherThing)\n config.hoverMenu.handler();\n };\n }\n\nconfig.shadowTiddlers.NoStyleSheet = config.shadowTiddlers.StyleSheet;\nconfig.shadowTiddlers.NoPageTemplate = config.shadowTiddlers.PageTemplate;\n\n\nfunction switchTheme(e){\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n var theLink = theTarget;\n var switchTo= theLink.getAttribute("switchTo");\n var mode = theLink.getAttribute("mode");\n if ((config.options[things[mode].cookie])!=switchTo)\n {store.makeActiveTheme(mode,switchTo,true);};\n return(false);\n}\n\n\nconfig.macros.themeSelect={};\nconfig.macros.themeSelect.dropdownchar = (document.all?"▼":"▾");\nconfig.macros.themeSelect.handler = function(place,macroName,params,wikifier,paramString,tiddler){\n var arrow = config.macros.themeSelect.dropdownchar;\n var mode = params[0];\n var label = (params[1]?params[1]:things[mode].label) + arrow;\n var cookie = (config.options[things[mode].cookie]);\n\n var onclick = function(e)\n { if (!e) var e = window.event;\n var popup = Popup.create(this);\n\n var tagged=[];\n\n store.forEachTiddler(function(title,tiddler) {\n if ((tiddler.tags).containsAny(things[mode].tag)){\n tagged.push(tiddler.title);}\n });\n\n //integrate ThemePacks\n if (config.themes) {\n // see what themes have been loaded...\n for (var i=0;i<config.themes.length;i++) {\n // see if there is one\n var lookForThis = config.themes[i] + things[mode].suffix;\n if (store.isShadowTiddler(lookForThis)) {\n tagged.pushUnique(lookForThis);\n }\n }\n tagged = tagged.sort();\n }\n\n //this function used later to create buttons\n var createThemeButton = function(switchTo){\n var theButton = createTiddlyButton(createTiddlyElement(popup,"li"),text,null,switchTheme,useClass);\n theButton.setAttribute("switchTo",switchTo);\n theButton.setAttribute("mode",mode);};\n\n //create Buttons for None(shadow styles) & Default (StyleSheet)\n // Default button is not created if StyleSheet doesnt exist.\n for(var t=0; t<specialCases.length; t++){\n var special = specialCases[t];\n var text = things[mode][special].text;\n var useClass = "tiddlyLinkExisting"; //redundant, optimize!\n if ((things[mode][special].title==cookie)||(special=="caseNone"&&!store.isTiddler(cookie)))\n {text+= " [x]";\n useClass = "currentlySelected";}\n if (!((special=="caseDefault")&&(!store.getTiddler(things[mode][special].title))))\n createThemeButton(things[mode][special].title); }\n\n //insert horizontal rule\n //createTiddlyElement(createTiddlyElement(popup,"li"),"hr");\n createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");\n\n //create buttons for all other stylesheet tiddlers\n for(var t=0; t<tagged.length; t++)\n { var useClass = "tiddlyLinkExisting";\n var text = (tagged[t]).replace((things[mode].suffix),"");\n if (tagged[t]==(cookie) )\n {text+=" [x]"; useClass="currentlySelected";}\n if ((tagged[t]!= (things[mode].theDefault))&&tagged[t]!= (things[mode].none))\n {createThemeButton(tagged[t]);}}\n Popup.show(popup,false);\n e.cancelBubble = true;\n if (e.stopPropagation)\n e.stopPropagation();\n return(false);\n };\n\n var createdropperButton = function(place){\n var sp = createTiddlyElement(place,"span",null,"ThemeChooserButton");\n var theDropDownBtn = createTiddlyButton(sp,label,things[mode].tooltip,onclick);\n };\n\n createdropperButton(place);\n};\n\n\nsetStylesheet(".popup li a.currentlySelected {background:#ccc;color:black;font-weight:bold;}","currentlySelectedStyle"); // could do better probably...\n\nconfig.macros.layoutChooser=config.macros.themeSelect;\n\n//shadow tiddler to hold instructions for creating ThemePacks\nconfig.shadowTiddlers.ThemePack='See http://simonbaird.com/mptw/#CreateThemePack'; \n\nconfig.macros.applyTheme = {handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n var theme = params[0];\n var label = params[1]?params[1]:'Apply theme "' + theme + '"';\n var tooltip = 'Apply the "'+theme+'" theme to this TiddlyWiki';\n createTiddlyButton(place,label,tooltip,function() {\n store.makeActiveTheme("style",theme+things.style.suffix,true);\n });\n}};\n\n\n// this means you can put #theme:ThemeName in url. suggested by Clint\nconfig.paramifiers.theme = {\n onstart: function(themeName) {\n store.makeActiveTheme("style",themeName+config.SelectTheme.things.style.suffix,true);\n }\n};\n\n//}}}
/***\n!Metadata:\n|''Name:''|XMLReader|\n|''Description:''||\n|''Version:''|2.2.0|\n|''Date:''|May 19, 2007|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License]]|\n|''~CoreVersion:''|2.2.0|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0|\n|''Required:''|As the param "asHtml" is used, [[NestedSlidersPlugin|http://www.tiddlytools.com/#NestedSlidersPlugin]] should be installed|\n!Syntax:\n{{{<<rssfeed withDesc|noDesc|asHtml rssfeed.xml|http://www.example.com/rssfeed.rdf>>}}}\n!Revision History:\n|''Version''|''Date''|''Note''|\n|2.2.0|May 19, 2007|Atom feeds suppported|\n|2.1.1|May 15, 2007|Fixed cache bug|\n|2.1.0|May 10, 2007|Fixed bugs:<br>1.missing parameter 'responseText' of processResponse<br>2.Caches failed|\n|2.0.0|Mar 08, 2007|Required TW 2.2.0+|\n|1.5.0|Mar 04, 2007|Codes reworked, more easier reused|\n|1.2.0|Jul 20, 2006|Runs compatibly with TW 2.1.0 (rev #403+)|\n|1.1.0|Jul 10, 2006)|change xmlhttp.send(null)/send() to xmlhttp.send("") for more compatibility for some browsers|\n|1.0.0|Mar 11, 2006|Initial release|\n|~|~|This macro is reworked from RssNewsMacro, but it can be easy to extended to support different structure of xml document from rss feeds|\n|~|~|You could uninstall the RssNewsMacro, but still use the original syntax,<<br>>{{{<<rssfeed withDesc|noDesc|asHtml "rssfeed.xml"|"http://www.example.com/rssfeed.rdf">>}}}|\n\n!Code section:\n***/\n//{{{\nversion.extensions.xmlreader = {major: 2, minor: 2, revision: 0,\n date: new Date("May 19, 2007"),\n name: "XMLReader",\n type: "Macro",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n};\n\nconfig.messages.XmlReader = {\n fromCache: "^^(//from cache//)^^",\n errorInDataRetriveing: "Problem retrieving XML data: %0",\n invalidXML: "Invalid XML retrieved from: %0",\n urlNotAccessible: "Access to %0 is not allowed,\snPlease check the setting of your browser:\sn1.For Gecko based, you should set the 'signed.applets.codebase_principal_support' to be true, in about:config.\sn2.For IE, you should add this web site to your trust list."\n};\n\nfunction XmlReader(place,withDesc,xmlURL) {\n this.xmlhttp = null;\n this.place = place;\n this.xmlURL = xmlURL;\n this.withDesc = withDesc;\n this.itemStructure = {title:'Title',link:'Link',pubDate:'PubDate',description:'Desc'};\n this.atomStructure = {title:'Title',id:'Link',updated:'Updated',summary:'Desc'};\n// this.rsTemplate = function(){var t='';for (var i in itemStructure){t+='_'+itemStructure[i]}};\n this.rsTemplate = '_pubDate\sn**[[_title|_link]]_description';\n this.items = {Elm: "%0Elm", Text: "_%0"};\n this.keyItem = "item";\n this.dateFormat = "DDD, DD MMM YYYY";\n this.groupBy = null;\n return this;\n};\n\nXmlReader.prototype.asyncGet = function(xmlURL,callback){\n if(window.Components && window.netscape && window.netscape.security && this.isCrossSite(xmlURL)){\n try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");}\n catch (e) {displayMessage(e.description?e.description:e.toString());}\n }\n return doHttp("GET",xmlURL,null,'text/xml',null,null,callback,null,null)\n};\n\nXmlReader.prototype.genLists = function(xml){\n var itemStructure;\n if (xml.lastChild.nodeName == 'feed'){\n this.keyItem = 'entry';\n itemStructure = this.atomStructure;\n }\n else {\n itemStructure = this.itemStructure;\n }\n var itemList = xml.getElementsByTagName(this.keyItem);\n var items = this.items;\n var rsLists='', rssItem; this.groupBy='';\n for (var i=0; i<itemList.length; i++){\n var itemElms=[],itemTexts=[];\n var rsTemplate=this.rsTemplate;\n for (var j in itemStructure){\n var itemElm = items.Elm.format([j]);\n var itemText = items.Text.format([j]);\n itemElms[itemElm] = itemList[i].getElementsByTagName(j).item(0);\n if(itemElms[itemElm]){\n var theTitle = itemStructure[j];\n var theText = (itemElms[itemElm].firstChild)?itemElms[itemElm].firstChild.nodeValue:'';\n rsTemplate=this.convertTemplate(rsTemplate,j,theText);\n }\n else {\n rsTemplate = rsTemplate.replace('_'+j, '');\n }\n }\n rsLists += rsTemplate;\n }\n return rsLists;\n};\n \nXmlReader.prototype.convertTemplate = function(rsTemplate,j,theText){\n switch (j){\n case 'title':\n rsTemplate = rsTemplate.replace(/_title/,theText.replace(/\s[|\s]/g,''));\n break;\n case 'id':\n j = 'link';\n case 'link' || 'id':\n rsTemplate = rsTemplate.replace('_'+j, theText);\n break;\n case 'updated':\n j = 'pubDate'\n case 'pubDate':\n theText = this.dateFormatString(this.dateFormat, theText);\n if (this.groupBy == theText){\n rsTemplate = rsTemplate.replace('_'+j, '');\n }\n else{\n rsTemplate = rsTemplate.replace('_'+j, '\sn* '+theText);\n this.groupBy = theText;\n }\n break;\n case 'summary':\n j = 'description';\n case 'description':\n var regexpDesc = new RegExp("withDesc|asHtml","g");\n if (regexpDesc.exec(this.withDesc) && theText){\n var _description = theText.replace(/\sn/g,' ');\n _description =_description.replace(/<br \s/>/ig,'\sn'); \n if (version.extensions.nestedSliders){\n _description = ((this.withDesc == "asHtml")?"<html>"+_description+"</html>":_description);\n rsTemplate = rsTemplate.replace('_'+j,'+++[...]'+_description+'\sn===\sn');\n }\n else {\n rsTemplate = rsTemplate.replace('_'+j,_description+'\sn');\n }\n }\n else {\n rsTemplate = rsTemplate.replace('_'+j,'');\n }\n break;\n }\n return (rsTemplate);\n};\n\nXmlReader.prototype.dateFormatString = function(template, theDate){\n theDate = theDate.replace(/-/g,'/').replace(/T.*UT|T.*Z/ ,'');\n var dateString = new Date(theDate);\n template = template.replace(/hh|mm|ss/g,'');\n return dateString.formatString(template);\n};\n\nXmlReader.prototype.isCrossSite = function (url){\n var result = false;\n var curLoc = document.location;\n if (url.indexOf(":") != -1 && curLoc.protocol.indexOf("http") != -1) {\n var re=/(\sw+):\s/\s/([^/:]+)(:\sd*)?([^# ]*)/;\n var rsURL=url.match(re);\n for (var i=0; i<rsURL.length; i++){\n rsURL[i]=(typeof rsURL[i] == 'undefined')?'':rsURL[i];\n }\n result = (curLoc.protocol == rsURL[1] && curLoc.host == rsURL[2] && curLoc.port == rsURL[3]);\n }\n return (!result);\n};\n//}}}\n/***\n!Macro rssfeed\n***/\n//{{{\nconfig.macros.rssfeed = {\n cache: {},\n dateFormat: "YYYY/0MM/0DD"\n};\n\nconfig.macros.rssfeed.handler = function(place,macroName,params){\n var withDesc = params[0];\n var xmlURL = params[1];\n var rss = new XmlReader(place,withDesc,xmlURL);\n rss.dateFormat = this.dateFormat;\n var processResponse = function(status,params,responseText,xmlURL,x){\n if (window.netscape){\n if (rss.isCrossSite(xmlURL)){\n try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");}\n catch (e) { displayMessage(e.description?e.description:e.toString()); }\n }\n }\n if (x.responseXML){\n xmlURL = xmlURL.replace(/[\s?|\s&]nocache.*/,'');\n config.macros.rssfeed.cache[xmlURL] = x;\n wikify(rss.genLists(x.responseXML),place);\n }\n else {\n wikify("<html>"+ x.responseText+"</html>", place);\n displayMessage(config.messages.XmlReader.invalidXML.format([xmlURL]));\n }\n };\n if (this.cache[xmlURL]) {\n wikify(config.messages.XmlReader.fromCache,place);\n var status = false;\n var x=this.cache[xmlURL];\n processResponse(status,null,x.responseText,xmlURL,x);\n }\n else {\n rss.xmlhttp = rss.asyncGet(xmlURL, processResponse);\n }\n};\n//}}}
/***\n|''Name:''|WikiBar|\n|''Version:''|2.0.0 beta3|\n|''Source:''|[[AiddlyWiki|http://aiddlywiki.sourceforge.net]]|\n|''Author:''|[[Arphen Lin|mailto:arphenlin@gmail.com]]|\n|''Type:''|toolbar macro command extension|\n|''Required:''|TiddlyWiki 2.0.0 beta6|\n!Description\nWikiBar is a toolbar that gives access to most of TiddlyWiki's formatting features with a few clicks. It's a handy tool for people who are not familiar with TiddlyWiki syntax.\nBesides, with WikiBar-addons, users can extend the power of WikiBar.\n!Support browser\n*Firefox 1.5\n!Revision history\n*v2.0.0 beta3 (2005/12/30)\n** remove macros (replaced by TWMacro addon)\n** add wikibar command in toolbar automatically\n** rename DOIT to HANDLER\n** rename TIP to TOOLTIP\n*v2.0.0 beta2 (2005/12/21)\n** re-design Wikibar addon framework\n*v2.0.0 beta1 (2005/12/14)\n** Note:\n*** WikiBarPlugin is renamed to WikiBar\n** New Features:\n*** support TiddlyWiki 2.0.0 template mechanism\n*** new wikibar data structure\n*** new wikibar-addon framework for developers\n**** support dynamic popup menu generator\n*** support most new macros added in TiddlyWiki 2.0.0\n*** multi-level popup menu\n*** fix wikibar tab stop\n*** remove paletteSelector\n** Known Bugs:\n*** popup-menu and color-picker can't be closed correctly\n*** some macros can't be displayed correctly in previewer\n*** text in previewer will be displayed italic\n*v1.2.0 (2005/11/21)\n**New Features:\n***User defined color palettes supported\n####Get color palettes from [[ColorZilla Palettes|http://www.iosart.com/firefox/colorzilla/palettes.html]].\n####Save the palette file(*.gpl) as a new tiddler and tag it with 'ColorPalettes', then you can use it in WikiBar.\n***WikiBar style sheet supported\n***Click on document to close current colorPicker, paletteSelector or aboutWikibar\n*v1.1.1 (2005/11/03)\n**Bugs fixed:\n***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello world!'\n*v1.1.0 (2005/11/01)\n**Bugs fixed:\n***WikiBar overruns (reported by by GeoffS <gslocock@yahoo.co.uk>)\n**New features:\n***Insert a color code at the cursor. (Thanks to RunningUtes <RunningUtes@gmail.com>)\n***Enable gradient macro. (Thanks to RunningUtes <RunningUtes@gmail.com>)\n***Insert tiddler comment tags {{{/% ... %/}}}. (new feature supported by TiddlyWiki 1.2.37)\n***Insert DateFormatString for {{{<<today>>}}} macro. (new feature supported by TiddlyWiki 1.2.37)\n**Enhanced:\n***Allow optional parameters in syntax.\n**Bugs:\n***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello world!'\n*v1.0.0 (2005/10/30)\n**Initial release\n!Code\n***/\n//{{{\nconfig.macros.wikibar = {major: 2, minor: 0, revision: 0, beta: 3, date: new Date(2005,12,30)};\nconfig.macros.wikibar.handler = function(place,macroName,params,wikifier,paramString,tiddler){\n if(!(tiddler instanceof Tiddler)) {return;}\n story.setDirty(tiddler.title,true);\n place.id = 'wikibar'+tiddler.title;\n place.className = 'toolbar wikibar';\n};\nfunction wikibar_install(){\n config.commands.wikibar = {\n text: 'wikibar',\n tooltip: 'wikibar on/off',\n handler: function(e,src,title) {\n if(!e){ e = window.event; }\n var theButton = resolveTarget(e);\n theButton.id = 'wikibarButton'+title;\n wikibarPopup.remove();\n wikibar_installAddons(theButton, title);\n wikibar_createWikibar(title);\n return(false);\n }\n };\n config.shadowTiddlers['EditTemplate'] = wikibar_addWikibarCommand(config.shadowTiddlers['EditTemplate']);\n var tiddler = store.getTiddler('EditTemplate');\n if(tiddler){\n tiddler.text = wikibar_addWikibarCommand(tiddler.text);\n }\n}\nfunction wikibar_installAddons(theButton, title){\n var tiddlers = store.getTaggedTiddlers('wikibarAddons');\n if(!tiddlers) { return; }\n theButton.addons=[];\n for(var i=0; i<tiddlers.length; i++){\n try{\n eval(tiddlers[i].text);\n try{\n wikibar_addonInstall(title);\n wikibar_addonInstall = null;\n theButton.addons.push({ok:true, name:tiddlers[i].title});\n }catch(ex){\n theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});\n }\n }catch(ex){\n theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});\n }\n }\n}\nfunction wikibar_addWikibarCommand(tiddlerText){\n var div = document.createElement('div');\n div.style.display = 'none';\n div.innerHTML = tiddlerText;\n for(var i=0; i<div.childNodes.length; i++){\n var o=div.childNodes[i];\n if(o.tagName==='DIV'){\n if(o.className=='toolbar'){\n var macroText = o.getAttribute('macro').trim();\n if(macroText.search('wikibar')<=0){\n macroText += ' wikibar';\n o.setAttribute('macro', macroText);\n }\n break;\n }\n }\n }\n return div.innerHTML.replace(/\s"/g, "\s'");\n}\nfunction wikibar_processSyntaxParams(theSyntax, params){\n try{\n var pcr = 'AplWikibarPcr';\n var rx=null;\n var allParams=null;\n if(params){\n if(typeof(params)=='object'){\n for(var i=0; i<params.length; i++){\n if(params[i]){\n params[i] = params[i].replace(new RegExp('%','g'), pcr).trim();\n rx = '(\s\s[%'+(i+1)+'\s\s])' + '|' + '(%'+(i+1)+')';\n theSyntax = theSyntax.replace(new RegExp(rx,'g'), params[i] );\n }\n }\n allParams = params.join(' ').trim();\n }else{\n allParams = params.replace(new RegExp('%','g'), pcr).trim();\n rx = /(\s[%1{1}\s])|(%1{1})/g;\n theSyntax = theSyntax.replace(rx, allParams);\n }\n }\n if(allParams){\n theSyntax = theSyntax.replace(new RegExp('%N{1}','g'), allParams);\n }\n rx=/\s[%(([1-9]{1,}[0-9]{0,})|(N{1}))\s]/g;\n theSyntax = theSyntax.replace(rx, '');\n rx=/%(([1-9]{1,}[0-9]{0,})|(N{1}))/g;\n if( theSyntax.match(rx) ){\n throw 'Not enough parameters! ' + theSyntax;\n }\n theSyntax=theSyntax.replace(new RegExp(pcr,'g'), '%');\n return theSyntax;\n } catch(ex){\n return null;\n }\n}\nfunction wikibar_resolveEditItem(tiddlerWrapper, itemName){\n if(tiddlerWrapper.hasChildNodes()){\n var c=tiddlerWrapper.childNodes;\n for(var i=0; i<c.length; i++){\n var txt=wikibar_resolveEditItem(c[i], itemName);\n if(!txt){\n continue;\n }else{\n return txt;\n }\n }\n }\n return ((tiddlerWrapper.getAttribute && tiddlerWrapper.getAttribute('edit')==itemName)? tiddlerWrapper : null);\n}\nfunction wikibar_resolveEditItemValue(tiddlerWrapper, itemName){\n var o = wikibar_resolveEditItem(tiddlerWrapper, itemName);\n return (o? o.value.replace(/\sr/mg,'') : null);\n}\nfunction wikibar_resolveTiddlerEditorWrapper(obj){\n if(obj.id=='tiddlerDisplay'){return null;}\n if((obj.getAttribute && obj.getAttribute('macro')=='edit text')){return obj;}\n return wikibar_resolveTiddlerEditorWrapper(obj.parentNode);\n}\nfunction wikibar_resolveTiddlerEditor(obj){\n if(obj.hasChildNodes()){\n var c = obj.childNodes;\n for(var i=0; i<c.length; i++){\n var o=wikibar_resolveTiddlerEditor(c[i]);\n if(o){ return o;}\n }\n }\n return ((obj.getAttribute && obj.getAttribute('edit')=='text')? obj : null);\n}\nfunction wikibar_resolveTargetButton(obj){\n if(obj.id && obj.id.substring(0,7)=='wikibar'){ return null; }\n if(obj.tiddlerTitle){\n return obj;\n }else{\n return wikibar_resolveTargetButton(obj.parentNode);\n }\n}\nfunction wikibar_isValidMenuItem(tool){\n if(!tool){ return false; }\n if(tool.TYPE=='MENU' || tool.TYPE=='MAIN_MENU'){\n for(var key in tool){\n if(key.substring(0,8)=='DYNAITEM'){ return true; }\n if(wikibar_isValidMenuItem(tool[key])){ return true; }\n }\n return false;\n }else{\n return (tool.HANDLER? true : false);\n }\n}\nfunction wikibar_editFormat(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){ return; }\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var endText = '';\n var fullText = editor.value;\n if(se>ss && ss>=0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n }\n else if(ss===0 && (se===0 || se == fullText.length) ){\n endText = fullText;\n }\n else if(se==ss && ss>0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editFormatByWord(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){return;}\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var selText = '';\n var endText = '';\n var fullText = editor.value;\n if(se>ss && ss>=0){\n frontText = fullText.substring(0, ss);\n selText = fullText.substring(ss,se);\n endText = fullText.substring(se, fullText.length);\n }\n else if(ss===0 && (se===0 || se == fullText.length) ){\n endText = fullText;\n }\n else if(se==ss && ss>0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n if(!( fullText.charAt(ss-1).match(/\sW/gi) || fullText.charAt(ss).match(/\sW/gi) )){\n var m = frontText.match(/\sW/gi);\n if(m){\n ss = frontText.lastIndexOf(m[m.length-1])+1;\n }\n else{\n ss = 0;\n }\n m = endText.match(/\sW/gi);\n if(m){\n se += endText.indexOf(m[0]);\n }\n else{\n se = fullText.length;\n }\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n selText = fullText.substring(ss,se);\n }\n }\n if(selText.length>0){\n repText = repText.replace('user_text', selText);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editFormatByCursor(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){ return; }\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var endText = '';\n var fullText = editor.value;\n if(se>ss && ss>=0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n }\n else if(ss===0 && (se===0 || se == fullText.length) ){\n endText = fullText;\n }\n else if(se==ss && ss>0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editFormatByLine(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){ return; }\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var selText = '';\n var endText = '';\n var fullText = editor.value;\n if(se>ss && ss>=0){\n if(this.byBlock){\n frontText = fullText.substring(0, ss);\n selText = fullText.substring(ss,se);\n endText = fullText.substring(se, fullText.length);\n }\n else{\n se = ss;\n }\n }\n if(ss===0 && (se===0 || se == fullText.length) ){\n var m=fullText.match(/(\sn|\sr)/g);\n if(m){\n se = fullText.indexOf(m[0]);\n }else{\n se = fullText.length;\n }\n selText = fullText.substring(0, se);\n endText = fullText.substring(se, fullText.length);\n }\n else if(se==ss && ss>0){\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n m = frontText.match(/(\sn|\sr)/g);\n if(m){\n ss = frontText.lastIndexOf(m[m.length-1])+1;\n }\n else{\n ss = 0;\n }\n m = endText.match(/(\sn|\sr)/g);\n if(m){\n se += endText.indexOf(m[0]);\n }\n else{\n se = fullText.length;\n }\n frontText = fullText.substring(0, ss);\n selText = fullText.substring(ss,se);\n endText = fullText.substring(se, fullText.length);\n }\n if(selText.length>0){\n repText = repText.replace('user_text', selText);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n if(this.byBlock){\n if( (frontText.charAt(frontText.length-1)!='\sn') && ss>0 ){\n repText = '\sn' + repText;\n }\n if( (endText.charAt(0)!='\sn') || se==fullText.length){\n repText += '\sn';\n }\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editFormatByTableCell(param){\n var editor = param.button.editor;\n var params = param.params;\n clearMessage();\n if(!editor){ return; }\n var repText = wikibar_processSyntaxParams(this.syntax, params);\n if(repText===null){ return; }\n var st = editor.scrollTop;\n var ss = editor.selectionStart;\n var se = editor.selectionEnd;\n var frontText= '';\n var selText = '';\n var endText = '';\n var fullText = editor.value;\n if(ss===0 || ss==fullText.length){\n throw 'not valid cell!';\n }\n se=ss;\n frontText = fullText.substring(0, ss);\n endText = fullText.substring(se, fullText.length);\n i=frontText.lastIndexOf('\sn');\n j=frontText.lastIndexOf('|');\n if(i>j || j<0){\n throw 'not valid cell!';\n }\n ss = j+1;\n i=endText.indexOf('\sn');\n j=endText.indexOf('|');\n if(i<j || j<0){\n throw 'not valid cell!';\n }\n se += j;\n frontText = fullText.substring(0, ss-1);\n selText = fullText.substring(ss,se);\n endText = fullText.substring(se+1, fullText.length);\n if(this.key.substring(0,5)=='align'){\n selText = selText.trim();\n if( selText=='>' || selText=='~' || selText.substring(0,8)=='bgcolor(') {return; }\n }\n if(selText.length>0){\n repText = repText.replace('user_text', selText);\n }\n if(repText.indexOf('user_text')>=0 && this.hint){\n repText = repText.replace('user_text', this.hint);\n }\n editor.value = frontText + repText + endText;\n editor.selectionStart = ss;\n editor.selectionEnd = ss + repText.length - 2;\n editor.scrollTop = st;\n editor.focus();\n}\nfunction wikibar_editSelectAll(param){\n var editor = param.button.editor;\n editor.selectionStart = 0;\n editor.selectionEnd = editor.value.length;\n editor.scrollTop = 0;\n editor.focus();\n}\nfunction wikibar_doPreview(param){\n var theButton = param.button;\n var editor = param.button.editor;\n var wikibar = theButton.parentNode;\n if(!wikibar) { return; }\n title = theButton.tiddlerTitle;\n var editorWrapper = wikibar_resolveTiddlerEditorWrapper(editor);\n var tiddlerWrapper = editorWrapper.parentNode;\n var previewer = document.getElementById('previewer'+title);\n if(previewer){\n previewer.parentNode.removeChild(previewer);\n editorWrapper.style.display = 'block';\n visible=true;\n }else{\n previewer = document.createElement('div');\n previewer.id = 'previewer'+title;\n previewer.className = 'viewer previewer';\n previewer.style.height = (editor.offsetHeight) + 'px';\n wikify(editor.value, previewer);\n tiddlerWrapper.insertBefore(previewer, editorWrapper);\n editorWrapper.style.display = 'none';\n visible=false;\n }\n var pv=null;\n for(var i=0; i<wikibar.childNodes.length; i++){\n try{\n var btn = wikibar.childNodes[i];\n if(btn.toolItem.key == 'preview'){ pv=btn; }\n if(btn.toolItem.key != 'preview'){\n btn.style.display = visible ? '': 'none';\n }\n }catch(ex){}\n }\n if(!pv) { return; }\n if(visible){\n pv.innerHTML = '<font face=\s"verdana\s">&infin;</font>';\n pv.title = 'preview current tiddler';\n }\n else{\n pv.innerHTML = '<font face=\s"verdana\s">&larr;</font>';\n pv.title = 'back to editor';\n }\n}\nfunction wikibar_doListAddons(param){\n clearMessage();\n var title = param.button.tiddlerTitle;\n var wikibarButton = document.getElementById('wikibarButton'+title);\n var ok=0, fail=0;\n for(var i=0; i<wikibarButton.addons.length; i++){\n var addon=wikibarButton.addons[i];\n if(addon.ok){\n displayMessage('[ o ] '+addon.name);\n ok++;\n }\n else{\n displayMessage('[ x ] '+addon.name + ': ' + addon.error);\n fail++;\n }\n }\n displayMessage('---------------------------------');\n displayMessage(ok + ' ok ; ' + fail + ' failed');\n}\nfunction wikibar_getColorCode(param){\n var cbOnPickColor = function(colorCode, param){\n param.params = colorCode;\n param.button.toolItem.doMore(param);\n };\n wikibarColorTool.openColorPicker(param.button, cbOnPickColor, param);\n}\nfunction wikibar_getLinkUrl(param){\n var url= prompt('Please enter the link target', (this.param? this.param : ''));\n if (url && url.trim().length>0){\n param.params = url;\n this.doMore(param);\n }\n}\nfunction wikibar_getTableRowCol(param){\n var rc= prompt('Please enter (rows x cols) of the table', '2 x 3');\n if (!rc || (rc.trim()).length<=0){ return; }\n var arr = rc.toUpperCase().split('X');\n if(arr.length != 2) { return; }\n for(var i=0; i<arr.length; i++){\n if(isNaN(arr[i].trim())) { return; }\n }\n var rows = parseInt(arr[0].trim(), 10);\n var cols = parseInt(arr[1].trim(), 10);\n var txtTable='';\n for(var r=0; r<rows; r++){\n for(var c=0; c<=cols; c++){\n if(c===0){\n txtTable += '|';\n }else{\n txtTable += ' |';\n }\n }\n txtTable += '\sn';\n }\n if(txtTable.trim().length>0){\n param.params = txtTable.trim();\n this.doMore(param);\n }\n}\nfunction wikibar_getMacroParam(param){\n var p = prompt('Please enter the parameters of macro \s"' + this.key + '\s":' +\n '\snSyntax: ' + this.syntax +\n '\sn\snNote: '+\n '\sn%1,%2,... - parameter needed'+\n '\sn[%1] - optional parameter'+\n '\sn%N - more than one parameter(1~n)'+\n '\sn[%N] - any number of parameters(0~n)'+\n '\sn\snPS:'+\n '\sn1. Parameters should be seperated with space character'+\n '\sn2. Use \s" to wrap the parameter that includes space character, ex: \s"hello world\s"'+\n '\sn3. Input the word(null) for the optional parameter ignored',\n (this.param? this.param : '') );\n if(!p) { return; }\n p=p.readMacroParams();\n for(var i=0; i<p.length; i++){\n var s=p[i].trim();\n if(s.indexOf(' ')>0){ p[i]="'"+s+"'"; }\n if(s.toLowerCase()=='null'){ p[i]=null; }\n }\n param.params = p;\n this.doMore(param);\n}\nfunction wikibar_getMorePalette(unused){\n clearMessage();\n displayMessage('Get more color palettes(*.gpl) from ColorZilla Palettes site', 'http:\s/\s/www.iosart.com/firefox/colorzilla/palettes.html');\n displayMessage('Save it as a new tiddler with \s"ColorPalettes\s" tag');\n}\nfunction wikibar_createWikibar(title){\n var theWikibar = document.getElementById('wikibar' + title);\n if(theWikibar){\n if(theWikibar.hasChildNodes()){\n theWikibar.style.display = (theWikibar.style.display=='block'? 'none':'block');\n return;\n }\n }\n var tiddlerWrapper = document.getElementById('tiddler'+title);\n var theTextarea = wikibar_resolveTiddlerEditor(tiddlerWrapper);\n if(!theTextarea){\n clearMessage();\n displayMessage('WikiBar only works in tiddler edit mode now');\n return;\n }else{\n if(!theTextarea.id){ theTextarea.id = 'editor'+title; }\n if(!theTextarea.parentNode.id){ theTextarea.parentNode.id='editorWrapper'+title; }\n }\n if(theWikibar){\n theWikibar = document.getElementById('wikibar'+title);\n }else{\n var editorWrapper = wikibar_resolveTiddlerEditorWrapper(theTextarea);\n theWikibar = createTiddlyElement(tiddlerWrapper, 'div', 'wikibar'+title, 'toolbar');\n addClass(theWikibar, 'wikibar');\n var previewer = document.getElementById('previewer'+title);\n if(previewer){\n tiddlerWrapper.insertBefore(theWikibar, previewer);\n }else{\n tiddlerWrapper.insertBefore(theWikibar, editorWrapper);\n }\n }\n wikibar_createMenu(theWikibar,wikibarStore,title,theTextarea);\n if(config.options['chkWikibarSetEditorHeight'] && config.options['txtWikibarEditorRows']){\n theTextarea.rows = config.options['txtWikibarEditorRows'];\n }\n setStylesheet(\n '.wikibar{text-align:left;visibility:visible;margin:2px;padding:1px;}.previewer{overflow:auto;display:block;border:1px solid;}#colorPicker{position:absolute;display:none;z-index:10;margin:0px;padding:0px;}#colorPicker table{margin:0px;padding:0px;border:2px solid #000;border-spacing:0px;border-collapse:collapse;}#colorPicker td{margin:0px;padding:0px;border:1px solid;font-size:11px;text-align:center;cursor:auto;}#colorPicker .header{background-color:#fff;}#colorPicker .button{background-color:#fff;cursor:pointer;cursor:hand;}#colorPicker .button:hover{padding-top:3px;padding-bottom:3px;color:#fff;background-color:#136;}#colorPicker .cell{padding:4px;font-size:7px;cursor:crosshair;}#colorPicker .cell:hover{padding:10px;}.wikibarPopup{position:absolute;z-index:10;border:1px solid #014;color:#014;background-color:#cef;}.wikibarPopup table{margin:0;padding:0;border:0;border-spacing:0;border-collapse:collapse;}.wikibarPopup .button:hover{color:#eee;background-color:#014;}.wikibarPopup .disabled{color:#888;}.wikibarPopup .disabled:hover{color:#888;background-color:#cef;}.wikibarPopup tr .seperator hr{margin:0;padding:0;background-color:#cef;width:100%;border:0;border-top:1px dashed #014;}.wikibarPopup tr .icon{font-family:verdana;font-weight:bolder;}.wikibarPopup tr .marker{font-family:verdana;font-weight:bolder;}.wikibarPopup td{font-size:0.9em;padding:2px;}.wikibarPopup input{border:0;border-bottom:1px solid #014;margin:0;padding:0;font-family:arial;font-size:100%;background-color:#fff;}',\n 'WikiBarStyleSheet');\n}\nfunction wikibar_createMenu(place,toolset,title,editor){\n if(!wikibar_isValidMenuItem(toolset)){return;}\n if(!(toolset.TYPE=='MAIN_MENU' || toolset.TYPE=='MENU')){ return; }\n for(var key in toolset){\n if(key.substring(0,9)=='SEPERATOR'){\n wikibar_createMenuSeperator(place);\n continue;\n }\n if(key.substring(0,8)=='DYNAITEM'){\n var dynaTools = toolset[key](title,editor);\n if(dynaTools.TYPE && dynaTools.TYPE=='MENU'){\n wikibar_createMenuItem(place,dynaTools,null,editor,title);\n }else{\n dynaTools.TYPE = 'MENU';\n wikibar_createMenu(place, dynaTools, title, editor);\n }\n continue;\n }\n if((toolset[key].TYPE!='MENU' && toolset[key].TYPE!='MAIN_MENU') && !toolset[key].HANDLER){continue;}\n wikibar_createMenuItem(place,toolset,key,editor,title);\n }\n}\nfunction wikibar_createMenuItem(place,toolset,key,editor,title){\n if(!key){\n var tool = toolset;\n }else{\n tool = toolset[key];\n tool.key = key;\n }\n if(!wikibar_isValidMenuItem(tool)){return;}\n var toolIsOnMainMenu = (toolset.TYPE=='MAIN_MENU');\n var toolIsMenu = (tool.TYPE=='MENU');\n var theButton;\n if(toolIsOnMainMenu){\n theButton = createTiddlyButton(\n place,\n '',\n (tool.TOOLTIP? tool.TOOLTIP : ''),\n (toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem),\n 'button');\n theButton.innerHTML = (tool.CAPTION? tool.CAPTION : key);\n theButton.isOnMainMenu = true;\n addClass(theButton, (toolIsMenu? 'menu' : 'item'));\n place.appendChild( document.createTextNode('\sn') );\n if(!toolIsMenu){\n if(config.options['chkWikibarPopmenuOnMouseOver']){\n theButton.onmouseover = function(e){ wikibarPopup.remove(); };\n }\n }\n }else{\n theButton=createTiddlyElement(place, 'tr',key,'button');\n theButton.title = (tool.TOOLTIP? tool.TOOLTIP : '');\n theButton.onclick = (toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem);\n var tdL = createTiddlyElement(theButton, 'td','','marker');\n var td = createTiddlyElement(theButton, 'td');\n var tdR = createTiddlyElement(theButton, 'td','','marker');\n td.innerHTML = (tool.CAPTION? tool.CAPTION : key);\n if(toolIsMenu){\n tdR.innerHTML='&nbsp;&nbsp;&rsaquo;';\n }\n if(tool.SELECTED){\n tdL.innerHTML = '&radic; ';\n addClass(theButton, 'selected');\n }\n if(tool.DISABLED){\n addClass(theButton, 'disabled');\n }\n }\n theButton.tiddlerTitle = title;\n theButton.toolItem = tool;\n theButton.editor = editor;\n theButton.tabIndex = 999;\n if(toolIsMenu){\n if(config.options['chkWikibarPopmenuOnMouseOver']){\n theButton.onmouseover = wikibar_onClickMenuItem;\n }\n }\n}\nfunction wikibar_createMenuSeperator(place){\n if(place.id.substring(0,7)=='wikibar') { return; }\n var onclickSeperator=function(e){\n if(!e){ e = window.event; }\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n return(false);\n };\n var theButton=createTiddlyElement(place,'tr','','seperator');\n var td = createTiddlyElement(theButton, 'td','','seperator');\n td.colSpan=3;\n theButton.onclick=onclickSeperator;\n td.innerHTML = '<hr>';\n}\nfunction wikibar_genWikibarAbout(){\n var toolset={};\n toolset.version = {\n CAPTION: '<center>WikiBar ' +\n config.macros.wikibar.major + '.' +\n config.macros.wikibar.minor + '.' +\n config.macros.wikibar.revision +\n (config.macros.wikibar.beta? ' beta '+config.macros.wikibar.beta : '') +\n '</center>',\n HANDLER: function(){}\n };\n toolset.SEPERATOR = {};\n toolset.author = {\n CAPTION: '<center>Arphen Lin<br>arphenlin@gmail.com</center>',\n TOOLTIP: 'send mail to the author',\n HANDLER: function(){ window.open('mailto:arphenlin@gmail.com'); }\n };\n toolset.website = {\n CAPTION: '<center>aiddlywiki.sourceforge.net</center>',\n TOOLTIP: 'go to the web site of WikiBar',\n HANDLER: function(){ window.open('http:\s/\s/aiddlywiki.sourceforge.net/'); }\n };\n return toolset;\n}\nfunction wikibar_genWikibarOptions(title, editor){\n var toolset={};\n toolset.popOnMouseOver = {\n CAPTION:'popup menu on mouse over',\n SELECTED: config.options['chkWikibarPopmenuOnMouseOver'],\n HANDLER: function(param){\n config.options['chkWikibarPopmenuOnMouseOver'] = !config.options['chkWikibarPopmenuOnMouseOver'];\n saveOptionCookie('chkWikibarPopmenuOnMouseOver');\n var title = param.button.tiddlerTitle;\n var wikibar = document.getElementById('wikibar'+title);\n if(wikibar){ wikibar.parentNode.removeChild(wikibar); }\n wikibar_createWikibar(title);\n }\n };\n toolset.setEditorSize = {\n CAPTION:'set editor height: <input id=\s"txtWikibarEditorRows\s" type=text size=1 MAXLENGTH=3 value=\s"' +\n (config.options['txtWikibarEditorRows']? config.options['txtWikibarEditorRows']:editor.rows) + '\s"> ok',\n HANDLER: function(param){\n var input = document.getElementById('txtWikibarEditorRows');\n if(input){\n var rows = parseInt(input.value, 10);\n if(!isNaN(rows)){\n var editor = param.button.editor;\n editor.rows = rows;\n }else{\n rows=config.maxEditRows;\n }\n config.options['txtWikibarEditorRows'] = rows;\n saveOptionCookie('txtWikibarEditorRows');\n config.maxEditRows = rows;\n }\n }\n };\n toolset.setEditorSizeOnLoadingWikibar = {\n CAPTION:'set editor height on loading wikibar',\n SELECTED: config.options['chkWikibarSetEditorHeight'],\n HANDLER: function(param){\n config.options['chkWikibarSetEditorHeight'] = !config.options['chkWikibarSetEditorHeight'];\n saveOptionCookie('chkWikibarSetEditorHeight');\n if(config.options['chkWikibarSetEditorHeight']){\n var rows = config.options['txtWikibarEditorRows'];\n if(!isNaN(rows)){ rows = 15; }\n var editor = param.button.editor;\n editor.rows = rows;\n config.options['txtWikibarEditorRows'] = rows;\n saveOptionCookie('txtWikibarEditorRows');\n }\n }\n };\n toolset.SEPERATOR = {};\n toolset.update = {\n CAPTION: 'check for updates',\n DISABLED: true,\n HANDLER: function(){}\n };\n return toolset;\n}\nfunction wikibar_genPaletteSelector(){\n try{\n var cpTiddlers = store.getTaggedTiddlers('ColorPalettes');\n if(!cpTiddlers) { return; }\n var palettes=[];\n palettes.push(wikibarColorTool.defaultPaletteName);\n for(var i=0; i<cpTiddlers.length; i++){\n palettes.push(cpTiddlers[i].title.trim());\n }\n var toolset={};\n for(i=0; i<palettes.length; i++){\n toolset[palettes[i]] = {\n TOOLTIP: palettes[i],\n SELECTED: (palettes[i]==wikibarColorTool.paletteName),\n HANDLER: wikibar_doSelectPalette\n };\n }\n return toolset;\n }catch(ex){ return null; }\n}\nfunction wikibar_onClickItem(e){\n if(!e){ e = window.event; }\n var theTarget = resolveTarget(e);\n if(theTarget.tagName=='INPUT'){\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n return;\n }\n var theButton = wikibar_resolveTargetButton(theTarget);\n if(!theButton){ return(false); }\n var o = theButton.toolItem;\n if(!o) { return; }\n var param = {\n event: e,\n button: theButton\n };\n if(o.HANDLER){ o.HANDLER(param); }\n if(o.DISABLED){\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n }\n return(false);\n}\nfunction wikibar_onClickMenuItem(e){\n if(!e){ e = window.event; }\n var theButton = wikibar_resolveTargetButton(resolveTarget(e));\n if(!theButton){ return(false); }\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n var title = theButton.tiddlerTitle;\n var editor = theButton.editor;\n var tool = theButton.toolItem;\n if(!tool) { return; }\n var popup = wikibarPopup.create(this);\n if(popup){\n wikibar_createMenu(popup,tool,title,editor);\n if(!popup.hasChildNodes()){\n wikibarPopup.remove();\n }else{\n wikibarPopup.show(popup, false);\n }\n }\n return(false);\n}\nvar wikibarColorTool = {\n defaultPaletteName : 'default',\n defaultColumns : 16,\n defaultPalette : [\n '#FFF','#DDD','#CCC','#BBB','#AAA','#999','#666','#333','#111','#000','#FC0','#F90','#F60','#F30','#C30','#C03',\n '#9C0','#9D0','#9E0','#E90','#D90','#C90','#FC3','#FC6','#F96','#F63','#600','#900','#C00','#F00','#F36','#F03',\n '#CF0','#CF3','#330','#660','#990','#CC0','#FF0','#C93','#C63','#300','#933','#C33','#F33','#C36','#F69','#F06',\n '#9F0','#CF6','#9C3','#663','#993','#CC3','#FF3','#960','#930','#633','#C66','#F66','#903','#C39','#F6C','#F09',\n '#6F0','#9F6','#6C3','#690','#996','#CC6','#FF6','#963','#630','#966','#F99','#F39','#C06','#906','#F3C','#F0C',\n '#3F0','#6F3','#390','#6C0','#9F3','#CC9','#FF9','#C96','#C60','#C99','#F9C','#C69','#936','#603','#C09','#303',\n '#0C0','#3C0','#360','#693','#9C6','#CF9','#FFC','#FC9','#F93','#FCC','#C9C','#969','#939','#909','#636','#606',\n '#060','#3C3','#6C6','#0F0','#3F3','#6F6','#9F9','#CFC','#9CF','#FCF','#F9F','#F6F','#F3F','#F0F','#C6C','#C3C',\n '#030','#363','#090','#393','#696','#9C9','#CFF','#39F','#69C','#CCF','#C9F','#96C','#639','#306','#90C','#C0C',\n '#0F3','#0C3','#063','#396','#6C9','#9FC','#9CC','#06C','#369','#99F','#99C','#93F','#60C','#609','#C3F','#C0F',\n '#0F6','#3F6','#093','#0C6','#3F9','#9FF','#699','#036','#039','#66F','#66C','#669','#309','#93C','#C6F','#90F',\n '#0F9','#6F9','#3C6','#096','#6FF','#6CC','#366','#069','#36C','#33F','#33C','#339','#336','#63C','#96F','#60F',\n '#0FC','#6FC','#3C9','#3FF','#3CC','#399','#033','#39C','#69F','#00F','#00C','#009','#006','#003','#63F','#30F',\n '#0C9','#3FC','#0FF','#0CC','#099','#066','#3CF','#6CF','#09C','#36F','#0CF','#09F','#06F','#03F','#03C','#30C'\n ],\n colorPicker : null,\n pickColorHandler: null,\n userData: null\n};\nwikibarColorTool.paletteName = wikibarColorTool.defaultPaletteName;\nwikibarColorTool.columns = wikibarColorTool.defaultColumns;\nwikibarColorTool.palette = wikibarColorTool.defaultPalette;\nwikibarColorTool.onPickColor = function(e){\n if (!e){ e = window.event; }\n var theCell = resolveTarget(e);\n if(!theCell){ return(false); }\n color = theCell.bgColor.toLowerCase();\n if(!color) { return; }\n wikibarColorTool.displayColorPicker(false);\n if(wikibarColorTool.pickColorHandler){\n wikibarColorTool.pickColorHandler(color, wikibarColorTool.userData);\n }\n return(false);\n};\nwikibarColorTool.onMouseOver = function(e){\n if (!e){ e = window.event; }\n var theButton = resolveTarget(e);\n if(!theButton){ return(false); }\n if(!wikibarColorTool) { return; }\n color = theButton.bgColor.toUpperCase();\n if(!color) { return; }\n td=document.getElementById('colorPickerInfo');\n if(!td) { return; }\n td.bgColor = color;\n td.innerHTML = '<span style=\s"color:#000;\s">'+color+'</span>&nbsp;&nbsp;&nbsp;' +\n '<span style=\s"color:#fff;\s">'+color+'</span>';\n e.cancelBubble = true;\n if (e.stopPropagation){ e.stopPropagation(); }\n return(false);\n};\nwikibarColorTool.openColorPicker = function(theTarget, pickColorHandler, userData){\n wikibarColorTool.skipClickDocumentEvent = true;\n wikibarColorTool.pickColorHandler = pickColorHandler;\n wikibarColorTool.userData = userData;\n wikibarColorTool.moveColorPicker(theTarget);\n};\nwikibarColorTool.convert3to6HexColor = function(c){\n c=c.trim();\n var rx=/^\s#(\sd|[a-f])(\sd|[a-f])(\sd|[a-f])$/gi;\n return (rx.test(c)? c.replace(rx, '#$1$1$2$2$3$3') : c);\n};\nwikibarColorTool.numToHexColor = function (n){\n if(typeof(n)=='number' && (n>=0 && n<=255)) {\n s = n.toString(16).toLowerCase();\n return ((s.length==1)? '0'+s : s);\n }else{\n return null;\n }\n};\nwikibarColorTool.renderColorPalette = function(){\n if(wikibarColorTool.paletteName==wikibarColorTool.defaultPaletteName){\n wikibarColorTool.palette=wikibarColorTool.defaultPalette;\n wikibarColorTool.columns=wikibarColorTool.defaultColumns;\n return;\n }\n tiddlerText = (store.getTiddlerText(wikibarColorTool.paletteName, '')).trim();\n if(tiddlerText.length<=0) { return; }\n var cpContents = tiddlerText.split('\sn');\n var colors=[];\n columns = wikibarColorTool.defaultColumns;\n var tmpArray=null;\n errCount=0;\n for(var i=0; i<cpContents.length; i++){\n cpLine=cpContents[i].trim();\n if( (!cpLine) || (cpLine.length<=0) || (cpLine.charAt(0) == '#') ){ continue; }\n if(cpLine.substring(0,8).toLowerCase()=='columns:'){\n tmpArray = cpLine.split(':');\n try{\n columns = parseInt(tmpArray[1],10);\n }catch(ex){\n columns = wikibarColorTool.defaultColumns;\n }\n }else{\n tmpArray = cpLine.replace('\st', ' ').split(/[ ]{1,}/);\n try{\n color='';\n for(var j=0; j<3; j++){\n c=parseInt(tmpArray[j].trim(), 10);\n if(isNaN(c)){\n break;\n }else{\n c=wikibarColorTool.numToHexColor(c);\n if(!c) {break;}\n color+=c;\n }\n }\n if(color.length==6){\n colors.push('#'+color);\n } else {\n throw 'error';\n }\n }catch(ex){\n }\n }\n }\n if(colors.length>0){\n wikibarColorTool.palette = colors;\n wikibarColorTool.columns = columns;\n }else{\n throw 'renderColorPalette(): No color defined in the palette.';\n }\n};\nwikibarColorTool.displayColorPicker = function(visible){\n if(wikibarColorTool.colorPicker){\n wikibarColorTool.colorPicker.style.display = (visible? 'block' : 'none');\n }\n};\nwikibarColorTool.moveColorPicker = function(theTarget){\n if(!wikibarColorTool.colorPicker){\n wikibarColorTool.createColorPicker();\n }\n var cp = wikibarColorTool.colorPicker;\n var rootLeft = findPosX(theTarget);\n var rootTop = findPosY(theTarget);\n var popupLeft = rootLeft;\n var popupTop = rootTop;\n var popupWidth = cp.offsetWidth;\n var winWidth = findWindowWidth();\n if(popupLeft + popupWidth > winWidth){\n popupLeft = winWidth - popupWidth;\n }\n cp.style.left = popupLeft + 'px';\n cp.style.top = popupTop + 'px';\n wikibarColorTool.displayColorPicker(true);\n};\nwikibarColorTool.createColorPicker = function(unused, palette){\n if(palette){ wikibarColorTool.paletteName=palette; }\n wikibarColorTool.renderColorPalette();\n wikibarColorTool.colorPicker = document.createElement('div');\n wikibarColorTool.colorPicker.id = 'colorPicker';\n document.body.appendChild(wikibarColorTool.colorPicker);\n var theTable = document.createElement('table');\n wikibarColorTool.colorPicker.appendChild(theTable);\n var theTR = document.createElement('tr');\n theTable.appendChild(theTR);\n var theTD = document.createElement('td');\n theTD.className = 'header';\n theTD.colSpan = wikibarColorTool.columns;\n theTD.innerHTML = wikibarColorTool.paletteName;\n theTR.appendChild(theTD);\n for(var i=0; i<wikibarColorTool.palette.length; i++){\n if((i%wikibarColorTool.columns)===0){\n theTR = document.createElement('tr');\n theTable.appendChild(theTR);\n }\n theTD = document.createElement('td');\n theTD.className = 'cell';\n theTD.bgColor = wikibarColorTool.convert3to6HexColor(wikibarColorTool.palette[i]);\n theTD.onclick = wikibarColorTool.onPickColor;\n theTD.onmouseover = wikibarColorTool.onMouseOver;\n theTR.appendChild(theTD);\n }\n rest = wikibarColorTool.palette.length % wikibarColorTool.columns;\n if(rest>0){\n theTD = document.createElement('td');\n theTD.colSpan = wikibarColorTool.columns-rest;\n theTD.bgColor = '#000000';\n theTR.appendChild(theTD);\n }\n theTR = document.createElement('tr');\n theTable.appendChild(theTR);\n theTD = document.createElement('td');\n theTD.colSpan = wikibarColorTool.columns;\n theTD.id = 'colorPickerInfo';\n theTR.appendChild(theTD);\n};\nwikibarColorTool.onDocumentClick = function(e){\n if (!e){ e = window.event; }\n if(wikibarColorTool.skipClickDocumentEvent) {\n wikibarColorTool.skipClickDocumentEvent = false;\n return true;\n }\n if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){\n wikibarColorTool.displayColorPicker(false);\n }\n return true;\n};\nfunction wikibar_doSelectPalette(param){\n clearMessage();\n var theButton = param.button;\n if(!theButton.toolItem.key) { return; }\n var palette = theButton.toolItem.key;\n var oldPaletteName = wikibarColorTool.paletteName;\n if(oldPaletteName != palette){\n try{\n wikibarColorTool.createColorPicker(theButton, palette);\n displayMessage('Palette \s"'+palette+'\s" ('+ wikibarColorTool.palette.length +' colors) is selected');\n }catch(ex){\n errMsg = ex;\n if(errMsg.substring(0,18)=='renderColorPalette'){\n displayMessage('Invalid palette \s"' + palette + '\s", please check it out!');\n wikibarColorTool.createColorPicker(theButton, oldPaletteName);\n }\n }\n }\n}\nvar wikibarPopup = {\n skipClickDocumentEvent: false,\n stack: []\n};\nwikibarPopup.resolveRootPopup = function(o){\n if(o.isOnMainMenu){ return null; }\n if(o.className.substring(0,12)=='wikibarPopup'){ return o;}\n return wikibarPopup.resolveRootPopup(o.parentNode);\n};\nwikibarPopup.create = function(root){\n for(var i=0; i<wikibarPopup.stack.length; i++){\n var p=wikibarPopup.stack[i];\n if(p.root==root){\n wikibarPopup.removeFrom(i+1);\n return null;\n }\n }\n var rootPopup = wikibarPopup.resolveRootPopup(root);\n if(!rootPopup){\n wikibarPopup.remove();\n }else{\n wikibarPopup.removeFromRootPopup(rootPopup);\n }\n var popup = createTiddlyElement(document.body,'div','wikibarPopup'+root.toolItem.key,'wikibarPopup');\n var pop = createTiddlyElement(popup,'table','','');\n wikibarPopup.stack.push({rootPopup: rootPopup, root: root, popup: popup});\n return pop;\n};\nwikibarPopup.show = function(unused,slowly){\n var curr = wikibarPopup.stack[wikibarPopup.stack.length-1];\n var overlayWidth = 1;\n var rootLeft, rootTop, rootWidth, rootHeight, popupLeft, popupTop, popupWidth;\n if(curr.rootPopup){\n rootLeft = findPosX(curr.rootPopup);\n rootTop = findPosY(curr.root);\n rootWidth = curr.rootPopup.offsetWidth;\n popupLeft = rootLeft + rootWidth - overlayWidth;\n popupTop = rootTop;\n }else{\n rootLeft = findPosX(curr.root);\n rootTop = findPosY(curr.root);\n rootHeight = curr.root.offsetHeight;\n popupLeft = rootLeft;\n popupTop = rootTop + rootHeight;\n }\n var winWidth = findWindowWidth();\n popupWidth = curr.popup.offsetWidth;\n if(popupLeft + popupWidth > winWidth){\n popupLeft = rootLeft - popupWidth + overlayWidth;\n }\n curr.popup.style.left = popupLeft + 'px';\n curr.popup.style.top = popupTop + 'px';\n curr.popup.style.display = 'block';\n addClass(curr.root, 'highlight');\n if(config.options.chkAnimate){\n anim.startAnimating(new Scroller(curr.popup,slowly));\n }else{\n window.scrollTo(0,ensureVisible(curr.popup));\n }\n};\nwikibarPopup.remove = function(){\n if(wikibarPopup.stack.length > 0){\n wikibarPopup.removeFrom(0);\n }\n};\nwikibarPopup.removeFrom = function(from){\n for(var t=wikibarPopup.stack.length-1; t>=from; t--){\n var p = wikibarPopup.stack[t];\n removeClass(p.root,'highlight');\n p.popup.parentNode.removeChild(p.popup);\n }\n wikibarPopup.stack = wikibarPopup.stack.slice(0,from);\n};\nwikibarPopup.removeFromRootPopup = function(from){\n for(var t=0; t<wikibarPopup.stack.length; t++){\n var p = wikibarPopup.stack[t];\n if(p.rootPopup==from){\n wikibarPopup.removeFrom(t);\n break;\n }\n }\n};\nwikibarPopup.onDocumentClick = function(e){\n if (!e){ e = window.event; }\n if(wikibarPopup.skipClickDocumentEvent){\n wikibarPopup.skipClickDocumentEvent=false;\n return true;\n }\n if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){\n wikibarPopup.remove();\n }\n return true;\n};\nvar wikibarStore = {\n TYPE: 'MAIN_MENU',\n help:{\n TYPE:'MENU',\n CAPTION: '<font face=\s"verdana\s">?</font>',\n TOOLTIP: 'about WikiBar',\n options:{\n TYPE:'MENU',\n DYNAITEM: wikibar_genWikibarOptions\n },\n about:{\n TYPE:'MENU',\n DYNAITEM: wikibar_genWikibarAbout\n }\n },\n preview:{\n TOOLTIP: 'preview this tiddler',\n CAPTION: '<font face=\s"verdana\s">&infin;</font>',\n HANDLER: wikibar_doPreview\n },\n line:{\n TOOLTIP: 'horizontal line',\n CAPTION: '<font face=\s"verdana\s">&mdash;</font>',\n syntax: '\sn----\sn',\n HANDLER: wikibar_editFormatByCursor\n },\n crlf:{\n TOOLTIP: 'new line',\n CAPTION: '<font face=\s"verdana\s">&para;</font>',\n syntax: '\sn',\n HANDLER: wikibar_editFormatByCursor\n },\n selectAll:{\n TOOLTIP: 'select all',\n CAPTION: '<font face=\s"verdana\s">&sect;</font>',\n HANDLER: wikibar_editSelectAll\n },\n deleteSelected:{\n TOOLTIP: 'delete selected',\n CAPTION: '<font face=\s"verdana\s">&times;</font>',\n syntax: '',\n HANDLER: wikibar_editFormat\n },\n textFormat:{\n TYPE: 'MENU',\n CAPTION: 'text',\n TOOLTIP: 'text formatters',\n ignore:{\n TOOLTIP: 'ignore wiki word',\n CAPTION: 'ignore wikiWord',\n syntax: '~user_text',\n hint: 'wiki_word',\n HANDLER: wikibar_editFormatByWord\n },\n bolder:{\n TOOLTIP: 'bolder text',\n CAPTION: '<strong>bolder</strong>',\n syntax: "''user_text''",\n hint: 'bold_text',\n HANDLER: wikibar_editFormatByWord\n },\n italic:{\n TOOLTIP: 'italic text',\n CAPTION: '<em>italic</em>',\n syntax: '\s/\s/user_text\s/\s/',\n hint: 'italic_text',\n HANDLER: wikibar_editFormatByWord\n },\n underline:{\n TOOLTIP: 'underline text',\n CAPTION: '<u>underline</u>',\n syntax: '__user_text__',\n hint: 'underline_text',\n HANDLER: wikibar_editFormatByWord\n },\n strikethrough:{\n TOOLTIP: 'strikethrough text',\n CAPTION: '<strike>strikethrough</strike>',\n syntax: '==user_text==',\n hint: 'strikethrough_text',\n HANDLER: wikibar_editFormatByWord\n },\n superscript:{\n TOOLTIP: 'superscript text',\n CAPTION: 'X<sup>superscript</sup>',\n syntax: '^^user_text^^',\n hint: 'superscript_text',\n HANDLER: wikibar_editFormatByWord\n },\n subscript:{\n TOOLTIP: 'subscript text',\n CAPTION: 'X<sub>subscript</sub>',\n syntax: '~~user_text~~',\n hint: 'subscript_text',\n HANDLER: wikibar_editFormatByWord\n },\n comment:{\n TOOLTIP: 'comment text',\n CAPTION: 'comment text',\n syntax: '/%user_text%/',\n hint: 'comment_text',\n HANDLER: wikibar_editFormatByWord\n },\n monospaced:{\n TOOLTIP: 'monospaced text',\n CAPTION: '<code>monospaced</code>',\n syntax: '{{{user_text}}}',\n hint: 'monospaced_text',\n HANDLER: wikibar_editFormatByWord\n }\n },\n paragraph:{\n TYPE: 'MENU',\n TOOLTIP: 'paragarph formatters',\n list:{\n TYPE: 'MENU',\n TOOLTIP: 'list tools',\n bullet:{\n TOOLTIP: 'bullet point',\n syntax: '*user_text',\n hint: 'bullet_text',\n HANDLER: wikibar_editFormatByLine\n },\n numbered:{\n TOOLTIP: 'numbered list',\n syntax: '#user_text',\n hint: 'numbered_text',\n HANDLER: wikibar_editFormatByLine\n }\n },\n heading:{\n TYPE: 'MENU',\n heading1:{\n CAPTION:'<h1>Heading 1</h1>',\n TOOLTIP: 'Heading 1',\n syntax: '!user_text',\n hint: 'heading_1',\n HANDLER: wikibar_editFormatByLine\n },\n heading2:{\n CAPTION:'<h2>Heading 2<h2>',\n TOOLTIP: 'Heading 2',\n syntax: '!!user_text',\n hint: 'heading_2',\n HANDLER: wikibar_editFormatByLine\n },\n heading3:{\n CAPTION:'<h3>Heading 3</h3>',\n TOOLTIP: 'Heading 3',\n syntax: '!!!user_text',\n hint: 'heading_3',\n HANDLER: wikibar_editFormatByLine\n },\n heading4:{\n CAPTION:'<h4>Heading 4</h4>',\n TOOLTIP: 'Heading 4',\n syntax: '!!!!user_text',\n hint: 'heading_4',\n HANDLER: wikibar_editFormatByLine\n },\n heading5:{\n CAPTION:'<h5>Heading 5</h5>',\n TOOLTIP: 'Heading 5',\n syntax: '!!!!!user_text',\n hint: 'heading_5',\n HANDLER: wikibar_editFormatByLine\n }\n },\n comment:{\n TYPE: 'MENU',\n commentByLine:{\n CAPTION:'comment by line',\n TOOLTIP: 'line comment',\n syntax: '/%user_text%/',\n hint: 'comment_text',\n HANDLER: wikibar_editFormatByLine\n },\n commentByBlock:{\n CAPTION:'comment by block',\n TOOLTIP: 'block comment',\n syntax: '/%\snuser_text\sn%/',\n hint: 'comment_text',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n },\n monospaced:{\n TYPE: 'MENU',\n monosByLine:{\n CAPTION: 'monospaced by line',\n TOOLTIP: 'line monospaced',\n syntax: '{{{\snuser_text\sn}}}',\n hint: 'monospaced_text',\n HANDLER: wikibar_editFormatByLine\n },\n monosByBlock:{\n CAPTION: 'monospaced by block',\n TOOLTIP: 'block monospaced',\n syntax: '{{{\snuser_text\sn}}}',\n hint: 'monospaced_text',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n },\n quote:{\n TYPE: 'MENU',\n quoteByLine:{\n CAPTION: 'quote by line',\n TOOLTIP: 'line quote',\n syntax: '>user_text',\n hint: 'quote_text',\n HANDLER: wikibar_editFormatByLine\n },\n quoteByBlcok:{\n CAPTION: 'quote by block',\n TOOLTIP: 'block quote',\n syntax: '<<<\snuser_text\sn<<<',\n hint: 'quote_text',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n },\n plugin:{\n TYPE: 'MENU',\n code:{\n CAPTION: 'code area',\n TOOLTIP: 'block monospaced for plugin',\n syntax: '\sn\s/\s/{{{\snuser_text\sn\s/\s/}}}\sn',\n hint: 'monospaced_plugin_code',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n },\n commentByLine:{\n CAPTION: 'comment by line',\n TOOLTIP: 'line comment',\n syntax: '\s/\s/user_text',\n hint: 'plugin_comment',\n HANDLER: wikibar_editFormatByLine\n },\n commentByBlock:{\n CAPTION: 'comment by block',\n TOOLTIP: 'block comment',\n syntax: '\s/\s***\snuser_text\sn***\s/',\n hint: 'plugin_comment',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n },\n css:{\n TYPE: 'MENU',\n code:{\n CAPTION: 'code area',\n TOOLTIP: 'block monospaced for css',\n syntax: '\sn\snuser_text\sn\sn',\n hint: 'monospaced_css_code',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n },\n commentByLine:{\n CAPTION: 'comment by line',\n TOOLTIP: 'line comment',\n syntax: '',\n hint: 'css_comment',\n HANDLER: wikibar_editFormatByLine\n },\n commentByBlock:{\n CAPTION: 'comment by block',\n TOOLTIP: 'block comment',\n syntax: '',\n hint: 'css_comment',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n }\n },\n color:{\n TYPE: 'MENU',\n TOOLTIP: 'color tools',\n highlight:{\n CAPTION:'highlight text',\n TOOLTIP: 'highlight text',\n syntax: '@@user_text@@',\n hint: 'highlight_text',\n HANDLER: wikibar_editFormatByWord\n },\n color:{\n CAPTION:'text color',\n TOOLTIP: 'text color',\n hint: 'your_text',\n syntax: '@@color(%1):user_text@@',\n HANDLER: wikibar_getColorCode,\n doMore: wikibar_editFormatByWord\n },\n bgcolor:{\n CAPTION:'background color',\n TOOLTIP: 'background color',\n hint: 'your_text',\n syntax: '@@bgcolor(%1):user_text@@',\n HANDLER: wikibar_getColorCode,\n doMore: wikibar_editFormatByWord\n },\n colorcode:{\n CAPTION:'color code',\n TOOLTIP: 'insert color code',\n syntax: '%1',\n HANDLER: wikibar_getColorCode,\n doMore: wikibar_editFormatByCursor\n },\n 'color palette':{\n TYPE:'MENU',\n DYNAITEM: wikibar_genPaletteSelector,\n SEPERATOR:{},\n morePalette:{\n CAPTION:'more palettes',\n TOOLTIP:'get more palettes',\n HANDLER: wikibar_getMorePalette\n }\n }\n },\n link:{\n TYPE: 'MENU',\n TOOLTIP: 'insert link',\n wiki:{\n CAPTION:'wiki link',\n TOOLTIP: 'wiki link',\n syntax: '[[user_text]]',\n hint: 'wiki_word',\n HANDLER: wikibar_editFormatByWord\n },\n pretty:{\n CAPTION: 'pretty link',\n TOOLTIP: 'pretty link',\n syntax: '[[user_text|%1]]',\n hint: 'pretty_word',\n param: 'PrettyLink Target',\n HANDLER: wikibar_getLinkUrl,\n doMore: wikibar_editFormatByWord\n },\n url:{\n TOOLTIP: 'url link',\n syntax: '[[user_text|%1]]',\n hint: 'your_text',\n param: 'http:\s/\s/...',\n HANDLER: wikibar_getLinkUrl,\n doMore: wikibar_editFormatByWord\n },\n image:{\n TOOLTIP: 'image link',\n syntax: '[img[user_text|%1]]',\n hint: 'alt_text',\n param: 'image/icon.jpg',\n HANDLER: wikibar_getLinkUrl,\n doMore: wikibar_editFormatByWord\n }\n },\n macro:{},\n more:{\n TYPE: 'MENU',\n TOOLTIP: 'more tools',\n table:{\n TYPE: 'MENU',\n TOOLTIP: 'table',\n table:{\n CAPTION:'create table',\n TOOLTIP: 'create a new table',\n syntax: '\sn%1\sn',\n HANDLER: wikibar_getTableRowCol,\n doMore: wikibar_editFormatByWord\n },\n header:{\n TOOLTIP: 'table header text',\n syntax: '|user_text|c',\n hint: 'table_header',\n HANDLER: wikibar_editFormatByWord\n },\n cell:{\n TOOLTIP: 'create a tabel cell',\n syntax: '|user_text|',\n hint: 'your_text',\n HANDLER: wikibar_editFormatByWord\n },\n columnHeader:{\n CAPTION:'column header',\n TOOLTIP: 'create a column header cell',\n syntax: '|!user_text|',\n hint: 'column_header',\n HANDLER: wikibar_editFormatByWord\n },\n cell:{\n TYPE: 'MENU',\n CAPTION: 'cell options',\n bgcolor:{\n CAPTION: 'background color',\n TOOLTIP: 'cell bgcolor',\n syntax: '|bgcolor(%1):user_text|',\n hint: 'your_text',\n HANDLER: wikibar_getColorCode,\n doMore: wikibar_editFormatByTableCell\n },\n alignLeft:{\n CAPTION: 'align left',\n TOOLTIP: 'left align cell text',\n syntax: '|user_text|',\n hint: 'your_text',\n HANDLER: wikibar_editFormatByTableCell\n },\n alignCenter:{\n CAPTION: 'align center',\n TOOLTIP: 'center align cell text',\n syntax: '| user_text |',\n hint: 'your_text',\n HANDLER: wikibar_editFormatByTableCell\n },\n alignRight:{\n CAPTION: 'align right',\n TOOLTIP: 'right align cell text',\n syntax: '| user_text|',\n hint: 'your_text',\n HANDLER: wikibar_editFormatByTableCell\n }\n }\n },\n html:{\n TYPE: 'MENU',\n html:{\n CAPTION: '&lt;html&gt;',\n TOOLTIP: 'html tag',\n syntax: '<html>\snuser_text\sn</html>',\n hint: 'html_content',\n byBlock: true,\n HANDLER: wikibar_editFormatByLine\n }\n }\n },\n addon:{\n TYPE: 'MENU',\n TOOLTIP:'3rd party tools',\n 'about addons':{\n TOOLTIP: 'list loaded addons',\n HANDLER: wikibar_doListAddons\n },\n SEPERATOR:{}\n }\n};\naddEvent(document, 'click', wikibarColorTool.onDocumentClick);\naddEvent(document, 'click', wikibarPopup.onDocumentClick);\nwikibar_install();\n//}}}\n\n\n
<<slider about [[Programming]] [[Programming]] 'Programming'>>\n<<slider about [[Work]] 'Work'>>\n[[Books|Books]]\n<<tag Links>>\n[[Memo|Memo]]\n[[INDEX|INDEX]]\n\n
<html><a href="http://sourceforge.net" target="_blank"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=156016&amp;type=1" width="88" height="31" border="0" alt="SourceForge.net Logo" /> </a></html>
친구 홈피, 게임, 프로그래밍 참고 사이트, 유용한 사이트, 기타...
Notice crazygats Work\n
* 프로젝트 만들기\n코드명 짓기 - 이건 최상위 디렉터리 이름이 된다.\n버전별로 다른 코드명을 사용할수도..\n\n* 디렉터리 구조 만들기\n|Directory|Contents|h\n|doc|디자인문서, 기술명세서 등.( 케릭터스크립트, 인터페이스디자인, 기타등등)|\n|source|소스코드( 프로젝트별로 별도의 디렉터리를 생성할수도.. )|\n|output or obj|debug, release 디렉터리로 구분해서 빌드대상 임시파일 저장. 프로젝트별로 별도의 디렉터리로 구분하는게 좋을듯..|\n|bin|프로젝트의 release 빌드와 게임데이터들|\n|lib|프로젝트에서 링크해서 쓰는 각종 라이브러리들|\n|test|게임의 디버그빌드와 테스트 팀에 필요한 특별한 파일들( 테스트 스크립트, 치트활성화 파일, 테스트 유틸리티, 릴리즈노트 등.. )|\n\n엔진은 별도로 위와 같은 디렉터리를 가지도록..\n별도의 헤더파일만 저장할 수 있는 디렉터리가 있으면 좋을듯..\n\n* Visual Studio 빌드옵션 설정\n.Net 의 프로젝트 속성창에서 조절할 수 있다.\n//{{{\n구성 속성( Configuration Properties )\n 일반(General)\n 출력 디렉터리(Output Directory) - ..\sbin\s(release) or ..\stest\s(debug)\n 중간파일 디렉터리(Intermediate Directory) - ..\soutput\sdebug or ..\soutput\srelease\n \n 디버깅(Debugging)\n 작업 디렉터리(Working Directory) - ..\sbin\n링커(Linker)\n 일반(General)\n 출력파일(Output file) - $(OutDir)\s$(ProjectName).exe or $(OutDir)\s$(ProjectName)_d.exe\n//}}}\n\n|Visual Studio.NET 매크로|Contents|h\n|$(IntDir)|중간 파일들의 경로(..\soutput\sdebug or ..\soutput\srelease)|\n|$(OutDir)|출력 디렉터리의 경로(..\sbin\s or ..\stest\s)|\n|$(TargetDir)|기본 출력 파일의 경로|\n|$(TargetName)|기본 출력 파일의 이름. 확장자는 붙이지 않음.|\n|$(TargetPath)|출력 파일의 완전한 경로와 파일 이름|\n\n위 매크로들은 아래 설정들에 사용가능\n|Properties|Contents|h\n|Debugging / Debugging Command|$(TargetPath)는 각 빌드 대상에 맞는 적절한 실행 파일을 호출한다.|\n|Debugging / Working Directory|항상 ..\sbin 으로 설정할것. 모든 빌드 대상에 작동한다.|\n|C/C++ / Precompiled Headers / Precompiled Header File|$(IntDir)$(TargetName).pch|\n|C/C++ / Output Files|ASM 리스트 위치, 목적 파일 이름, 프로그램 데이터베이스 파일 이름에 $(IntDir)를 사용한다.|\n|C/C++ / Browse Information / Browse Files|$(IntDir)|\n|Linker / Debug Settings / Generate Program Database File|$(IntDir)$(TargetName).pdb|\n|Linker / Debug Settings / Map File|$(IntDir)$(TargetName).map|\n----\n* 빌드 구성\n두개이상의 빌드 대상들 - Debug, Release, 기타..\n릴리즈빌드에서는 최적화 활성, 기호들이나 기타 디버그정보는 출력파일에 포함시키지 않도록..\n\n주의 - 모든 빌드 대상들이 항상 제대로 작동하도록 관리할 것. 특히 릴리즈 빌드. 나중에 안돌아가면 대략 난감.\n----
\n[[CommentPluginStyle]]
/*{{{*/\n/*Monochrome Theme for TiddlyWiki*/\n/*Design and CSS by Saq Imtiaz*/\n/*Version 1.0*/\n/*}}}*/\n/*{{{*/\n\nbody {background:#3B3B3B; color:#C3C3C3; font:12px Verdana, Helvetica, sans-serif;\n }\n\n#header {padding: 0em 0em 0em 0em; background:transparent; font-family: arial,helvetica; font-size:12px;\n }\n\n.siteTitle {\npadding-top:5px;\nfloat:left;\nfont-family: 'Trebuchet MS' sans-serif;\nfont-weight: bold;\nfont-size: 32px;\ncolor: #ccc; margin-right:2em;margin-left:0.5em;\n}\n\n#topMenu br {display:none;}\n#topMenu a, #topMenu .tiddlyLink, #topMenu .button {margin:0em; color:#666; padding:15px 15px 10px 15px;padding-top:1.6em;border:none; border-right: 1px solid #666;float:left;}\n#topMenu {border-left: 1px solid #666; float:left;margin:0;}\n#topMenu a:hover {color:#ccc; background:#3b3b3b;}\n\n#displayArea {margin-left:1.35em; margin-right:17.65em; margin-top:0.5em; padding-top:1em; padding-bottom:10px;}\n\n.tiddler {background:#454545; margin-bottom:20px; padding:1em 2em 1em 2em;}\n\na, a:hover{\ncolor:#fff;\ntext-decoration: none; background:transparent;\n}\n\n.viewer a, .viewer a:hover{border-bottom:1px dotted #fff; font-weight:normal;}\n\n.viewer .button, .editorFooter .button{\ncolor: #fff;\nborder: 1px solid #fff;\n}\n\n.viewer .button:hover,\n.editorFooter .button:hover, .viewer .button:active, .viewer .highlight,.editorFooter .button:active, .editorFooter .highlight{\ncolor: #fff;\nbackground: #3B3B3B;\nborder-color: #3B3B3B;\n}\n\n.title {color:#ccc; font-family:'Lucida Grande', Verdana, Sans-Serif; font-size:1.5em;\n}\n\n.subtitle, .subtitle a { color: #777; font-size: 0.95em;margin:0.2em;}\n.shadow .title{color:#777;}\n\n.toolbar {font-size:90%;}\n.selected .toolbar a {color:#666;border:0;}\n.selected .toolbar a:hover {color:#999; background:transparent;border:0;}\n\n.toolbar .button:hover, .toolbar .highlight, .toolbar .marked, .toolbar a.button:active{color:#666;border:0; background:transparent;border:0;}\n\n.tagging, .tagged {\nborder: 1px solid #555;\nbackground-color: #444;\n}\n\n.selected .tagging, .selected .tagged {\nbackground-color: #3B3B3B;\nborder: 1px solid #666;\n}\n\n.tagging .listTitle, .tagged .listTitle {\ncolor: #666;\n}\n\n.selected .tagging .listTitle, .selected .tagged .listTitle {\ncolor: #aaa;\n}\n\n.tagging .button, .tagged .button {\ncolor: #838383;\n}\n.selected .tagging .button, .selected .tagged .button {\ncolor:#c3c3c3;\n}\n\n.highlight, .marked {background:transparent; color:#111; border:none; text-decoration:underline;}\n\n.tagging .button:hover, .tagged .button:hover, .tagging .button:active, .tagged .button:active {\nborder: none; background:transparent; text-decoration:underline; color:#333;\n}\n\n#sidebarOptions {margin-top:1em;}\n#sidebar {margin-right:1.35em;}\n\n#sidebarTabs .tabContents { \n font-family: arial,helvetica;}\n\n#sidebarOptions a, #sidebarOptions a:hover{border:none;color:#666;}\n#sidebarOptions a:hover, #sidebarOptions a:active {background:#454545; color:#ccc;}\n#sidebarTabs .tabContents {background:#454545;border:0px solid #666; border-right:1px solid #454545;}\n#sidebarOptions input {background:#ccc; border:1px solid #666;}\n\n#sidebarTabs .tabContents .tiddlyLink, #sidebarTabs .tabContents .button{color:#666;font-weight:normal;}\n#sidebarTabs .tabContents .tiddlyLink:hover, #sidebarTabs .tabContents .button:hover {color:#ccc; background:transparent;}\n.listTitle {color:#777;}\n\n#sidebarTabs .tabSelected,#sidebarTabs .tabSelected:hover{background:#454545;border:none;color:#ccc; border:1px solid #454545;}\n#sidebarTabs .tabUnselected{background:#3B3B3B; border:1px solid #454545; color:#666;}\n\n #sidebarTabs .txtMoreTab .tabSelected,\n #sidebarTabs .txtMoreTab .tab:hover,\n #sidebarTabs .txtMoreTab .tabContents{\ncolor: #ccc;\nbackground: #3B3B3B; border:1px solid #3B3B3B;\n}\n\n #sidebarTabs .txtMoreTab .tabUnselected {\n\ncolor: #777; border:1px solid #3B3B3B;\nbackground: #454545;\n}\n\n\n#sidebarTabs .tabContents .button:hover, #sidebarTabs .tabContents .highlight, #sidebarTabs .tabContents .marked, #sidebarTabs .tabContents a.button:active{color:#ccc; background:transparent;}\n\n #sidebarOptions .sliderPanel {\nbackground: #454545; font-size: .9em;\n}\n\n#sidebarOptions .sliderPanel input {border:1px solid #666; background:#ccc;}\n#sidebarOptions .sliderPanel .txtOptionInput {border:1px solid #666;width:9em;}\n\n#sidebarOptions .sliderPanel a {font-weight:normal; color:#666;background-color: #454545; border-bottom:1px dotted #333;}\n\n#sidebarOptions .sliderPanel a:hover {\ncolor:#ccc;\nbackground-color: #454545;\nborder:none;\nborder-bottom:1px dotted #111;\n}\n\n.popup {\nbackground: #3B3B3B;\nborder: 1px solid #454545;\n}\n\n.popup li.disabled {\ncolor: #000;\n}\n\n.popup li a, .popup li a:visited {\ncolor: #777;\nborder: none;\n}\n\n.popup li a:hover {\nbackground: #3b3b3b;\ncolor: #c3c3c3;\nborder: none;\n}\n.popup hr {\n color: #777;\n background: #777;\n border-bottom: 1px;\n}\n\n.listBreak div{\n border-bottom: 1px solid #777;\n}\n\n#messageArea {\nborder: 4px dotted #ccc;\nbackground: #454545;\ncolor: #777;\nfont-size:90%;\n}\n\n#messageArea .button{\n\ncolor: #3B3B3B;\nbackground:#ccc;\nborder: 1px solid #ccc;\n}\n\n#messageArea .button:hover {\n\ncolor: #ccc;\nbackground: #3B3B3B;\nborder-color: #3B3B3B;\n}\n\n.viewer blockquote {\nborder-left: 5px solid #3B3B3B; background:#3B3B3B\n}\n\n.viewer table, .viewer td {\nborder: 1px solid #2E2E2E;\n}\n\n.viewer th, thead td {\nbackground: #3B3B3B;\nborder: 1px solid #3B3B3B;\ncolor: #ccc;\n}\n.viewer pre {\nborder: 1px solid #3b3b3b;\nbackground: #5F5F5F;\n}\n\n.viewer code {\ncolor: #c3c3c3; background:#5f5f5f;\n}\n\n.viewer hr {\nborder-top: dashed 1px #222; margin:0 1em;\n}\n\n.editor input {\nborder: 1px solid #ccc; margin-top:5px;\n}\n\n.editor textarea {\nborder: 1px solid #ccc;\n}\n\nh1,h2,h3,h4,h5 { color: #9c9c9c; background: transparent; padding-bottom:2px; font-family: Arial, Helvetica, sans-serif; }\nh1 {font-size:18px;}\nh2 {font-size:16px;}\nh3 {font-size: 14px;}
Crazygats
* 이 름 : 강 현 진\n* 닉네임 : Crazygats\n* 나 이 : 30대 초반.\n* 취 미 : 게임하기( 주로 총질을 많이함 )\n* 태어난 곳 : 따뜻한 남쪽나라 부산.\n* 직 업 : 게임프로그래머.\n* 수상 경력 : 동명정보기술원에서 팀 프로젝트로 만든 "모리노리" 란 게임으로 Full 3D realtime Herd simulation game( 일명 양치기게임 ) 2004년 10월 17일, 제 5회 성균관대학교 게임개발경진대회 대학일반부 장려상 수상.\n* 이수과정 : 동명정보대학교 정보기술원 3D 게임 프로그램과정 5기 수료.\n* 경 력 : \n** 2004.7 ~ 2006.11 : [[태울엔터테인먼트|http://www.taewool.co.kr/]]\n*** 키린온라인 클라이언트 - UI 툴 및 UI 수정작업, 컨텐츠 추가 작업.\n*** 시아온라인 태국 서비스 클라이언트 - 태국어 변환 작업.\n*** 시아온라인 중국 서비스 클라이언트 - 중국어 변환 작업, 추가 컨텐츠 작업.\n*** 시아온라인 엔진 TFT - 케릭터시스템 & 오브젝트 매니저 수정. 환경시스템 수정.\n*** 칠검온라인 엔진 TFT - Shadow System 구현. World Editor & Character Tool 수정.\n*** 3D Engine 팀(자체엔진개발) - DB 연동 툴 설계 및 제작.(지형툴, 모델툴, 월드툴, 이텍트툴)\n** 2006.12 ~ 2008.1 : [[인터렉티비|http://www.interactivy.com/]], [[팻마우스|http://www.fatmouse.co.kr/]]\n*** 3인칭 슈팅게임 [[타임키드|http://www.timekid.co.kr]] 알파 버전 제작.(상용엔진 Gamebryo 2.3 사용)\n*** 클라이언트 파트장 & 메인프로그래머.\n*** Main Framework, Character Animation, Effect System, Game Character System, Scene Manager 담당.\n** 2008.1 ~ 2008.5 : 베스트플로우, [[한얼소프트|http://www.haneolsoft.com/]]\n*** [[거상온라인|http://www.gersang.co.kr/]] 차기작 프로토타입 제작. - 클라이언트 메인.\n** 2008.8 ~ 2009.12 : [[T3 Entertainment|http://http://www.t3.co.kr]]\n*** 오디션2 - 중국 C9 사내테스트, 예당 사내테스트 & FGT\n*** 클라이언트 파트장 \n*** 리소스매니징 시스템 추가, 아바타시스템 리펙토링(불필요한 클래스 제거 및 통합, 파츠데이타 로딩제어, 아바타로딩 개선, 아바타메니저 수정, 아바타스크립트 수정), SceneInterface(State, Window) System 리펙토링, 스크립트 로딩 관리 개선, 네트워크 모듈교체에 따른 모든 패킷 및 로직 수정, 이펙트 시스템 교체, 로딩프로세스 개선( 이펙트 로딩, 댄스모션 로딩 수정), 미니볼륨시스템추가, 관전기능 추가. 보안솔루션 X-Trap 연동 구현\n \n* 하고 싶은 것들 : 나의 이름으로 게임을 만들고 싶다.
[[MochaStyleSheet]]
<!--{{{-->\n<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>\n<div class='headerShadow'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n<div class='headerForeground'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n</div>\n<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>\n<div id='sidebar'>\n<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n<div id='sidebarCopyright' refresh='content' tiddler='Copyright'></div>\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n</div>\n<!--}}}-->
<div>\n[[MochaPageTemplate]]\n</div>\n
/*{{{*/\n/*Mocha TiddlyWiki Theme*/\n/*Version 1.0*/\n/*Design and CSS originally by Anthonyy, ported to TiddlyWiki by Saq Imtiaz.*/\n/*}}}*/\n/*{{{*/\n #contentWrapper{\nmargin: 0 3.4em;\n\n font-family: Lucida Grande, Tahoma, Arial, Helvetica, sans-serif; /* Lucida Grande for the Macs, Tahoma for the PCs */\nfont-size: 11px;\n line-height: 1.6em;\n color: #666;\n}\n\n.header {\n background: #fff; \n padding-top: 10px;\n clear: both;\n\nborder-bottom: 4px solid #948979;\n}\n\n.headerShadow { padding: 2.6em 0em 0.5em 0em; }\n\n.siteTitle {\n font-family: 'Trebuchet MS' sans-serif;\n font-weight: bold;\n font-size: 32px;\n color: #CC6633;\n margin-bottom: 30px;\n background-color: #FFF;\n}\n\n.siteTitle a{color:#CC6633; border-bottom:1px dotted #cc6633;}\n\n.siteSubtitle {\n font-size: 1.0em;\n display: block;\n margin: .5em 3em; color: #999999;\n}\n\n#mainMenu {\nposition:relative;\nfloat:left;\nmargin-bottom:1em;\ndisplay:inline;\ntext-align:left;\npadding: 2em 0.5em 0.5em 0em;\nwidth:13em;\nfont-size:1em;\n}\n\n#sidebar{\nposition:relative;\nfloat:right;\nmargin-bottom:1em;\npadding-top:2em;\ndisplay:inline;\n\n}\n\n#displayArea {\n margin: 0em 17em 0em 15em;\n}\n\n.tagClear {clear:none;}\n\n#contentFooter {background:#575352; color:#BFB6B3; clear: both; padding: 0.5em 1em;}\n\n \n #contentFooter a {\n color: #BFB6B3;\n border-bottom: 1px dotted #BFB6B3;\n }\n \n #contentFooter a:hover {\n color: #FFFFFF;\n background-color:#575352;\n }\n\n a,#sidebarOptions .sliderPanel a{\n color:#CC6714;\n text-decoration: none;\n }\n\n a:hover,#sidebarOptions .sliderPanel a:hover {\n color:#CC6714;\n background-color: #F5F5F5; \n }\n\n.viewer .button, .editorFooter .button{\n color: #666;\n border: 1px solid #CC6714;\n}\n\n.viewer .button:hover, \n.editorFooter .button:hover{\n color: #fff;\n background: #CC6714;\n border-color: #CC6714;\n}\n\n.viewer .button:active, .viewer .highlight,.editorFooter .button:active, .editorFooter .highlight{color:#fff; background:#575352;border-color:#575352;}\n\n\n #mainMenu a {\n display: block;\n padding: 5px;\n border-bottom: 1px solid #CCC;\n }\n\n #mainMenu a:link, #navlist a:visited {\n color:#CC6714;\n text-decoration: none;\n }\n \n #mainMenu a:hover {\n background: #000000 url(arrow.gif) 96% 50% no-repeat;\n background-color: #F5F5F5;\n color:#CC6714;\n }\n \n #mainMenu a:hover, #mainMenu a:active, #mainMenu .highlight, #mainMenu .marked {\n background: #000000 url(arrow.gif) 96% 50% no-repeat;\n background-color: #F5F5F5;\n color:#CC6714;\n }\n\n#mainMenu span {position:relative;}\n\n#mainMenu br {display:none;}\n\n#sidebarOptions a {\n color:#999;\n text-decoration: none;\n }\n\n#sidebarOptions a:hover {\n color:#4F4B45;\n background-color: #F5F5F5;border:1px solid #fff;\n }\n\n#sidebarOptions {line-height:1.4em;}\n\n .tiddler {\n padding-bottom: 40px;\n border-bottom: 1px solid #DDDDDD; \n }\n.title {color:#CC6633;}\n.subtitle, .subtitle a { color: #999999; font-size: 1.0em;margin:0.2em;}\n.shadow .title{color:#948979;}\n\n.selected .toolbar a {color:#999999;}\n.selected .toolbar a:hover {color:#4F4B45; background:transparent;border:1px solid #fff;}\n\n.toolbar .button:hover, .toolbar .highlight, .toolbar .marked, .toolbar a.button:active{color:#4F4B45; background:transparent;border:1px solid #fff;}\n\n .listLink,#sidebarTabs .tabContents {line-height:1.5em;}\n .listTitle {color:#888;}\n\n#sidebarTabs .tabContents {background:#fff;}\n#sidebarTabs .tabContents .tiddlyLink, #sidebarTabs .tabContents .button{color:#999;}\n#sidebarTabs .tabContents .tiddlyLink:hover,#sidebarTabs .tabContents .button:hover{color:#4F4B45;background:#fff}\n\n#sidebarTabs .tabContents .button:hover, #sidebarTabs .tabContents .highlight, #sidebarTabs .tabContents .marked, #sidebarTabs .tabContents a.button:active{color:#4F4B45;background:#fff}\n\n.tabSelected{color:#fff; background:#948979;}\n\n.tabUnselected {\n background: #ccc;\n}\n\n .tabSelected, .tabSelected:hover {\n color: #fff;\n background: #948979;\n border: solid 1px #948979;\npadding-bottom:1px;\n}\n\n .tabUnselected {\n color: #999;\n background: #eee;\n border: solid 1px #ccc;\npadding-bottom:1px;\n}\n\n#sidebarTabs .tabUnselected { border-bottom: none;padding-bottom:3px;}\n#sidebarTabs .tabSelected{padding-bottom:3px;}\n\n\n#sidebarTabs .tabUnselected:hover { border-bottom: none;padding-bottom:3px;color:#4F4B45}\n\n#sidebarOptions .sliderPanel {\n background: #fff; border:none;\n font-size: .9em;\n}\n#sidebarOptions .sliderPanel a {font-weight:normal;}\n#sidebarOptions .sliderPanel input {border:1px solid #999;}\n\n.viewer blockquote {\n border-left: 3px solid #948979;\n}\n\n.viewer table {\n border: 2px solid [[ColorPalette::TertiaryDark]];\n}\n\n.viewer th, thead td {\n background: #948979;\n border: 1px solid #948979;\n color: #fff;\n}\n.viewer pre {\n border: 1px solid #948979;\n background: #f5f5f5;\n}\n\n.viewer code {\n color: #2F2A29;\n}\n\n.viewer hr {\n border-top: dashed 1px #948979;\n}\n\n.editor input {\n border: 1px solid #948979;\n}\n\n.editor textarea {\n border: 1px solid #948979;\n}\n\n.popup {\n background: #948979;\n border: 1px solid #948979;\n}\n\n.popup li.disabled {\n color: #000;\n}\n\n.popup li a, .popup li a:visited {\n color: #eee;\n border: none;\n}\n\n.popup li a:hover {\n background: #575352;\n color: #fff;\n border: none;\n}\n\n.tagging, .tagged {\n border: 1px solid #eee;\n background-color: #F7F7F7;\n}\n\n.selected .tagging, .selected .tagged {\n background-color: #eee;\n border: 1px solid #BFBAB3;\n}\n\n .tagging .listTitle, .tagged .listTitle {\n color: #bbb;\n}\n\n.selected .tagging .listTitle, .selected .tagged .listTitle {\n color: #666; \n}\n\n.tagging .button, .tagged .button {\n color:#aaa;\n}\n.selected .tagging .button, .selected .tagged .button {\n color:#4F4B45;\n}\n\n.highlight, .marked {background:transparent; color:#111; border:none; text-decoration:underline;}\n\n.tagging .button:hover, .tagged .button:hover, .tagging .button:active, .tagged .button:active {\n border: none; background:transparent; text-decoration:underline; color:#000;\n}\n\nh1,h2,h3,h4,h5 { color: #666; background: transparent; padding-bottom:2px; font-family: Arial, Helvetica, sans-serif; }\nh1 {font-size:18px;}\nh2 {font-size:16px;}\nh3 {font-size: 14px;}\n\n#messageArea {\n border: 4px solid #948979;\n background: #f5f5f5;\n color: #999;\n font-size:90%;\n}\n\n#messageArea a:hover { background:#f5f5f5;}\n\n#messageArea .button{\n color: #666;\n border: 1px solid #CC6714;\n}\n\n#messageArea .button:hover {\n color: #fff;\n background: #948979;\n border-color: #948979;\n}\n\n\n* html .viewer pre {\n margin-left: 0em;\n}\n\n* html .editor textarea, * html .editor input {\n width: 98%;\n}\n\n.searchBar {float:right;font-size: 1.0em;}\n.searchBar .button {color:#999;display:block;}\n.searchBar .button:hover {border:1px solid #fff;color:#4F4B45;}\n.searchBar input { \n background-color: #FFF;\n color: #999999;\n border: 1px solid #CCC; margin-right:3px;\n}\n\n#sidebarOptions .button:active, #sidebarOptions .highlight {background:#F5F5F5;}\n\n*html #contentFooter { padding:0.25em 1em 0.5em 1em;}\n\n#noticeBoard {font-size: 0.9em; color:#999; position:relative;display:block;background:#fff; clear: both; margin-right:0.5em; margin-top:60px; padding:5px; border-bottom: 1px dotted #CCC; border-top: 1px dotted #CCC;}\n#mainMenu #noticeBoard a,#mainMenu #noticeBoard .tiddlyLink {display:inline;border:none;padding:5px 2px;color:#DF9153 }\n#noticeBoard a:hover {border:none;} \n\n#noticeBoard br {display:inline;}\n\n#mainMenu #noticeBoard .button{\n color: #666;\n border: 1px solid #DF9153;padding:2px;\n}\n\n#mainMenu #noticeBoard .button:hover{\n color: #fff;\n background: #DF9153;\n border-color: #DF9153;\n}\n\n.searchbar {position:relative; width:11em;}\n.searchbar .button{margin:0; width:11em;}\n#header {display:inline-block;}\n/*}}}*/
* [[OPERATION7|http://operation7.mgame.com/]] 친구가 만든 FPS 게임. [>img[OPERATION7|image/Links/op.jpg][http://operation7.mgame.com/]] \n@@clear(left):clear(right):display(block):@@\n----\n* [[America's Army|http://www.americasarmy.com/]] [>img[America's Army|image/Links/logo_aao.gif][http://www.americasarmy.com/]] \n* [[America's Army Korea Community Site|http://army.technoa.co.kr/]]\n@@clear(left):clear(right):display(block):@@\n----\n* [[EVE Online|http://www.eve-online.com/]] [>img[EVE Online|image/Links/125x125_01.jpg][http://www.eve-online.com/]]\n@@clear(left):clear(right):display(block):@@\n----\n\n\n\n
[[CrazygatsHome|Main.html]]^^
* [img[TiddlyWiki Home|image/Links/favicon.ico][http://www.tiddlywiki.com/]] [[TiddlyWiki|http://www.tiddlywiki.com/]]\n* [[TiddlyThemes|http://tiddlythemes.com/#Home]] - [[TiddlyThemes 바꾸기|테마바꾸기]]\n* [[ccTiddly|http://cctiddly.sourceforge.net/]] - [[ccTiddly 설치방법|ccTiddly 설치방법]]\n* TiddlyWiki 사용방법 - tags formatting 참고\n
* [>img[평곤이형 위키형 홈피|image/Links/viper_logo.png][http://www.viper.pe.kr/cgi-bin/moin.cgi]]..평곤이형 홈피.\n@@clear(left):clear(right):display(block):@@\n----\n* [>img[붉은 전갈|image/Links/redscorpionB.gif][http://www.redscorpion.net/]]..붉은 전갈.\n@@clear(left):clear(right):display(block):@@\n----\n* [[태진이형 홈피|http://www.gingaminga.com/]]
* [[Freemind|http://freemind.sourceforge.net/wiki/index.php/Main_Page]] [>img[Freemind|image/Links/freemind.jpg][http://freemind.sourceforge.net/wiki/index.php/Main_Page]] \n 공짜 마인드맵 프로그램.\n java로 구현된 Free Software.\n brain stormming\n* [[Mind-Mapping 에 대한 wikipedia의 설명|http://en.wikipedia.org/wiki/Mind_mapping]]\n@@clear(left):clear(right):display(block):@@\n----\n* [[StarUML|http://staruml.sourceforge.net/ko/]] 오픈소스 UML/MDA 플랫폼. [>img[StarUML|image/Links/logo_staruml.gif][http://staruml.sourceforge.net/ko/]] \n* [[StarUML 5.0 사용자 가이드|http://staruml.sourceforge.net/docs/user-guide(ko)/toc.html]]\n@@clear(left):clear(right):display(block):@@\n----\n
@@\n이곳은 제가 그동안 공부하고 작업했던 것들의 정리를 목적으로 만든 홈페이지입니다.\n공유를 목적으로 만든 곳이 아니지만 이곳을 방문하시는 모든 분들에게 자료와 정보를 공개합니다.\n@@
Type the text for 'New Tiddler'
!{{{개발의 7가지 정석과 3가지 바보짓}}}\n\n정석1. 재사용 계획. 같은 일을 되풀이하지 마라.\n정석2. 문서화. 머릿속에 남겨두지 마라.\n정석3. 기획먼저. 개발은 다음(80/20 법칙)\n정석4. 일정. 모든 사람들에게 목표를 확실히 알려주어라.\n정석5. 실수를 잡으면서 가라.\n정석6. R & D 의 수준을 조절하라.\n정석7. 선을 그을 때를 알라.\n----\n@@바보짓1. 부적절한 관리@@\n프로젝트의 결정권이 택도 아닌놈 한테 부여되었을 때 발생한다. 권위는 팀원들에 의해 만들어지며, 영화의 감독과 마찬가지로 결정권과 창조적 비전을 가진 개인이 갖게 된다.\n\n@@바보짓2. 기능의 범람@@\n씨잘데기 없는 기능을 중간에 넣자고 할 때 발생한다. 그거 만드는 시간도 결코 공짜가 아니다.\n\n@@바보짓3. 코더들의 편협함@@\n단지 코딩실력으로 사람을 평가하지 말란 말이다. 코딩만 잘함 뭐해 인간이 되야지.\n----
@@1. 약속을 하고도 오지 않는다. (약속을 지키지 않는다.)@@\n 말 할 필요도 없는 것이지만, 갑자기 약속을 취소하면 “저 사람은 약속을 지키지 않는 사람”이라는 딱지가 붙게 됩니다. Woody Allen씨도 말한 것처럼 “당신이 성공하는지 실패하는지는 당신이 제시간에 오는지에 달려 있다”라는 것입니다.\n가지 못할 것 같으면 약속을 하지 맙시다.\n\n@@2. 하루의 반은 꾸물꾸물 대고 있다.@@\n 해야 하는데…, 하지만…, 하며 꾸물거리며 하루의 반을 넘기지 않도록 합시다. 가장 중요한 일에 힘을 넣어 하거나, 하고 싶은 것을 작게 분해하여 하도록 합시다.\n\n@@3. 일은 하고 있지만, 전혀 중요한 일이 아니다.@@\n 꾸물거리고 있으면 빠지기 쉬운 것이 “전혀 중요하지 않는 일에 몰두한다.”라는 것입니다. 자신의 목표에 맞추어 그것을 달성하는데 의미가 있는 일을 합시다.\n\n@@4. 너무 많이 생각한다.@@\n 생각만 하고, 행동으로 옮기지 않으면 결국 아무것도 달성하지 못합니다.\n\n@@5. 매사를 부정적으로만 판단한다.@@\n 매사에는 어느 정도 부정적인 면도 있지만, 그것이 100%는 아니다. 라는 것을 기억해 둡시다. 그리고 거꾸로 긍정적인 면은 이라는 생각을 하면 의욕이 생길 것입니다.\n\n@@6. 자신의 생각에 구애되어 있다.@@\n 다른 사람의 의견을 들읍시다.\n\n@@7. 지나치게 많은 정보의 수집으로 인한 자만감@@\n 정보를 수집하는 것은 중요한 일입니다만, 지나치게 많이 수집하는 것은 좋지 않습니다. 적당량을 작업에 이용합시다.\n\n[[[출처]|http://blog.naver.com/pyoungon/40045088232]] \n\n
{{{\n{{wrappingClass{Text that is now accentuated}}}\n}}}\n\n{{wrappingClass{Text that is now accentuated}}}\n\nBy default, the text is placed in a {{{<span>}}}. To use a {{{<div>}}} instead, insert a line break before the text:\n\n{{{\n{{wrappingClass{\nText that is now accentuated}}}\n}}}\n\n{{wrappingClass{\nText that is now accentuated}}}
<<option chkGenerateAnRssFeed>> GenerateAnRssFeed\n<<option chkOpenInNewWindow>> OpenLinksInNewWindow\n<<option chkSaveEmptyTemplate>> SaveEmptyTemplate\n<<option chkToggleLinks>> Clicking on links to tiddlers that are already open causes them to close\n^^(override with Control or other modifier key)^^\n<<option chkHttpReadOnly>> HideEditingFeatures when viewed over HTTP\n<<option chkForceMinorUpdate>> Treat edits as MinorChanges by preserving date and time\n^^(override with Shift key when clicking 'done' or by pressing Ctrl-Shift-Enter^^\n<<option chkConfirmDelete>> ConfirmBeforeDeleting\nMaximum number of lines in a tiddler edit box: <<option txtMaxEditRows>>\nFolder name for backup files: <<option txtBackupFolder>>\n<<option chkInsertTabs>> Use tab key to insert tab characters instead of jumping to next field
To make quoted bits of text stand out, you can use BlockQuotes within your [[tiddler]]s, like this:\n\nJeremyRuston said:\n<<<\nA TiddlyWiki is like a blog because it's divided up into neat little chunks, but it encourages you to read it by hyperlinking rather than sequentially: if you like, a non-linear blog analogue that binds the individual microcontent items into a cohesive whole.\n<<<\n\nLike BulletPoints and NumberedBulletPoints, you can have multiple levels of BlockQuotes. Just edit this tiddler to see how it's done.\n\n>level 1\n>level 1\n>>level 2\n>>level 2\n>>>level 3\n>>>level 3\n>>level 2\n>level 1
Creating BulletPoints is simple.\n* Just add an asterisk\n* at the beginning of a line.\n** If you want to create sub-bullets\n** start the line with two asterisks\n*** And if you want yet another level\n*** use three asterisks\n* Edit this tiddler to see how it's done\n* You can also do NumberedBulletPoints
{{{\n[img[title|filename]]\n[img[filename]]\n[img[title|filename][link]]\n[img[filename][link]]\n}}}\nThe tooltip is optional.\n[<img[Viper|image/Links/viper_logo.png][http://www.flickr.com/photos/jermy/8749660/]][>img[Viper|image/Links/viper_logo.png][http://www.flickr.com/photos/jermy/8749285/]]You can also float images to the left or right: the forest is left aligned with {{{[<img[}}}, and the field is right aligned with {{{[>img[}}}.\n@@clear(left):clear(right):display(block):You can use CSS to clear the floats@@\n{{{\n[<img[A woody bit of Hampstead Heath|forest.jpg]]\n[>img[A field near Milton Keynes|field.jpg]]\n}}}
Like most wikis, TiddlyWiki supports a range of simplified character formatting:\n| !To get | !Type this |h\n| ''Bold'' | {{{''Bold''}}} |\n| --Strikethrough-- | {{{--Strikethrough--}}} |\n| __Underline__ | {{{__Underline__}}} (that's two underline characters) |\n| //Italic// | {{{//Italic//}}} |\n| Superscript: 2^^3^^=8 | {{{2^^3^^=8}}} |\n| Subscript: a~~ij~~ = -a~~ji~~ | {{{a~~ij~~ = -a~~ji~~}}} |\n| @@highlight@@ | {{{@@highlight@@}}} |\n<<<\nThe highlight can also accept CSS syntax to directly style the text:\n@@color:green;green coloured@@\n@@background-color:#ff0000;color:#ffffff;red coloured@@\n@@text-shadow:black 3px 3px 8px;font-size:18pt;display:block;margin:1em 1em 1em 1em;border:1px solid black;Access any CSS style@@\n<<<\n\n//For backwards compatibility, the following highlight syntax is also accepted://\n{{{\n@@bgcolor(#ff0000):color(#ffffff):red coloured@@\n}}}\n@@bgcolor(#ff0000):color(#ffffff):red coloured@@
You can divide a tiddler into\n----\nsections by typing four dashes on a line by themselves\nformatting
Entities in HTML documents allow characters to be entered that can't easily be typed on an ordinary keyboard. They take the form of an ampersand (&), an identifying string, and a terminating semi-colon (;). There's a complete reference [[here|http://www.htmlhelp.com/reference/html40/entities/]]; some of the more common and useful ones are shown below. Also see [[Paul's Notepad|http://thepettersons.org/PaulsNotepad.html#GreekHtmlEntities HtmlEntitiesList LatinHtmlEntities MathHtmlEntities]] for a more complete list.\n\n|>|>|>|>|>|>| !HTML Entities |\n| &amp;nbsp; | &nbsp; | no-break space | &nbsp;&nbsp; | &amp;apos; | &apos; | single quote, apostrophe |\n| &amp;ndash; | &ndash; | en dash |~| &amp;quot; | " | quotation mark |\n| &amp;mdash; | &mdash; | em dash |~| &amp;prime; | &prime; | prime; minutes; feet |\n| &amp;hellip; | &hellip; | horizontal ellipsis |~| &amp;Prime; | &Prime; | double prime; seconds; inches |\n| &amp;copy; | &copy; | Copyright symbol |~| &amp;lsquo; | &lsquo; | left single quote |\n| &amp;reg; | &reg; | Registered symbol |~| &amp;rsquo; | &rsquo; | right single quote |\n| &amp;trade; | &trade; | Trademark symbol |~| &amp;ldquo; | &ldquo; | left double quote |\n| &amp;dagger; | &dagger; | dagger |~| &amp;rdquo; | &rdquo; | right double quote |\n| &amp;Dagger; | &Dagger; | double dagger |~| &amp;laquo; | &laquo; | left angle quote |\n| &amp;para; | &para; | paragraph sign |~| &amp;raquo; | &raquo; | right angle quote |\n| &amp;sect; | &sect; | section sign |~| &amp;times; | &times; | multiplication symbol |\n| &amp;uarr; | &uarr; | up arrow |~| &amp;darr; | &darr; | down arrow |\n| &amp;larr; | &larr; | left arrow |~| &amp;rarr; | &rarr; | right arrow |\n| &amp;lArr; | &lArr; | double left arrow |~| &amp;rArr; | &rArr; | double right arrow |\n| &amp;harr; | &harr; | left right arrow |~| &amp;hArr; | &hArr; | double left right arrow |\n\nThe table below shows how accented characters can be built up by subsituting a base character into the various accent entities in place of the underscore ('_'):\n\n|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>| !Accented Characters |\n| grave accent | &amp;_grave; | &Agrave; | &agrave; | &Egrave; | &egrave; | &Igrave; | &igrave; | &Ograve; | &ograve; | &Ugrave; | &ugrave; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |\n| acute accent | &amp;_acute; | &Aacute; | &aacute; | &Eacute; | &eacute; | &Iacute; | &iacute; | &Oacute; | &oacute; | &Uacute; | &uacute; | &nbsp; | &nbsp; | &Yacute; | &yacute; | &nbsp; | &nbsp; |\n| circumflex accent | &amp;_circ; | &Acirc; | &acirc; | &Ecirc; | &ecirc; | &Icirc; | &icirc; | &Ocirc; | &ocirc; | &Ucirc; | &ucirc; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |\n| umlaut mark | &amp;_uml; | &Auml; | &auml; | &Euml; | &euml; | &Iuml; | &iuml; | &Ouml; | &ouml; | &Uuml; | &uuml; | &nbsp; | &nbsp; | &Yuml; | &yuml; | &nbsp; | &nbsp; |\n| tilde | &amp;_tilde; | &Atilde; | &atilde; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &Otilde; | &otilde; | &nbsp; | &nbsp; | &Ntilde; | &ntilde; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |\n| ring | &amp;_ring; | &Aring; | &aring; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |\n| slash | &amp;_slash; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &Oslash; | &oslash; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |\n| cedilla | &amp;_cedil; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &Ccedil; | &ccedil; |
Monospaced text is supported - edit this tiddler to see the syntax.\n\nYou can also have monospaced blocks (useful for source code):\n{{{\nvoid main()\n{\n int i = 0;\n}\n}}}
It's easy to create NumberedBulletPoints.\n# Use a single '#' at the start of each line\n# and the tiddler will automatically\n# start numbering your list.\n## If you want a sub-list\n## within any bullets\n## add two '#'s at the start of the lines.\n# When you go back to a single '#'\n# the main numbered list will start up\n# where it left off.\n\nIt's just as simple to do normal BulletPoints.
|Standard Periodic Table (ref. Wikipedia)|c\n|| !1 | !2 |!| !3 | !4 | !5 | !6 | !7 | !8 | !9 | !10 | !11 | !12 | !13 | !14 | !15 | !16 | !17 | !18 |\n|!1|bgcolor(#a0ffa0): @@color(red):H@@ |>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>||bgcolor(#c0ffff): @@color(red):He@@ |\n|!2|bgcolor(#ff6666): Li |bgcolor(#ffdead): Be |>|>|>|>|>|>|>|>|>|>||bgcolor(#cccc99): B |bgcolor(#a0ffa0): C |bgcolor(#a0ffa0): @@color(red):N@@ |bgcolor(#a0ffa0): @@color(red):O@@ |bgcolor(#ffff99): @@color(red):F@@ |bgcolor(#c0ffff): @@color(red):Ne@@ |\n|!3|bgcolor(#ff6666): Na |bgcolor(#ffdead): Mg |>|>|>|>|>|>|>|>|>|>||bgcolor(#cccccc): Al |bgcolor(#cccc99): Si |bgcolor(#a0ffa0): P |bgcolor(#a0ffa0): S |bgcolor(#ffff99): @@color(red):Cl@@ |bgcolor(#c0ffff): @@color(red):Ar@@ |\n|!4|bgcolor(#ff6666): K |bgcolor(#ffdead): Ca ||bgcolor(#ffc0c0): Sc |bgcolor(#ffc0c0): Ti |bgcolor(#ffc0c0): V |bgcolor(#ffc0c0): Cr |bgcolor(#ffc0c0): Mn |bgcolor(#ffc0c0): Fe |bgcolor(#ffc0c0): Co |bgcolor(#ffc0c0): Ni |bgcolor(#ffc0c0): Cu |bgcolor(#ffc0c0): Zn |bgcolor(#cccccc): Ga |bgcolor(#cccc99): Ge |bgcolor(#cccc99): As |bgcolor(#a0ffa0): Se |bgcolor(#ffff99): @@color(green):Br@@ |bgcolor(#c0ffff): @@color(red):Kr@@ |\n|!5|bgcolor(#ff6666): Rb |bgcolor(#ffdead): Sr ||bgcolor(#ffc0c0): Y |bgcolor(#ffc0c0): Zr |bgcolor(#ffc0c0): Nb |bgcolor(#ffc0c0): Mo |bgcolor(#ffc0c0): Tc |bgcolor(#ffc0c0): Ru |bgcolor(#ffc0c0): Rh |bgcolor(#ffc0c0): Pd |bgcolor(#ffc0c0): Ag |bgcolor(#ffc0c0): Cd |bgcolor(#cccccc): In |bgcolor(#cccccc): Sn |bgcolor(#cccc99): Sb |bgcolor(#cccc99): Te |bgcolor(#ffff99): I |bgcolor(#c0ffff): @@color(red):Xe@@ |\n|!6|bgcolor(#ff6666): Cs |bgcolor(#ffdead): Ba |bgcolor(#ffbfff):^^*1^^|bgcolor(#ffc0c0): Lu |bgcolor(#ffc0c0): Hf |bgcolor(#ffc0c0): Ta |bgcolor(#ffc0c0): W |bgcolor(#ffc0c0): Re |bgcolor(#ffc0c0): Os |bgcolor(#ffc0c0): Ir |bgcolor(#ffc0c0): Pt |bgcolor(#ffc0c0): Au |bgcolor(#ffc0c0): @@color(green):Hg@@ |bgcolor(#cccccc): Tl |bgcolor(#cccccc): Pb |bgcolor(#cccccc): Bi |bgcolor(#cccc99): Po |bgcolor(#ffff99): At |bgcolor(#c0ffff): @@color(red):Rn@@ |\n|!7|bgcolor(#ff6666): Fr |bgcolor(#ffdead): Ra |bgcolor(#ff99cc):^^*2^^|bgcolor(#ffc0c0): Lr |bgcolor(#ffc0c0): Rf |bgcolor(#ffc0c0): Db |bgcolor(#ffc0c0): Sq |bgcolor(#ffc0c0): Bh |bgcolor(#ffc0c0): Hs |bgcolor(#ffc0c0): Mt |bgcolor(#ffc0c0): Ds |bgcolor(#ffc0c0): Rg |bgcolor(#ffc0c0): @@color(green):Uub@@ |bgcolor(#cccccc): Uut |bgcolor(#cccccc): Uuq |bgcolor(#cccccc): Uup |bgcolor(#cccccc): Uuh |bgcolor(#fcfecc): @@color(#cccccc):Uus@@ |bgcolor(#ecfefc): @@color(#cccccc):Uuo@@ |\n\n| !Lanthanides^^*1^^|bgcolor(#ffbfff): La |bgcolor(#ffbfff): Ce |bgcolor(#ffbfff): Pr |bgcolor(#ffbfff): Nd |bgcolor(#ffbfff): Pm |bgcolor(#ffbfff): Sm |bgcolor(#ffbfff): Eu |bgcolor(#ffbfff): Gd |bgcolor(#ffbfff): Tb |bgcolor(#ffbfff): Dy |bgcolor(#ffbfff): Ho |bgcolor(#ffbfff): Er |bgcolor(#ffbfff): Tm |bgcolor(#ffbfff): Yb |\n| !Actinides^^*2^^|bgcolor(#ff99cc): Ac |bgcolor(#ff99cc): Th |bgcolor(#ff99cc): Pa |bgcolor(#ff99cc): U |bgcolor(#ff99cc): Np |bgcolor(#ff99cc): Pu |bgcolor(#ff99cc): Am |bgcolor(#ff99cc): Cm |bgcolor(#ff99cc): Bk |bgcolor(#ff99cc): Cf |bgcolor(#ff99cc): Es |bgcolor(#ff99cc): Fm |bgcolor(#ff99cc): Md |bgcolor(#ff99cc): No |\n\n*Chemical Series of the Periodic Table\n**@@bgcolor(#ff6666): Alkali metals@@\n**@@bgcolor(#ffdead): Alkaline earth metals@@\n**@@bgcolor(#ffbfff): Lanthanides@@\n**@@bgcolor(#ff99cc): Actinides@@\n**@@bgcolor(#ffc0c0): Transition metals@@\n**@@bgcolor(#cccccc): Poor metals@@\n**@@bgcolor(#cccc99): Metalloids@@\n**@@bgcolor(#a0ffa0): Nonmetals@@\n**@@bgcolor(#ffff99): Halogens@@\n**@@bgcolor(#c0ffff): Noble gases@@\n\n*State at standard temperature and pressure\n**those in @@color(red):red@@ are gases\n**those in @@color(green):green@@ are liquids\n**those in black are solids
To make plugins, stylesheets and templates easier to read, you can use special alternative formatting for monospaced blocks.\n\nIn JavaScript code:\n{{{\n//{{{\nvar id = document.getElementById("mainMenu");\n//}}}\n}}}\nIn HTML templates:\n{{{\n<!--{{{-->\n<div id="MainMenu">\n</div>\n<!--}}}-->\n}}}\nIn CSS stylesheets\n{{{\n/*{{{*/\ndiv {color: #ff0000;}\n/*}}}*/\n}}}\nIt will be displayed as:\n//{{{\nvar id = document.getElementById("mainMenu");\n//}}}\n\n<!--{{{-->\n<div id="MainMenu">\n</div>\n<!--}}}-->\n\n/*{{{*/\ndiv {color: #ff0000;}\n/*}}}*/
You can now link to [[external sites|http://www.osmosoft.com]] or [[ordinary tiddlers|TiddlyWiki]] with ordinary words, without the messiness of the full URL appearing. Edit this tiddler to see how.\n\nYou can also LinkToFolders.
!Header 1\n!!Header 2\n!!!Header 3\n!!!!Header 4\n!!!!!Header 5
*sample:\n|!th1111111111|!th2222222222|\n|>| colspan |\n| rowspan |left|\n|~| right|\n|bgcolor(#a0ffa0):colored| center |\n|caption|c\n*another sample: see PeriodicTable.\nFor advanced effects, you can control the CSS style of a table by adding a row like this:\n{{{\n|cssClass|k\n}}}
To hide text within a tiddler so that it is not displayed you can wrap it in {{{/%}}} and {{{%/}}}. It can be a useful trick for hiding drafts or annotating complex markup. Edit this tiddler to see an example.\n/%This text is not displayed\nuntil you try to edit %/
Sometimes it's handy to be able to write WikiWords without them being recognised as links (for people's names, for instance). You can do this by preceding the WikiWord with a tilde ({{{~}}}). For example, ~JamesBond, ~JavaScript and ~TiddlyWiki
!!!요구사항\nccTiddly 를 설치하려면 웹호스팅하는곳에서 PHP4/5, MySQL 을 지원해야된다.\n*[[PHP4/5|http://php.net]]\n*[[MySQL|http://mysql.com]]\n\n!!!설치\n* 다운로드 받은 ccTiddly 를 웹호스팅 디렉토리에 압축을 푼다. 압축푼상태 그대로 둔다.\n* 파일을 읽을수 있도록 권한설정을 해준다.\n* 'config' 디렉토리로 가서 'default.php' 파일을 연다.\n* 'default.php' 파일을 편집한다.\n>@@color:red;대략 편집할 것들이다. 읽어보고 필요하면 다른옵션들도 편집해도 된다.@@\n>@@color:green;database/table@@ \n>$tiddlyCfg['db']['host'] = "localhost"; @@color:blue;sql host@@\n>$tiddlyCfg['db']['login'] = "root"; @@color:blue;login name@@\n>$tiddlyCfg['db']['pass'] = ""; @@color:blue;login password@@\n>$tiddlyCfg['db']['name'] = "cct"; @@color:blue;db name@@\n>@@color:green;username password pair@@\n>$tiddlyCfg['user'] = array("username"=>"password"); \n>$tiddlyCfg['group']['admin'] = array("username");\n>@@color:green;default privileges@@\n>$tiddlyCfg['privilege_misc']['undefined_privilege'] = "D"; \n>$tiddlyCfg['privilege_misc']['default_privilege'] = "AUUU"; \n>$tiddlyCfg['privilege_misc']['group_default_privilege']['anonymous'] = "AUUD";\n>$tiddlyCfg['privilege_misc']['group_default_privilege']['user'] = "AAAA";\n* 웹에서 'index.php' 파일을 열면 위키가 뜰것이다. \n* 문제가 없으면 설치 끝.\n
Type the text for 'New Tiddler'
!2007년 작업 했던 것들( 회사 작업 내용들 )\n!!![[Timekids Online|http://www.timekid.co.kr/]]\n@@color:red;ScreenShot@@\n|<html><a href="image/work/TK/LaraStar2.jpg" target="_blank"><img src="image/work/TK/LaraStar2.jpg" width="200" height="150" border="0"></a></html>|<html><a href="image/work/TK/LaraStar3.jpg" target="_blank"><img src="image/work/TK/LaraStar3.jpg" width="200" height="150" border="0"></a></html>|<html><a href="image/work/TK/LaraStar.jpg" target="_blank"><img src="image/work/TK/LaraStar.jpg" width="200" height="150" border="0"></a></html>|\n|<html><a href="image/work/TK/CyonBungee1.jpg" target="_blank"><img src="image/work/TK/CyonBungee1.jpg" width="200" height="150" border="0"></a></html>|<html><a href="image/work/TK/CyonBungee2.jpg" target="_blank"><img src="image/work/TK/CyonBungee2.jpg" width="200" height="150" border="0"></a></html>|<html><a href="image/work/TK/CyonBungee3.jpg" target="_blank"><img src="image/work/TK/CyonBungee3.jpg" width="200" height="150" border="0"></a></html>|\n|<html><a href="image/work/TK/CyonJuipsik1.jpg" target="_blank"><img src="image/work/TK/CyonJuipsik1.jpg" width="200" height="150" border="0"></a></html>|<html><a href="image/work/TK/CyonJuipsik2.jpg" target="_blank"><img src="image/work/TK/CyonJuipsik2.jpg" width="200" height="150" border="0"></a></html>|<html><a href="image/work/TK/je2.jpg" target="_blank"><img src="image/work/TK/je2.jpg" width="200" height="150" border="0"></a></html>|\n\n@@color:red;게임플레이 동영상@@\n<html><p align="center"><object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715" width="500" height="400">\n <param name="FileName" value="image/work/TK/Timekids.asf">\n <embed src="image/work/TK/Timekids.asf" pluginspage="http://www.microsoft.com/Windows/Downloads/Contents/Products/MediaPlayer/" width="500" height="400"></embed>\n </object></p></html>
#[[TiddlyThemes|http://tiddlythemes.com/#Home]] 에서 원하는 테마를 고른다.\n#고른 테마에서 StyleSheet, PageTemplate 을 복사해서 '테마이름StyleSheet', '테마이름PageTemplate' 을 만든다.\n##예) 테마이름이 Mocha 라고 하면 MochaStyleSheet, MochaPageTemplate\n#그리고 StyleSheet, PageTemplate 를 수정한다. \n##StyleSheet 수정 - {{{[[MochaStyleSheet]]}}}\n##PageTemplate 수정 - {{{<div>[[MochaPageTemplate]]</div>}}}\n#이렇게 하면 원하는 테마로 바뀐다.\n#그래도 안바뀌면 EditTemplate, ViewTemplate 를 원하는 테마껄로 바꿔주면 된다.\n
*[[2003]]\n*[[2004 2005 2006]]\n*[[2007]]\n*[[2008]]
<!--{{{-->\n<div id='header' class='header' macro='gradient vert #555555 #3b3b3b '>\n <div class='siteTitle' refresh='content' tiddler='SiteTitle'></div>\n <span id='topMenu' refresh='content' tiddler='MainMenu'></span>\n</div>\n\n<div id='sidebar'>\n<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n</div>\n<!--}}}-->
Copyright © Crazygats. All rights reserved.\n
<!--{{{-->\n<div id='header' class='header'>\n<div class='headerShadow'>\n<span class='searchBar' macro='search'></span>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n\n</div>\n<div id='mainMenu'>\n<span refresh='content' tiddler='MainMenu'></span>\n<span id='noticeBoard' refresh='content' tiddler='NoticeBoard'></span>\n\n</div>\n<div id='sidebar'>\n<div id='sidebarOptions' refresh='content' tiddler='MochaSideBarOptions'></div>\n<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n</div>\n<div id='contentFooter' refresh='content' tiddler='contentFooter'></div>\n<!--}}}-->
<<closeAll>><<permaview>><<newTiddler>><<newJournal 'DD MMM YYYY'>><<tiddler 'LoginPanel'>><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel 'options »' 'Change TiddlyWiki advanced options'>>\n
/*{{{*/\n/*Bleach Theme for TiddlyWiki*/\n/*Design and CSS by Saq Imtiaz*/\n/*Version 1.0*/\n/*}}}*/\n/*{{{*/\n/***\n!General\n***/\nbody {\n background: #fff;\n}\n\n#contentWrapper{\nmargin: 2.5em auto;\nwidth:759px;\nline-height: 1.6em;\nborder:1px solid #999;\nfont-size: 11px;\nfont-family: Lucida Grande, Tahoma, Arial, Helvetica, sans-serif;\ncolor: #555;height:1%;\n}\n\n.clearAll {clear:both;}\n.tagClear {clear:none;}\n/*}}}*/\n\n/*{{{*/\n/***\n!Header\n***/\n#header {background:#fff; border-bottom:1px solid #999;padding: 2.5em 2em 1.6em 2em; height:1%;\n }\n\n.siteTitle {\nfont-family: 'Trebuchet MS' sans-serif;\nfont-weight: bold;\nfont-size: 32px;\ncolor: #EF680E;\nbackground-color: #FFF; \n}\n\n.siteSubtitle {\n font-size: 1.0em;\n display:block; \ncolor: #999999; margin-top:0.5em !important; margin-top:1em; margin-left:3em;\n}\n\n#topMenu { positon:relative; float:right; display:inline; margin-right:2em;}\n#topMenu br {display:none; }\n#topMenu { background: #fff; color:#000;padding: 1em 1em;}\n#topMenu a, #topMenu .tiddlyLink, #topMenu .button {margin:0 0.5em; color:#666;}\n\n/*}}}*/\n\n/*{{{*/\n/***\n!displayArea\n***/\n\n#displayArea {margin-left:1.35em; margin-right:16.3em; margin-top:0; padding-top:1em; padding-bottom:10px;}\n\n/*}}}*/\n\n/*{{{*/\n/***\n!Sidebar\n***/\n#sidebar {position:relative;float:right; line-height: 1.4em; border-left:0px solid#000; display:inline; background:#fff; right:0; \nwidth: 16em;}\n\n/***\n!SidebarOptions\n***/\n#sidebarOptions {padding-left:0.5em; border-left:1px solid #999;padding-top:1em;}\n\n#sidebarOptions a {\n color:#999;\n text-decoration: none;}\n#sidebarOptions a:hover, #sidebarOptions .button:active {\n color:#333;\n background-color: #fff;border:1px solid #fff;\n }\n#sidebarOptions input {border:1px solid #999; width:10em;}\n\n\n\n/***\n!SidebarTabs\n***/\n#sidebarTabs {border-left:1px solid #999;}\n#sidebarTabs .tabContents {background:#fff;}\n#sidebarTabs .tabContents .tiddlyLink, #sidebarTabs .tabContents .button{color:#999;}\n#sidebarTabs .tabContents .tiddlyLink:hover,#sidebarTabs .tabContents .button:hover{color:#333;background:#fff;border:none;}\n\n#sidebarTabs .tabContents .button:hover, #sidebarTabs .tabContents .highlight, #sidebarTabs .tabContents .marked, #sidebarTabs .tabContents a.button:active{color:#333;background:#fff}\n\n.tabSelected{color:#fff; background:#999;}\n\n.tabUnselected {\n background: #ccc;\n}\n\n .tabSelected, .tabSelected:hover {\n color: #fff;\n background: #999;\n border: solid 1px #999;\npadding-bottom:1px;\n}\n\n#sidebarTabs .tabUnselected:hover { border-bottom: none;padding-bottom:3px;color:#4F4B45}\n\n .tabUnselected {\n color: #999;\n background: #eee;\n border: solid 1px #ccc;\npadding-bottom:1px;\n}\n\n#sidebarTabs .tabUnselected { border-bottom: none;padding-bottom:3px;}\n#sidebarTabs .tabSelected{padding-bottom:3px;}\n\n\n#sidebarOptions .sliderPanel {\n background: #fff; border:none;\n font-size: .9em;\n}\n#sidebarOptions .sliderPanel a {font-weight:normal; }\n#sidebarOptions .sliderPanel input {border:1px solid #999;width:auto;}\n#sidebarOptions .sliderPanel .txtOptionInput {border:1px solid #999;width:9em;}\n\n#sidebarTabs .tabContents {border-right:0; border-left:0; border-bottom:1px solid#999; padding-left:4px;}\n .listLink,#sidebarTabs .tabContents {line-height:1.5em;}\n .listTitle {color:#666;}\n\n#sidebarTabs .tabUnselected:hover { border-bottom: none;padding-bottom:3px;color:#4F4B45}\n#sidebarTabs .txtMoreTab .tabContents {border-left:1px solid #999;}\n#sidebarTabs .txtMainTab .tabContents li a{font-weight:bold;}\n/*}}}*/\n\n/*{{{*/\n.title {color:#EF680E;}\n.subtitle, .subtitle a { color: #999999; font-size: 1em;margin:0.2em; font-variant: small-caps;}\n.shadow .title{color:#999;}\n\n.selected .toolbar a {color:#999999;}\n.selected .toolbar a:hover {color:#333; background:transparent;border:1px solid #fff;}\n\n.toolbar .button:hover, .toolbar .highlight, .toolbar .marked, .toolbar a.button:active{color:#333; background:transparent;border:1px solid #fff;}\n\n* html .viewer pre {\n margin-left: 0em;\n}\n\n* html .editor textarea, * html .editor input {\n width: 98%;\n}\n\n a,#sidebarOptions .sliderPanel a{\n color:#EF680E;\n text-decoration: none;\n }\n\n a:hover,#sidebarOptions .sliderPanel a:hover {\n color:#EF680E;\n background-color: #fff; \nborder-bottom:1px dotted #EF680E;\n }\n\n.viewer .button, .editorFooter .button{\n color: #555;\n border: 1px solid #EF680E;\n}\n\n.viewer .button:hover, \n.editorFooter .button:hover{\n color: #fff;\n background: #EF680E;\n border-color: #EF680E;\n}\n\n.viewer .button:active, .viewer .highlight,.editorFooter .button:active, .editorFooter .highlight{color:#fff; background:#DF691B;border-color:#DF691B;}\n\n\n #topMenu a, #topMenu .button {\n padding: 20px 10px; border:none; font-weight:bold;\n }\n\n #topMenu a:link{\n text-decoration: none;\n }\n \n #topMenu a:hover, #topMenu .button:hover {\n background-color: #fff;\n color:#EF680E;\nborder:none;\n }\n\n\n\n\n\n.tagging, .tagged {\n border: 1px solid #eee;\n background-color: #F7F7F7;\n}\n\n.selected .tagging, .selected .tagged {\n background-color: #eee;\n border: 1px solid #BFBAB3;\n}\n\n .tagging .listTitle, .tagged .listTitle {\n color: #bbb;\n}\n\n.selected .tagging .listTitle, .selected .tagged .listTitle {\n color: #666; \n}\n\n.tagging .button, .tagged .button {\n color:#aaa;\n}\n.selected .tagging .button, .selected .tagged .button {\n color:#BFBAB3;\n}\n\n.highlight, .marked {background:transparent; color:#111; border:none; text-decoration:underline;}\n\n.tagging .button:hover, .tagged .button:hover, .tagging .button:active, .tagged .button:active {\n border: none; background:transparent; text-decoration:underline; color:#333;\n}\n\n\n\n\n\n.popup {\n background: #999;\n border: 1px solid #999;\n}\n\n.popup li.disabled {\n color: #000;\n}\n\n.popup li a, .popup li a:visited {\n color: #eee;\n border: none;\n}\n\n.popup li a:hover {\n background: #6F6A68;\n color: #fff;\n border: none;\n}\n\n\n .tiddler {\n padding-bottom: 40px;\n /*border-bottom: 1px solid #999; */\n }\n\n\n\n\n\n#messageArea {\n border: 4px solid #999;\n background: #f5f5f5;\n color: #999;\n font-size:90%;\n}\n\n#messageArea a:hover { background:#f5f5f5; border:none;}\n\n#messageArea .button{\n color: #666;\n border: 1px solid #CC6714;\n}\n\n#messageArea .button:hover {\n color: #fff;\n background: #999;\n border-color: #999;\n}\n\n\n\n\n\n\n\n\n\n\n\n\n.viewer blockquote {\n border-left: 5px solid #888;\n}\n\n.viewer table {\n border: 2px solid #888;\n}\n\n.viewer th, thead td {\n background: #888;\n border: 1px solid #888;\n color: #fff;\n}\n.viewer pre {\n border: 1px solid #999;\n background: #f5f5f5;\n}\n\n.viewer code {\n color: #111; background:#f5f5f5;\n}\n\n.viewer hr {\n border-top: dashed 1px #999;\n}\n\n.editor input {\n border: 1px solid #888;\n}\n\n.editor textarea {\n border: 1px solid #888;\n}\n\n.tabContents {background:#f7f7f7;}\n\nh1,h2,h3,h4,h5 { color: #555; background: transparent; padding-bottom:2px; font-family: Arial, Helvetica, sans-serif; }\nh1 {font-size:18px;}\nh2 {font-size:16px;}\nh3 {font-size: 14px;}\n\n#contentFooter {background:#999; color:#dfdfdf; clear: both; padding: 0.5em 1em; }\n\n #contentFooter a {\n color: #dfdfdf;\n border-bottom: 1px dotted #fff; font-weight:normal;\n }\n \n #contentFooter a:hover {\n color: #FFFFFF;\n background-color:transparent;\n } \n/*}}}*/
Last Updated: \n[img[image/Links/favicon.ico]] TiddlyWiki <<version>>\n© 2008 [[Crazygats|crazygats]]
<!--{{{-->\n<div id='header' class='header'>\n <div id='title'>\n <div id='topMenu' refresh='content' tiddler='MainMenu'></div>\n <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n </div>\n\n</div>\n\n<div id='sidebar'>\n<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n<div class='clearAll'></div>\n</div>\n<div id='contentFooter' refresh='content' tiddler='contentFooter'></div>\n<!--}}}-->
/***\nhttp://tiddlystyles.com/#theme:TiddlyPedia\n***/\n\n/*{{{*/\nbody{\n background: #f9f9f9 url(headbg.jpg) no-repeat top left;\n}\n\n#titleLine{\n display: block;\n background: transparent url(wiki.png) no-repeat 18px -7px;\n _background: transparent;\n height: 120px;\n _height: 135px;\n width: 150px;\n color: #000;\n border: 1px;\n padding: 0;\n margin: 0;\n}\n\n* html #titleLine{\n filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='wiki.png',sizingMethod='scale');\n}\n\n#contentWrapper #siteTitle a{\n display: inline;\n font-weight: bold;\n color: #000;\n font-size: 13px;\n}\n\n#siteSubtitle{\n padding: 0;\n}\n\n#siteTitle, #mainMenu{\n position: static;\n}\n\n#contentWrapper #sidebar{\n top: 0;\n left: 0;\n}\n\n#displayArea {\n margin: 0 0 0 15em;\n}\n\n#messageArea{\n position: fixed;\n top: 0;\n right: 0;\n font-size: 10px;\n border: 1px solid #aaa;\n background: #fff;\n z-index: 25;\n}\n\n#messageArea a:link{\n color: #002bb8;\n text-decoration: none;\n}\n\n#messageArea a:hover{\n text-decoration: underline;\n}\n\n.viewer{\n background: #fff;\n border: 1px solid #aaa;\n padding: 1em;\nmargin: 0;\n}\n\n.body{\n padding: 1px;\n}\n\n.title{\n background: #fff;\n border: 1px solid #aaa;\n display: inline;\n margin-left: .5em;\n padding: 2px .5em;\n border-bottom: 0;\n font-weight: bold;\n color: #000;\n font-size: 1.2em;\n}\n\n.toolbar{\n visibility: visible;\n display: inline;\n padding: 0;\n font-family: sans-serif;\n}\n\n.toolbar a.button:link,.toolbar a.button:visited{\n background: #fff;\n border: 1px solid #aaa;\n color:#002bb8;\n font-size: 11px;\n padding-bottom: 0;\n margin-right: .25em;\n}\n\n/* TiddlyPedia was Created by Clinton Checketts based on the Monobook skin of Wikipedia */\n\n#contentWrapper .toolbar .button:hover{\n border-bottom: 1px solid #fff;\n background: #fff;\n color:#002bb8;\n}\n\n.toolbar a.button:hover{\n border-bottom: 1px solid #fff;\n background: #fff;\n color:#000;\n}\n\n#displayArea .viewer a,a.button:link,a.button:visited,\na.tiddlyLink:link,a.tiddlyLink:visited,\n#sidebarOptions .sliderPanel a{\n color:#002bb8;\n background: transparent;\n border: 0;\n}\n\n.viewer a:hover,a.button:hover,a.button:active,\na.tiddlyLink:hover,a.tiddlyLink:active,\n.viewer a.button:hover,\n#sidebarOptions .sliderPanel a:hover{\n color:#002bb8;\n background: transparent;\n text-decoration: underline;\n}\n\n#mainMenu{\n font-family: sans-serif;\n text-align: left;\n font-size: x-small;\n width: 100%;\n margin: 0;\n padding: 0;\n}\n\n#mainMenu h1{\n font-size: 11px;\n font-weight: normal;\n padding: 0;\n margin: 0;\n background: transparent;\n}\n\n#mainMenu ul{\n font-size: 11px;\n border: 1px solid #aaa;\n padding: .25em 0;\n margin: 0;\n list-style-type: square;\n list-style-image: url(bullet.gif);\n background: #fff;\n width: 100%;\n}\n\n#mainMenu li{\n margin: 0 0 0 2em;\n padding: 0;\n}\n\n#contentWrapper #mainMenu a:link,#contentWrapper #mainMenu a:visited{\n color:#002bb8;\n padding: 0;\n margin: 0;\n background: transparent;\n}\n\n#mainMenu .externalLink {\n text-decoration: none;\n}\n\n#mainMenu .externalLink:hover {\n text-decoration: underline;\n}\n\n#sidebar{\n padding: .5em;\n font-family: sans-serif;\n}\n\n#sidebarOptions{\n border: 1px solid #aaa;\n background: #fff;\n margin-top: .5em;\n width: 100%;\n}\n\n#sidebar .sliderPanel{\n margin: 0;\n}\n\n#contentWrapper #sidebarOptions .button,#contentWrapper #sidebarOptions .button:hover{\n color:#002bb8;\n padding: .1em 0 .1em 2em;\n background: transparent url(bullet.gif) 10px -2px no-repeat;\n}\n\n#sidebarOptions input{\n width: 80%;\n margin: 0 .5em;\n}\n\n#sidebarTabs{\n background: #fff;\n margin-top: .5em;\n width: 100%;\n}\n\n#sidebarTabs .tabContents,#sidebarTabs .tabContents .tabContents{\n border: 1px solid #aaa;\n background: #fff;\n}\n\n#sidebarTabs .tabSelected,#sidebarTabs .tabcontents .tabSelected {\n background: #fff;\n border: 1px solid #aaa;\n border-bottom: 0;\n cursor: default;\n padding-bottom: 3px;\n color: #000;\n}\n\n#sidebarTabs .tabUnselected,#sidebarTabs .tabContents .tabUnselected{\n background: #aaa;\n padding-bottom: 0;\n color: #000; \n}\n\n#contentWrapper #sidebarTabs .tiddlyLink,#contentWrapper #sidebarTabs .button,\n#contentWrapper #sidebarTabs a.tiddlyLink:hover,#contentWrapper #sidebarTabs a.button:hover{\n background: transparent;\n color: #002bb8;\n}\n\n.footer{\n margin: -1em 0 1em 0; \n}\n\n.footer .button:hover,.editorFooter .button:hover{\nbackground: transparent;\n color: #002bb8;\n border-bottom: 1px solid #002bb8;\n}\n\n#popup{\n background: #e9e9e9;\n color: #000;\n}\n\n#popup hr{\n border-color: #aaa;\n background-color: #aaa;\n}\n\n#popup a{\n color: #000;\n}\n\n#popup a:hover,#contentWrapper #sidebarTabs #popup a:hover{\n background: #666;\n color: #fff;\n text-decoration: none;\n}\n\n#displayArea .tiddler a.tiddlyLinkNonExisting{\n color: #ba0000;\n}\n\n#displayArea .tiddler a.externalLink{\n text-decoration: none;\n color:#002bb8;\n padding-right: 1em;\n background: transparent url(external.png) 100% 50% no-repeat;\n}\n\n#displayArea .tiddler a.externalLink:hover{\n text-decoration: underline;\n}\n\n.viewer pre{\n background: #e9e9e9;\n border: 1px solid #666;\n}\n\n.viewer h1, .viewer h2, .viewer h3, .viewer h4, .viewer h5, .viewer h6{\n background: transparent;\n border-bottom: .2em solid #aaa;\n}\n\n#sidebar .sliderPanel{\n background: #e9e9e9;\n}\n\n#sidebar .sliderPanel input{width: auto;}\n\n.tagged, .tagging, .listTitle{\n float: none;\n display: inline;\n}\n\n.tagged li, .tagging li,\n.tagged ul, .tagging ul{\n display: inline;\n}\n\n/*}}}*/
<!--{{{-->\n<div id='header'>\n</div>\n<div id='sidebar'>\n<div id='titleLine'></div>\n<span id='siteTitle' refresh='content' tiddler='SiteTitle'></span>- <span id='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>\n<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n</div>\n\n<!--}}}-->
<DIV class=toolbar macro='toolbar +saveTiddler -cancelTiddler deleteTiddler wikibar'></DIV>\n<DIV class=title macro='view title'></DIV>\n<DIV class=editor macro='edit title'></DIV>\n<DIV class=editor macro='edit text'></DIV>\n<DIV class=editor macro='edit tags'></DIV>\n<DIV class=editorFooter><SPAN macro='message views.editor.tagPrompt'></SPAN><SPAN macro='tagChooser'></SPAN></DIV>\n\n
<!--{{{-->\n<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler permalink references revisions jump'></div>\n<div class='title' macro='view title'></div>\n<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date [[DD MMM YYYY]]'></span> (created <span macro='view created date [[DD MMM YYYY]]'></span>)</div>\n<div class='tagging' macro='tagging'></div>\n<div class='tagged' macro='tags'></div>\n<div class='viewer' macro='view text wikified'></div>\n<div class='tagClear'></div>\n<!--}}}-->\n<div class='comments' macro='comments'></div>
<DIV class=toolbar macro='toolbar +saveTiddler -cancelTiddler deleteTiddler wikibar'></DIV>\n<DIV class=title macro='view title'></DIV>\n<DIV class=editor macro='edit title'></DIV>\n<DIV class=editor macro='edit text'></DIV>\n<DIV class=editor macro='edit tags'></DIV>\n<DIV class=editorFooter><SPAN macro='message views.editor.tagPrompt'></SPAN><SPAN macro='tagChooser'></SPAN></DIV>\n\n
<div class='title' macro='view title'></div>\n<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>\n<div class='editor' macro='edit title'></div>\n<div class='editor' macro='edit text'></div>\n<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--{{{-->\n<div class='title' macro='view title'></div>\n<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></div>\n<div class='tagging' macro='tagging'></div>\n<div class='tagged' macro='tags'></div>\n<div class='viewer' macro='view text wikified'></div>\n<div class='tagClear'></div>\n<!--}}}-->
<!--{{{-->\n<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler permalink references revisions jump'></div>\n<div class='title' macro='view title'></div>\n<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date [[DD MMM YYYY]]'></span> (created <span macro='view created date [[DD MMM YYYY]]'></span>)</div>\n<div class='tagging' macro='tagging'></div>\n<div class='tagged' macro='tags'></div>\n<div class='viewer' macro='view text wikified'></div>\n<div class='tagClear'></div>\n<!--}}}-->\n
From journeyman to Master
!게임스쿨 다니면서 작업한 내용들\n\n|>|>|!2D Project|\n|>|>|일주일간 4명이서 만든 첫 프로젝트입니다. 게임명은 " Serious Shooting" 입니다.|\n|<html><a href="image/work/seriousshooting0.JPG" target="_blank"><img src="image/work/seriousshooting0.JPG" width="200" height="150" border="0" alt="초기화면"></a></html>|<html><a href="image/work/seriousshooting1.JPG" target="_blank"><img src="image/work/seriousshooting1.JPG" width="200" height="150" border="0" alt="게임실행화면"></a></html>|<html><a href="image/work/seriousshooting2.JPG" target="_blank"><img src="image/work/seriousshooting2.JPG" width="200" height="150" border="0" alt="엔딩 장면"></a></html>|\n\n|>|! Software Rendering|\n|>|Direct3D나 OpenGL을 사용하지 않고 순수 소프트웨어로 구현.|\n|<html><a href="image/work/softwareRendering0.jpg" target="_blank"><img src="image/work/softwareRendering0.jpg" width="320" height="239" border="0" alt="쉐이딩"></a></html>|<html><a href="image/work/softwareRendering1.jpg" target="_blank"><img src="image/work/softwareRendering1.jpg" width="320" height="241" border="0" alt="Fog"></a></html>|\n\n|>|!Character Animation & Cartoon Rendering|\n|>|HalfLife 에 사용된 SMD 로 구현해서 카툰렌더링을 추가해봤습니다.|\n|<html><a href="image/work/cartoon0.JPG" target="_blank"><img src="image/work/cartoon0.JPG" width="320" height="239" border="0"></a></html>|<html><a href="image/work/cartoon1.JPG" target="_blank"><img src="image/work/cartoon1.JPG" width="320" height="238" border="0"></a></html>|\n\n|!AI Sample - 팀 프로젝트에 쓸 인공지능 기능을 테스트 삼아 만들어본 인공지능 프로토 타입|\n|가운데 박스는 좌우로 이동가능. y축 회전이 가능하고 특정키를 누르면 다른 박스들이 가운데 박스로부터 도망가고 |\n|특정키를 누르면 기준 박스로 모이는 간단한 인공지능 구현. 유한상태기계( FSM ) 사용|\n|<html><p align="center"><a href="image/work/ai.JPG" target="_blank"><img src="image/work/ai.JPG" width="320" height="191" border="0"></a></p></html>|\n\n|>|!초간단 맵 툴|\n|>|높이맵과 디테일맵을 로드해서 지형생성하고 오브젝트 배치할 수 있는 간단한 기능의 맵툴. 시리얼라이즈 포맷은 INI 파일|\n|<html><a href="image/work/maptool0.jpg" target="_blank"><img src="image/work/maptool0.jpg" width="320" height="195" border="0" alt="오브젝트 배치"></a></html>|<html><a href="image/work/maptool1.jpg" target="_blank"><img src="image/work/maptool1.jpg" width="320" height="196" border="0" alt="Background & Font Color"></a></html>|\n|<html><a href="image/work/maptool2.jpg" target="_blank"><img src="image/work/maptool2.jpg" width="320" height="196" border="0" alt="Wireframe"></a></html>|<html><a href="image/work/maptool3.jpg" target="_blank"><img src="image/work/maptool3.jpg" width="320" height="196" border="0" alt="Frustum"></a></html>|\n\n|!팀 프로젝트 "MoriNori"|\n|팀명 "Interval"|\n|프로젝트 명 "모리노리"|\n|자세한 내용은 [[여기|http://www.gingaminga.com/]] 에서 참고.|\n|<html><a href="http://www.gingaminga.com/" target="_blank"><img src="image/work/morinori.jpg" width="670" height="516" border="0"></a></html>|
!2004, 2005, 2006년 작업 했던 것들( 회사 작업 내용들 )\n\n!!!@@color:red;키린온라인@@\n신입으로 들어와 처음 했던 프로젝트( 인터페이스툴 조금, 클라이언트 컨텐츠 작업 조금 ).\n현재 서비스는 하지 않는다.\n|<html><a href="image/work/kirin1.JPG" target="_blank"><img src="image/work/kirin1.JPG" width="200" height="150" border="0" alt="로딩화면"></a></html>|<html><a href="image/work/kirin0.jpg" target="_blank"><img src="image/work/kirin0.jpg" width="200" height="150" border="0"></a></html>|<html><a href="image/work/kirin3.jpg" target="_blank"><img src="image/work/kirin3.jpg" width="200" height="150" border="0" alt="타운"></a></html>|\n\n중국사이트에서 찾아낸 동영상 자료다.\n<html><object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715" width="500" height="400">\n <param name="FileName" value="image/work/PA_22939_1128414938966[1].wmv">\n <embed src="image/work/PA_22939_1128414938966[1].wmv" pluginspage="http://www.microsoft.com/Windows/Downloads/Contents/Products/MediaPlayer/" width="500" height="400"></embed>\n </object></html>\n\n\n!!!@@color:red;[[Xiah Online|http://www.xiah.co.kr/]]@@\n클라이언트 컨텐츠 작업 및 엔진 수정작업\n|<html><a href="image/work/xiah0.jpg" target="_blank"><img src="image/work/xiah0.jpg" width="320" height="239" border="0" alt="loading"></a></html>|<html><a href="image/work/xiah1.jpg" target="_blank"><img src="image/work/xiah1.jpg" width="320" height="239" border="0" alt="게임 스샷"></a></html>|\n\n\n!!!@@color:red;엔진팀에서의 각종 툴 작업@@\n!!!!@@color:green;Terrain Editor : 그래픽팀없이 인터페이스 설계 및 디지인을 내손으로 처음 했었던 툴.@@\n|<html><a href="image/work/TerrainEditor/open.jpg" target="_blank"><img src="image/work/TerrainEditor/open.jpg" width="200" height="150" border="0" alt="open"></a></html>|<html><a href="image/work/TerrainEditor/raise.jpg" target="_blank"><img src="image/work/TerrainEditor/raise.jpg" width="200" height="150" border="0" alt="raise"></a></html>|<html><a href="image/work/TerrainEditor/flat.jpg" target="_blank"><img src="image/work/TerrainEditor/flat.jpg" width="200" height="150" border="0" alt="flat"></a></html>|\n|<html><a href="image/work/TerrainEditor/pen.jpg" target="_blank"><img src="image/work/TerrainEditor/pen.jpg" width="200" height="150" border="0" alt="use pen"></a></html>|<html><a href="image/work/TerrainEditor/penSelect.jpg" target="_blank"><img src="image/work/TerrainEditor/penSelect.jpg" width="200" height="150" border="0" alt="pen Select "></a></html>|<html><a href="image/work/TerrainEditor/smooth1.jpg" target="_blank"><img src="image/work/TerrainEditor/smooth1.jpg" width="200" height="150" border="0" alt="rough terrain"></a></html>|\n|<html><a href="image/work/TerrainEditor/smooth2.jpg" target="_blank"><img src="image/work/TerrainEditor/smooth2.jpg" width="200" height="150" border="0" alt="smooth terrain"></a></html>|<html><a href="image/work/TerrainEditor/re1.jpg" target="_blank"><img src="image/work/TerrainEditor/re1.jpg" width="200" height="150" border="0" alt="브러쉬로 여러영역 지정하기"></a></html>|<html><a href="image/work/TerrainEditor/p.jpg" target="_blank"><img src="image/work/TerrainEditor/p.jpg" width="200" height="150" border="0" alt="Painting Palette"></a></html>|\n|<html><a href="image/work/TerrainEditor/p1.jpg" target="_blank"><img src="image/work/TerrainEditor/p1.jpg" width="200" height="150" border="0" alt="Painting1"></a></html>|<html><a href="image/work/TerrainEditor/p2.jpg" target="_blank"><img src="image/work/TerrainEditor/p2.jpg" width="200" height="150" border="0" alt="Painting2"></a></html>|<html><a href="image/work/TerrainEditor/p3.jpg" target="_blank"><img src="image/work/TerrainEditor/p3.jpg" width="200" height="150" border="0" alt="Painting3"></a></html>|\n\n!!!!@@color:green;Model Tool : 가장 손이 많이 간 툴로써 제작기간 또한 길었다. ( 수시로 있었던 엔진 업데이트땀시...ㅠㅠ )@@\n|<html><a href="image/work/ModelTool/model00.jpg" target="_blank"><img src="image/work/ModelTool/model00.jpg" width="200" height="150" border="0" alt="유리재질모델"></a></html>|<html><a href="image/work/ModelTool/model2.jpg" target="_blank"><img src="image/work/ModelTool/model2.jpg" width="200" height="150" border="0" alt="모델의 메쉬선택"></a></html>|<html><a href="image/work/ModelTool/model5.jpg" target="_blank"><img src="image/work/ModelTool/model5.jpg" width="200" height="150" border="0" alt="본"></a></html>|\n|<html><a href="image/work/ModelTool/model6.jpg" target="_blank"><img src="image/work/ModelTool/model6.jpg" width="200" height="150" border="0" alt="Collision model"></a></html>|<html><a href="image/work/ModelTool/model7.jpg" target="_blank"><img src="image/work/ModelTool/model7.jpg" width="200" height="150" border="0" alt="model + bone + Collision model"></a></html>|<html><a href="image/work/ModelTool/model9.jpg" target="_blank"><img src="image/work/ModelTool/model9.jpg" width="200" height="150" border="0" alt="모델의 메쉬 애니메이션"></a></html>|\n|<html><a href="image/work/ModelTool/model10.jpg" target="_blank"><img src="image/work/ModelTool/model10.jpg" width="200" height="150" border="0" alt="모델의 메쉬 스케일"></a></html>|<html><a href="image/work/ModelTool/model_0.jpg" target="_blank"><img src="image/work/ModelTool/model_0.jpg" width="200" height="150" border="0" alt="모델 + 이펙트"></a></html>|<html><a href="image/work/ModelTool/model_1.jpg" target="_blank"><img src="image/work/ModelTool/model_1.jpg" width="200" height="150" border="0" alt="와이어프레임"></a></html>|\n\n!!!!@@color:green;World Tool : 엔진 스펙 교체로 대대적인 수정작업이 있었던 툴. 모델툴 다음으로 손이 많이 간 툴이다. @@\n|<html><a href="image/work/WorldTool/world0.jpg" target="_blank"><img src="image/work/WorldTool/world0.jpg" width="200" height="150" border="0" alt="Scene 로딩"></a></html>|<html><a href="image/work/WorldTool/world1.jpg" target="_blank"><img src="image/work/WorldTool/world1.jpg" width="200" height="150" border="0" alt="오브젝트 선택"></a></html>|<html><a href="image/work/WorldTool/world2.jpg" target="_blank"><img src="image/work/WorldTool/world2.jpg" width="200" height="150" border="0" alt="와이어프레임"></a></html>|\n\n!!!!@@color:green;Effect Tool : 가장 나중에 제작한 툴이다. @@\n|<html><a href="image/work/EffectTool/effect0.jpg" target="_blank"><img src="image/work/EffectTool/effect0.jpg" width="200" height="150" border="0"></a></html>|<html><a href="image/work/EffectTool/effect1.jpg" target="_blank"><img src="image/work/EffectTool/effect1.jpg" width="200" height="150" border="0"></a></html>|<html><a href="image/work/EffectTool/effect3.jpg" target="_blank"><img src="image/work/EffectTool/effect3.jpg" width="200" height="150" border="0"></a></html>|\n\n
Type the text for 'New Tiddler'
*[[2D Programming]]\n*[[3D Programming]]\n*[[프로그래밍 일반]]\n*[[C/C++]]
일반적인 이야기나 관심있는 분야에 대해 메모하는 곳.
명언, 살아가면서 도움될만한 글들을 모으자.
나의 일상
Software 3D 를 공부할 때 참고한 사이트\nhttp://web.archive.org/web/20030810200131/www.fastgraph.com/tutorial/fgtut02.html
Type the text for 'New Tiddler'
[[GameDev.net 한글문서 프로젝트|http://www.gamesync.com.ne.kr/gamedev.net/index.html]]
!Introduction\n*2D primitives \n**Line segments \n**Ellipses and circles \n**Polygons \n**Curves \n*Rasterization (Scan-Conversion) \n**Turn 2D primitives into sets of pixels \n**A Pixel Is Not A Little Square (Digital Signal Processing) \n**Antialiasing \n*Clipping \n**Compute the intersection of a primitive and a shape \n***Primitive: line segment, polygon \n***Shape: rectangle, convex polygon \n\n!A bit of Math \n*Coordinate system: y axis upward or downward? \n*Pixels are at the centers of integer coordinates \n*''Line segments'' \n**Equation of a (2D) line: ax + by + c = 0 \n**Direction: (-b a) \n**Parametric equation of a segment [P1-P2]\n<<<\nx(t) = x1 + t*(x2-x1) = (1-t)*x1 + t*x2\ny(t) = y1 + t*(y2-y1) = (1-t)*y1 + t*y2\nt in [0..1]\n<<<\n \n*''Ellipses and Circles'' \n**Ellipse parallel to the axes, center at origin: \n>x^2 / a^2 + y^2 / b^2 = 1 \n**Parametric Equation:\n>x(t) = a cos(t)\n>y(t) = b sin(t)\n>t in [0..2*pi] \n**Circle: a = b = r \n*''Polygons''\n**Closed sequence of line segments (P1 P2 .. Pn) \n**Different types \n***Convex \n***Concave = not convex \n***Self-intersecting (8-shape) \n***With holes \n*''Norm'': ||V|| = sqr(x^2 + y^2) \n**unit vector if norm is 1 \n*''Dot-product'': V1.V2 = (x1 y1).(x2 y2) = x1 x2 + y1 y2 \n**V1.V2 = cos(a) ||V1|| ||V2|| \n**vectors orthogonal if dot product is 0 \n**if V1 is a unit vector, V1.V2 is the length of the projection of V2 onto V1. \n*''Cross-product'': ||V1 x V2|| = x1 y2 - x2 y1 \n**||V1xV2|| = sin(a) ||V1|| ||V2|| \n*''Distance''\n**d(P1,P2) = ||P1P2|| \n**d(P,L) = N.RP where N is the unit normal vector of line L and R is a point on L. \n\n!Rasterization \n*Converting mathematical definitions to pixels \n**We can only approximate the mathematical definition \n***A Pixel is Not a Little Square \n***Avoid holes \n***Draw each pixel exactly once \n**Naive (expensive) approach \n***Evaluate formulas on the pixel grid \n**Clever approach \n***Use integer calculations \n***Avoid divides and multiplies \n***Use incremental computations \n***Use spatial coherence \n*[[Scan-converting lines|Scan-converting lines]] \n**[[Midpoint line algorithm|Midpoint line algorithm]] \n*Scan-converting ellipses \n**Use midpoint algorithm \n**Scan-converting circles \n***Use symmetry: compute only one octant \n***Use midpoint algorithm \n****E move: dnew = dold + 2x + 3 \n****SE move: dnew = dold + 2x - 2y + 5 \n****initial value: d0 = 5/4 - r \n***Use second-order differences to avoid multiplies \n****E move: d += deltaE, deltaE += 2, deltaSE += 2; \n****SE move: d += deltaSE, deltaE += 2, deltaSE += 4; \n****initial values: deltaE = 3, deltaSE = -2r + 5 \n**Scan-converting ellipses \n***Use symmetry: compute one quadrant \n***Split quadrant in two parts, at point with 45 degrees tangent \n*Filling primitives \n**Filling rectangles \n**Filling ellipses and circles \n**[[Scan-converting polygons|Scan-converting polygons]] \n***[[Fill polygon algorithm|Fill polygon algorithm]]\n**Filling arbitrary shapes \n***Boundaries and Connectivity \n***Flood-filling algorithm \n*Thick primitives \n**Pixel replication \n**The moving pen \n**Filling areas between boundaries \n*Line attributes: dashes \n*Fill attributes: patterns \n*Anti-aliasing: \n**Try to avoid jaggies \n**Pixel intensity proportional to coverage by primitive \n**A Pixel Is Not A Little Square \n***Approximate a pixel by a cone \n**Anti-aliasing lines \n***Precompute table mapping d(P,L) to pixel intensity \n***Compute distance incrementally \n***[[Anti-aliased midpoint line algorithm|Anti-aliased midpoint line algorithm]]\n\n!Clipping \n*Display pixels of a primitive that are inside a clipping region \n**Common case: rectangle parallel to axes \n*Three approaches: \n**Analytical clipping: compute clipped primitive and scan-convert result \n**Stenciling: scan-convert primitive and clip each pixel \n***Simple version for rectangular shape: scissoring \n**Post-raster: scan-convert to off-screen buffer and copy back clipped pixels \n*[[Clipping lines|Clipping lines]] \n**against a rectangle: [[Cohen-Sutherland line-clipping algorithm|Cohen-Sutherland line-clipping algorithm]] \n**against a convex polygon: [[Cyrus-Beck line-clipping algorithm|Cyrus-Beck line-clipping algorithm]] \n*Clipping polygons \n**Clip a convex or concave polygon P against a concave polygon C \n**Sketch: \n***C is the intersection of the half-planes supporting its edges \n***Clip P by each such half-plane H \n****For each edge e=(s,p) of P:\n*****if e is inside H, add p to the output polygon\n*****if e is outside H, do nothing\n*****if e intersects H, add the intersection point to the output polygon \n**Example with clipping polygon C being a rectangle:\n[img[Polygon-clipping.gif|image/study/untitled.bmp]]\n
See [[2D rendering|2D rendering]] for the context of this lecture. \n\nWe consider lines in the first octant. Other cases are symmetrical. \n\n!Naive Algorithm \n*Line segment defined by P0 P1 \n*Equation of line is\n>Y = mX + B\n>m = (y1-y0) / (x1-x0)\n>B = y0 - m*x0 \n*Algorithm: \n**start with the smallest of (x0,x1) \n**compute corresponding value of y \n**SetPixel(x, round(y)) \n**increment x and loop until reaching max(x0,x1) \n*Cost: 1 fmult + 1 fadd + 1 round per loop \n\n!Incremental Algorithm \n*Compute y using it's previous value rather than from scratch \n*y[i+1] = y[i] + m*(x[i+1]-x[i]), but since we increment x by 1:\n>y[i+1] = y[i] + m \n*Cost: 1 fadd + 1 round per loop \n\n!Midpoint line Algorithm \n!!Principle\n*Use spatial coherence: if point P(x,y) is in the scan-conversion, the next point is either P(x+1,y) or P(x+1,y+1): \n**P(x+1,y) is called an E-move \n**P(x+1,y+1) is called a NE-move \n*To decide which point, use the relative position of the midpoint M = (x+1, y+1/2) with respect to the line L\n*The distance d can be computed incrementally with only one or two integer adds per loop! \n\n!!Detail\n*Define an implicit function to represent the line: \n**F(x,y) = 0 if (x,y) is on the line \n**F(x,y) < 0 if (x,y) is on one side of the line \n**F(x,y) > 0 if (x,y) is on the other side of the line \n*For our line:\n>F(x,y) = dy*x - dx*y + C (with dy>0) \n*Decision value: distance between midpoint and line:\n>d = F(x+1, y+1/2) \n*Incremental computation of d: \n**If previous move was E, dnew = F(x+2, y+1/2)\n>dnew = dold + dy \n**If previous move was NE, dnew = F(x+2, y+3/2)\n>dnew = dold + dy - dx \n*Next move: \n**If d < 0, E move: x -> x+1 \n**If d > 0, NE move: x -> x+1, y -> y+1 \n**If d = 0, E or NE are equally bad: pick one \n*Initial value of d: \n**d0 = F(x0+1, y0+1/2) = F(x0,y0) + dy - dx/2 \n**(x0,y0) is on line so we know F(x0,y0)=0 \n**d0 = dy - dx/2 \n*To compute d with integer arithmetic, we use F'(x,y) = 2*F(x,y): \n**d0 = 2*dy - dx \n**if E move: dnew = dold + 2*dy \n**if NE move: dnew = dold + 2*dy - 2*dx \n*Cost: 1 iadd per pixel \n\n!Implementation\nSource for the [[midpoint line algorithm|Midpoint line algorithm]] \n
See the lecture on [[scan-converting lines|Scan-converting lines]] for the explanations of this algorithm. \n\n{{{\n/*\n * draw a line from P0(x0,y0) to P1(x1,y1),\n * where P1 is assumed to be in the first octant\n * relative to P0\n */\nvoid\nMidpointLine (int x0, int y0, int x1, int y1) {\n int dx = x1 - x0;\n int dy = y1 - y0;\n int d = 2*dy - dx;\n int incrE = 2*dy ;\n int incrNE = 2*(dy-dx);\n int x = x0;\n int y = y0;\n\n WritePixel (x0,y0);\n\n while (x < x1) {\n if (d <= 0) {\n d += incrE;\n x++;\n } else {\n d += incrNE;\n x++ ;\n y++ ;\n }\n WritePixel (x,y);\n }\n}\n}}}\n
See [[2D rendering|2D rendering]] for the context of this lecture. \n\n!What is a polygon \n*Closed sequence of line segments: P0 P1 ... Pn P0 \n*''Convex'' polygon: if A and B in P, [A..B] in P. \n**Other formulation: P is the intersection of the half-planes defined by its (oriented) edges. \n**Testing convexity: for each vertex Pi, the dot product (Pi-1 Pi).(Pi Pi+1) has the same sign. \n*''Concave'' polygon: non-convex \n*''Self-intersecting'' polygon: for some i and j, [Pi..Pi+1] and [Pj..Pj+1] intersect \n*Polygon ''with hole'': defined by an external polygon P0..Pn and an interior hole H0..Hp. May have several holes. Can often be considered as a concave polygon P0..Pn Hp..H0 Pn P0. \n*Interior of a polygon: \n**''even-odd rule'': point M inside polygon P if a half-line starting at P crosses the polygon boundary an even number of times. \n**''zero-winding rule'': let W(P,M) the winding number of M relative to P be defined as the number of times P goes around M. M is inside P if W(P,M) is non-zero. W(P,M) can be computed by counting the intersections of a half-line starting at M and the edges of P, with a +1 or -1 coefficient depending on the sign of d.e where d is the normal vector of the half-line and e is the direction of the edge. \n**''non-exterior rule'': for any line that intersects the polygon at points Q0..Qm, any segment [Qi..Qj] is interior to the polygon. (Think of the polygon as a fence). \n[img[interior-rules|image/study/interior-rules.bmp]]\n\n!Scan-conversion \n*Boundary of the polygon defined as the pixels resulting from scan-converting its edges. \n*Interior could be defined as any pixel that is not on the boundary that matches the above definition of interior points \n*Problem when drawing adjacent polygons without boundaries: polygons should join without holes or overlaps \n*No perfect solution. Arbitrary rule: \n**Point of the boundary is interior if the polygon is to the right or to the top of the half-plane defined by the edge containing the boundary point.\n**For a rectangle: bottom and left edge are interior, right and top edges are not. \n**Applies to any polygon (incl. self-intersecting and with holes) \n\n!Scanline algorithm \n!!Principle\n*Compute the intersection of the interior of the polygon with each successive horizontal line. \n*Works for any type of polygon and any interior rule. \n*Exploits spatial coherence \n*Iterative \n\n!!Outline\n*For each scanline: \n**Find the intersection of the scanline with the polygon edges \n**Sort the intersections by increasing values of x \n**For each segment [xi..xi+1], determine if the segment is interior with the interior rule: \n***even-odd rule: set parity to even, invert it at each intersection point. Interior segments are labeled 'odd' \n***non-zero winding rule: set winding number to 0 and update it for each subsequent segment according to the direction of the intersecting edge. We only need to know if the edge intersects the scanline downward or upward, not where. \n*To make the algorithm efficient, compute the intersections incrementally using edge-coherence: the intersections at scanline yi+1 are "close" to the intersections at scanline yi. \n**Scanline yi intersects edge ej at xj \n**Slope of line supporting edge ej is m \n**Scanline yi+1 intersects edge ej at xj+1 = xj + 1/m \n*Keep track of the subset of edges that intersect the current scanline in an Active Edge Table (AET) \n*Keep track of y values at which edges start and stop with a Global Edge Table GET. \n\n!!Detail\n*Create the global edge table GET, indexed by y coordinate: \n**For each non-horizontal edge ej, create an entry in GET[ymin(ej)] and store x(ymin(ej)), ymax(ej) and 1/m(ej) \n**(Ignore horizontal edges) \n**Make sure edges at same y coordinate are sorted by increasing x \n*Set AET to the empty list and yi to the min(y) \n*Repeat until AET and GET are empty \n**Move entering edges from GET to AET (i.e. edges in GET[yi]) \n**Remove from AET edges ej with ymax(ej) = ej \n**Sort AET by increasing x \n**Compute interior segments according to interior rule and draw corresponding spans. \n**Increment yi \n**For each edge in AET, compute next intersection point xj \n*Notes: \n**Horizontal edges are handled implicitely \n**Since we add/remove edges before scan-conversion of a line, the end of the edge with lowest y belongs to the edge, but not the other one. \n**To draw a span (x1,x2) of scanline y, draw pixels (x,y) where ceiling(x1) <= x <= floor(x2). Don't draw the spane if x1 = x2. \n**Polygons with adjacent edges join without overlap nor holes. \n**To handle polygon with holes with the non-zero winding rule, make sure that the edges of the hole are oriented in the opposite direction as the edges of the surrounding polygon. \n**Polygons with sharp edges (slivers) might be scan-converted as disconnected sets of pixels. This is a form of aliasing problem. \n\n!!Implementation\nSource of [[fill polygon algorithm|Fill polygon algorithm]]
See the lecture on [[scan-converting|Scan-converting polygons]] polygons for the explanation of this algorithm. \n\n{{{\n/*\n * a polygon is a sequence of edges\n */\ntypedef struct _edge {\n int xA, yA, xB, yB;\n struct _edge* next;\n} edge;\n\ntypedef edge* polygon;\n\n/* create a polygon */\nextern polygon NewPolygon (int x, int y);\nextern void AddPolygonPoint (polygon p, int x, int y);\nextern void ClosePolygon (polygon p);\n\n/* enumerate edges */\nextern edge* FirstEdge (polygon p);\nextern edge* NextEdge (polygon p, edge* e);\n\n/*\n * the Global Edge Table is an array of lists of edges\n */\ntypedef struct _GET_edge {\n int xmin, ymin, xmax, ymax;\n struct _GET_edge* next;\n} GET_edge;\n\n#define YMAX 1024\ntypedef GET_edge* GET[YMAX];\n\n/* initialize GET to empty entries */\nextern void InitGET (GET get);\n\n/* insert an edge in GET, ignoring horizontal edges */\nextern void InsertGET (GET get, int y, edge* e);\n\n/*\n * the Active Edge Table is a list of intersection points\n */\n\ntypedef struct _AET_point {\n int ymax, x, num, den, incr; /* realx = x + num/den */\n struct _AET_point* next;\n} AET_point;\n\ntypedef AET_point* AET;\n\n/* enumerate AET */\nextern AET_point* FirstPoint (AET aet);\nextern AET_point* NextPoint (AET aet, AET_point* p);\n \n/* update the set of edges intersecting the scanline at coordinate y\n * remove edges that end at current scanline\n * add edges that begin at current scanline with\n * x=xmin, num=0, den= ynax-ymin, incr=xmax-xmin\n */\nextern void UpdateAET (AET* aet, int y, GET get);\n\n/* sort AET by increasing x */\nextern void SortAET (AET* aet);\n\n/* compute the intersection of the next scanline with the edge */\nvoid UpdatePoint (AET_point* p)\n{\n if (p->incr == 0)\n return;\n p->num += p->incr;\n if (p->incr > 0) {\n while (p->num > p->den) {\n p->num -= p->den;\n p->x++;\n }\n } else {\n while (p->num < 0) {\n p->num += p->den;\n p->x--;\n }\n }\n}\n\n/* draw a span of the polygon */\nvoid DrawSpan (int y, AET_point* p1, AET_point* p2)\n{\n int x, x1, x2;\n \n /* don't draw spans with exactly one integer point */\n if (p1->x == p2->x && p1->num == 0 && p2->num == 0)\n return;\n \n /* round left end */\n x1 = p1->x;\n if (p1->num > 0)\n x1++;\n\n /* round right end */\n x2 = p2->x;\n if (p2->num == 0)\n x2--;\n\n /* draw pixels */\n for (x = x1; x <= x2; x++)\n WritePixel (x, y);\n}\n\n/*\n * fill an arbitrary polygon with the even-odd interior rule\n */\nvoid FillPoly (polygon poly)\n{\n int yinf, ymin, y;\n int even;\n GET get;\n AET aet;\n edge* e;\n AET_point* p;\n AET_point* p1;\n AET_point* p2;\n \n /* create Global Edge Table, initialize y and AET */\n InitGET (get);\n yinf = YMAX;\n for (e = FirstEdge (poly); e; e = NextEdge (poly, e)) {\n ymin = min (e->yA, e->yB);\n InsertGET (get, ymin, e);\n if (ymin < yinf)\n yinf = ymin;\n }\n\n if (yinf < 0)\n yinf = 0;\n y = yinf;\n aet = NULL;\n \n /* sweep the scanline */\n do {\n /* insert / delete edges in Active Edge Table */\n UpdateAET (&aet, y, get);\n \n /* sort Active Edge Table by increasing x */\n SortAET (&aet);\n\n /* draw spans with even-odd rule */\n p1 = NULL;\n even = 0;\n for (p2 = FirstPoint (aet); p2; p2 = NextPoint (aet, p2)) {\n if (even)\n DrawSpan (y, p1, p2);\n even = !even;\n p1 = p2;\n }\n \n /* compute intersections for next scanline */\n y++;\n for (p = FirstPoint (aet); p; p = NextPoint (aet, p))\n UpdatePoint (p);\n \n } while (aet != NULL && y < YMAX);\n}\n}}}
See the [[2D rendering|2D rendering]] lecture for the context of this algorithm. \n\n{{{\n#define MAX 255\n#define TABLESIZE 60\n\nstatic int table [MAX];\n\nstatic void\nInitTable (int n, int greys) {\n double cumul [MAX];\n int nsquare = n*n;\n int nover2 = n/2;\n int i, j;\n double s, total;\n\n total = 0.0;\n for (i=0; i<n; i++) {\n s = 0.0;\n for (j=0; j<n; j++) {\n double d = sqrt((n-i)*(n-i)+(n-j)*(n-j));\n if (d > nsquare)\n d = nsquare;\n s += nsquare - d;\n }\n cumul[i] = 2*s;\n total += 4*s;\n }\n\n s = 0.0;\n\n for (i=0; i<n; i++) {\n s += cumul[i];\n table [n + nover2 - i] = greys*s/total;\n }\n\n for (i=0; i<nover2; i++) {\n s = s - cumul[i] + cumul[n-i]; \n table[nover2-i] = greys*s/total;\n }\n\n table[0] = greys;\n}\n\nvoid\nIntensifyPixel (int x, int y, double distance)\n{\n double level;\n double maxd = 1.5;\n\n if (distance > maxd)\n return;\n\n level = (double) table[(int)(distance*TAILLETABLE)] / 255.0; \n \n Grey (level);\n WritePixel (x,y);\n}\n\nvoid\nAntiAliasedLineMidpoint (int x0, int y0, int x1, int y1)\n{\n int dx = x1-x0;\n int dy = y1-y0;\n int d = 2*dy-dx;\n int incrE = 2*dy;\n int incrNE = 2*(dy-dx);\n int two_v_dx = 0;\n double invDenom = 1.0 / (2.0 * sqrt(dx*dx+dy*dy));\n double two_dx_invDenom = 2.0 * dx * invDenom;\n int x = x0;\n int y = y0;\n \n InitTable (TABLESIZE, 255.0);\n \n IntensifyPixel(x, y, 0, version);\n IntensifyPixel(x, y+1, two_dx_invDenom);\n IntensifyPixel(x, y-1, two_dx_invDenom);\n \n while (x < x1) {\n if (d<0) {\n two_v_dx = d+dx;\n d += incrE;\n x++ ;\n } else {\n two_v_dx = d-dx;\n d += incrNE;\n x++;\n y++;\n }\n\n IntensifyPixel(x, y, two_v_dx*invDenom, version);\n IntensifyPixel(x, y+1, two_dx_invDenom - two_v_dx*invDenom);\n IntensifyPixel(x, y-1, two_dx_invDenom + two_v_dx*invDenom);\n }\n}\n}}}
See [[2D rendering|2D rendering]] for the context of this lecture. \n\nThis section is covered in chapter 3 of Foley96. Additional material can be found in chapter 19. \n\n!Clipping lines against a rectangle \n*Common case to clip drawing to the screen or to a rectangular window. \n*Use analytical clipping to reduce number of pixels to draw. \n*Rectangle defined by 4 lines: \n**x = left, x = right \n**y = top, y = bottom \n*Results of clipping a line segment: \n**line completely inside the rectangle \n**line completely outside the rectangle \n**one end outside and one end inside \n**both ends outside but line intersects rectangle \n*Brute-force approach: \n**compute intersections between lines \n**figure out if they belong to the rectangle \n*Better approach: \n**test if the line is trivially accepted or rejected \n**compute only the intersections that are needed \n*Note that the resulting clipped segment does not necessarily have integer coordinates: need a special version of the [[midpoint line algorithm|Midpoint line algorithm]] that uses real coordinates instead of integers. \n\n!!Cohen-Sutherland algorithm\n*Split the plane in 9 areas with the lines defining the rectangle \n*Assign a code to each area: ABCD where \n**A = 1 if y > top, 0 otherwise \n**B = 1 if y < bottom, 0 otherwise \n**C = 1 if x > right, 0 otherwise \n**D = 1 if x < left, 0 otherwise \n*Compute the codes of each end of the line, C0 and C1 \n*Test codes to process line segment: \n**Trivial accept if C0 == 0 && C1 == 0 \n**Trivial reject if C0 & C1 != 0 \n**Clip end outside the rectangle (i.e. with code != 0), using code to pick a side of the rectangle that intersects the line. Replace the clipped end by the intersection point and its code by 0000. Iterate algorithm until trivial accept or reject. \n*Intersection formulas are simple because one line is horizontal or vertical: \n**intersection with y=yclip:\n>x = x0 + (x1-x0)*(yclip-y0)/(y1-y0) \n**intersection with x=xclip:\n>y = y0 + (y1-y0)*(xclip-x0)/(x1-x0) \n*Each intersection requires 1 fmult + 1 fdiv. However m = (y1-y0)/(x1-x0) and m' = 1/m can be computed once since the slope of the line supporting the segment does not change. Each intersection then costs 1 fmult: \n**x = x0 + m'*(yclip-y0) \n**y = y0 + m *(xlicp-x0) \n*The algorithm is not optimal since it can compute unecessary intersection points. \n\n*Source code of [[Cohen-Sutherland line-clipping algorithm|Cohen-Sutherland line-clipping algorithm]]\n\n!Clipping lines against convex polygons \n!!Intersection of two line segments\n*Use parametric equations to represent the line segment and the edges of the clipping polygon:\nP(t) = P0 + (P1 - P0) t = (1-t) P0 + t P1, t in [0..1] \n*The intersection of 2 segments [AB] and [PQ] is M on [AB] such that the dot product N.PM = 0, where N is the normal of PQ. (see picture below) \n**M = A + (B - A) t \n**N.PM = N.{A + (B-A)t - P} = 0 \n**By distributing the dot product: N.PA + N.ABt = 0 \n**Therefore t = - N.PA / N.AB\n**We need to make sure the denominator is non zero: \n***N != 0 (guaranteed), \n***AB != 0 (A != B), \n***N is not orthogonal to AB (if so, there can't be an intersection). \n**There is an intersection if the computed t is in [0..1] \n\n!!Cyrus-Beck algorithm\n*Clipping a segment [AB] by a polygon P0..Pn, oriented in clock-wise order. \n*tmax = 0; tmin = 1 \n*For each edge [Pi Pi+1] in the clipping polygon \n**Compute the dot product pi = Ni.AB where Ni is the normal to the edge \n**If pi is not null, compute ti = - N.PiA / pi \n***If pi positive, tmax = max (tmax, ti) \n***If pi negative, tmin = min (tmin, ti) \n*If tmax < tmin, reject segment, otherwise return the segment [P(tmin) P(tmax)] \n*The sign of pi tells whether the segment [AB] is "entering" or "leaving" the polygon, and therefore which end of the segment to clip \n*The algorithm postpones the computation of the actual intersection points until the very end, which makes it more efficient than Cohen-Sutherland when many lines intersect the rectangle. \n*This algorithm generalizes to 3D for clipping 3D line segments against a convex polyhedron. \n\n*Source code of [[Cyrus-Beck line-clipping algorithm|Cyrus-Beck line-clipping algorithm]]
See the lecture on [[clipping lines|Clipping lines]] for the explanation of this algorithm. \n\n{{{\n/*\n * define the coding of end points\n */\ntypedef unsigned int code;\nenum {TOP = 0x1, BOTTOM = 0x2, RIGHT = 0x4, LEFT = 0x8};\n\n/*\n * a rectangle is defined by 4 sides\n */\ntypedef struct {\n int xmin, ymin, xmax, ymax;\n} rectangle;\n\n/*\n * compute the code of a point relative to a rectangle\n */\ncode\nComputeCode (double x, double y, rectangle r)\n{\n code c = 0;\n if (y > r.ymax)\n c |= TOP;\n else if (y < r.ymin)\n c |= BOTTOM;\n if (x > r.xmax)\n c |= RIGHT;\n else if (x < r.xmin)\n c |= LEFT;\n return c;\n}\n\n/*\n * clip line P0(x0,y0)-P1(x1,y1) against a rectangle\n */\nvoid\nCohenSutherlandClip (double x0, double y0, double x1, double y1, rectangle clip)\n{\n code C0, C1, C;\n double x, y;\n \n C0 = ComputeCode (x0, y0, clip);\n C1 = ComputeCode (x1, y1, clip);\n \n for (;;) {\n /* trivial accept: both ends in rectangle */\n if ((C0 | C1) == 0) {\n MidPointLineReal (x0, y0, x1, y1);\n return;\n }\n \n /* trivial reject: both ends on the external side of the rectangle */\n if ((C0 & C1) != 0)\n return;\n \n /* normal case: clip end outside rectangle */\n C = C0 ? C0 : C1;\n if (C & TOP) {\n x = x0 + (x1 - x0) * (clip.ymax - y0) / (y1 - y0);\n y = clip.ymax;\n } else if (C & BOTTOM) {\n x = x0 + (x1 - x0) * (clip.ymin - y0) / (y1 - y0);\n y = clip.ymin;\n } else if (C & RIGHT) {\n x = clip.xmax;\n y = y0 + (y1 - y0) * (clip.xmax - x0) / (x1 - x0);\n } else {\n x = clip.xmin;\n y = y0 + (y1 - y0) * (clip.xmin - x0) / (x1 - x0);\n }\n \n /* set new end point and iterate */\n if (C == C0) {\n x0 = x; y0 = y;\n C0 = ComputeCode (x0, y0, clip);\n } else {\n x1 = x; y1 = y;\n C1 = ComputeCode (x1, y1, clip);\n }\n }\n \n /* notreached */\n}\n}}}\n
See the lecture on [[clipping lines|Clipping lines]] for the explanation of this algorithm. \n\n\n{{{\n/*\n * a polygon is a list of edges.\n * each edge has a precomputed normal.\n */\ntypedef struct _edge {\n int xA, yA, xB, yB;\n double nx, ny;\n struct _edge* next;\n} edge;\n\ntypedef edge* polygon;\n\nedge* FirstEdge (polygon poly) { return poly; }\nedge* NextEdge (polygon poly, edge* e) { return e ? e->next : NULL; }\n\n/*\n * update the parameter tE or tL depending on the\n * sign of denom/num.\n * Return true if the line can be trivially rejected.\n */\nstatic bool\nClipParam (double denom, double num, double *tE, double *tL)\n{\n double t;\n \n if (denom > 0) {\n t = num / denom;\n if (t > *tL)\n return false;\n *tE = t;\n } else if (denom < 0) {\n t = num / denom;\n if (t < *tE)\n return false;\n *tL = t;\n } else if (num > 0)\n return false;\n return true;\n}\n\nvoid\nCyrusBeckLineClip (double x0, double y0, double x1, double y1, polygon clip)\n{\n double dx = x1 - x0;\n double dy = y1 - y0;\n double tE = 0.0;\n double tL = 1.0;\n edge* e;\n \n /* clip the segment against each edge of the polygon */\n for (e = FirstEdge(clip); e; e = NextEdge (clip, e)) {\n /* denom is -Ni.D; num is Ni.(A-P) */\n denom = - e->nx * dx - e->ny * dy;\n num = e->nx * (e->xA - x0) + e->ny * (e->yA - y0);\n if (! ClipParam (denom, num, &tE, &tL))\n return;\n }\n \n /* compute clipped end points */\n if (tL < 1) {\n x1 = x0 + tL*dx;\n y1 = y0 + tL*dy;\n }\n if (tE > 0) {\n x0 += tE*dx;\n y0 += tE*dy;\n }\n \n /* display clipped segment */\n MidPointLineReal (x0, y0, x1, y1);\n}\n}}}
요즘 완전히 낮과 밤이 바뀌어 버렸다. 새벽에 잠이 안오다가 날을 몇번 샜더니 이렇게 되버렸다. 흠... 계속 이러면 곤란한데...\n/% comments test %/
[img[Yaw|image/study/YAW-blueintel.gif]] Yaw\n@@clear(left):clear(right):display(block):@@\n\n[img[Pitch|image/study/PITCH-blueintel.gif]] Pitch\n@@clear(left):clear(right):display(block):@@\n\n[img[Roll|image/study/ROLL-blueintel.gif]] Roll\n@@clear(left):clear(right):display(block):@@
(See also SliderSiteMap)\n|<<siteMap WhatsNew>><<siteMap FunStuff>>|<<siteMap TagglyTagging>><<siteMap More... 2>>|<<siteMap Plugins 2>>|\n|noBorder threeCol|k\n
Demo of slider formatting in SiteMapMacro\n|!sliders|!openSliders|!popups|\n|{{{<<siteMap TagglyTagging . sliders>>}}}|{{{<<siteMap TagglyTagging . openSliders>>}}}|{{{<<siteMap TagglyTagging . popups>>}}}|\n|<<siteMap TagglyTagging . sliders>>|<<siteMap TagglyTagging . openSliders>>|<<siteMap TagglyTagging . popups>>|
/***\n| Name:|SiteMapMacro|\n| Author:|Simon Baird|\n| Location:|http://simonbaird.com/mptw/#SiteMapMacro|\n| Version:|1.0.3, 15-Mar-06|\n\n!!Examples\nSee SiteMap and SliderSiteMap for example usage.\n\n!!Parameters\n* Name of tiddler to start at\n* Max depth (a number) \n* Format (eg, nested, see formats below)\n* Don't show root flag (anything other than null turns it on)\n* Tags - a string containing a bracketed list of tags that we are interested in\n\n!!History\n* 1.0.3 (15-Mar-06)\n** added tag filtering\n* 1.0.2 (15-Mar-06)\n** Added json format and dontshowroot option\n* 1.0.1 (9-Mar-06)\n** Added selectable formats and fixed nested slider format\n* 1.0.0 (8-Mar-06)\n** first release\n\n***/\n//{{{\n\nversion.extensions.SiteMapMacro = {\n major: 1,\n minor: 0,\n revision: 3,\n date: new Date(2006,3,15),\n source: "http://simonbaird.com/mptw/#SiteMapMacro"\n};\n\nconfig.macros.siteMap = {\n\n formats: {\n bullets: {\n formatString: "%0[[%1]]\sn%2",\n indentString: "*"\n },\n\n // put this in your StyleSheet to make it look good.\n // .sliderPanel { margin-left: 2em; }\n\n sliders: {\n formatString: "[[%1]]+++\sn%2===\sn\sn",\n formatStringLeaf: "[[%1]]\sn"\n },\n\n openSliders: {\n formatString: "[[%1]]++++\sn%2===\sn\sn",\n formatStringLeaf: "[[%1]]\sn"\n },\n\n popups: {\n formatString: "[[%1]]+++^\sn%2===\sn\sn",\n formatStringLeaf: "[[%1]]\sn"\n },\n\n // these don't work too well\n openPopups: {\n formatString: "[[%1]]++++^\sn%2===\sn\sn",\n formatStringLeaf: "[[%1]]\sn"\n },\n \n // this is a little nuts but it works\n json: {\n formatString: '\sn%0{"%1":[%2\sn%0]}',\n formatStringLeaf: '\sn%0"%1"',\n indentString: " ",\n separatorString: ","\n }\n\n\n },\n\n defaultFormat: "bullets",\n\n treeTraverse: function(title,depth,maxdepth,format,dontshowroot,tags,excludetags) {\n\n var tiddler = store.getTiddler(title);\n var tagging = store.getTaggedTiddlers(title);\n\n if (dontshowroot)\n depth = 0;\n\n var indent = "";\n if (this.formats[format].indentString)\n for (var j=0;j<depth;j++)\n indent += this.formats[format].indentString;\n\n var childOutput = "";\n if (!maxdepth || depth < parseInt(maxdepth)) \n for (var i=0;i<tagging.length;i++)\n if (tagging[i].title != title) {\n if (this.formats[format].separatorString && i != 0)\n childOutput += this.formats[format].separatorString;\n childOutput += this.treeTraverse(tagging[i].title,depth+1,maxdepth,format,null,tags,excludetags);\n }\n\n if (childOutput == "" && (\n (tags && tags != "" && !tiddler.tags.containsAll(tags.readBracketedList())) ||\n (excludetags && excludetags != "" && tiddler.tags.containsAny(excludetags.readBracketedList()))\n )\n ) {\n // so prune it cos it doesn't have the right tags and neither do any of it's children\n return "";\n }\n\n if (dontshowroot)\n return childOutput;\n\n if (this.formats[format].formatStringLeaf && childOutput == "") {\n // required for nestedSliders\n return this.formats[format].formatStringLeaf.format([indent,title,childOutput]);\n }\n\n return this.formats[format].formatString.format([indent,title,childOutput]);\n },\n\n handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n wikify(this.treeTraverse(\n params[0] && params[0] != '.' ? params[0] : tiddler.title, 1, \n params[1] && params[1] != '.' ? params[1] : null, // maxdepth\n params[2] && params[2] != '.' ? params[2] : this.defaultFormat, // format\n params[3] && params[3] != '.' ? params[3] : null, // dontshowroot\n params[4] && params[4] != '.' ? params[4] : null, // tags\n params[5] && params[5] != '.' ? params[5] : null // excludetags\n ),place);\n }\n\n}\n\n//}}}\n
|<<siteMap ㄱ>><<siteMap ㄴ>><<siteMap ㄷ>><<siteMap ㄹ>><<siteMap ㅁ>>|<<siteMap ㅂ>><<siteMap ㅅ>><<siteMap ㅇ>><<siteMap ㅈ>><<siteMap ㅊ>>|<<siteMap ㅋ>><<siteMap ㅌ>><<siteMap ㅍ>><<siteMap ㅎ>>|\n|noBorder threeCol|k\n\n\n|<<siteMap A>><<siteMap B>><<siteMap C>><<siteMap D>><<siteMap E>><<siteMap F>><<siteMap G>><<siteMap H>><<siteMap I>>|<<siteMap J>><<siteMap K>><<siteMap L>><<siteMap M>><<siteMap N>><<siteMap 0>><<siteMap P>><<siteMap Q>><<siteMap R>>|<<siteMap S>><<siteMap T>><<siteMap U>><<siteMap V>><<siteMap W>><<siteMap X>><<siteMap Y>><<siteMap Z>>|\n|noBorder threeCol|k\n
/***\n|Name:|CloseOnCancelPlugin|\n|Description:|Closes the tiddler if you click new tiddler then cancel. Default behaviour is to leave it open|\n|Version:|3.0.1 ($Rev: 3861 $)|\n|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|\n|Source:|http://mptw.tiddlyspot.com/#CloseOnCancelPlugin|\n|Author:|Simon Baird <simon.baird@gmail.com>|\n|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|\n***/\n//{{{\nmerge(config.commands.cancelTiddler,{\n\n handler_mptw_orig_closeUnsaved: config.commands.cancelTiddler.handler,\n\n handler: function(event,src,title) {\n this.handler_mptw_orig_closeUnsaved(event,src,title);\n if (!store.tiddlerExists(title) && !store.isShadowTiddler(title))\n story.closeTiddler(title,true);\n return false;\n }\n\n});\n\n//}}}
/***\n|Name:|NewHerePlugin|\n|Description:|Creates the new here and new journal macros|\n|Version:|3.0 ($Rev: 3861 $)|\n|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|\n|Source:|http://mptw.tiddlyspot.com/#NewHerePlugin|\n|Author:|Simon Baird <simon.baird@gmail.com>|\n|License|http://mptw.tiddlyspot.com/#TheBSDLicense|\n***/\n//{{{\nmerge(config.macros, {\n newHere: {\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n wikify("<<newTiddler "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);\n }\n },\n newJournalHere: {\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n wikify("<<newJournal "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);\n }\n }\n});\n\n//}}}
/***\n|Name:|ExtentTagButtonPlugin|\n|Description:|Adds a New tiddler button in the tag drop down|\n|Version:|3.2 ($Rev: 3861 $)|\n|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|\n|Source:|http://mptw.tiddlyspot.com/#ExtendTagButtonPlugin|\n|Author:|Simon Baird <simon.baird@gmail.com>|\n|License|http://mptw.tiddlyspot.com/#TheBSDLicense|\n***/\n//{{{\n\nwindow.onClickTag_mptw_orig = window.onClickTag;\nwindow.onClickTag = function(e) {\n window.onClickTag_mptw_orig.apply(this,arguments);\n var tag = this.getAttribute("tag");\n var title = this.getAttribute("tiddler");\n // Thanks Saq, you're a genius :)\n var popup = Popup.stack[Popup.stack.length-1].popup;\n createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");\n wikify("<<newTiddler label:'New tiddler' tag:'"+tag+"'>>",createTiddlyElement(popup,"li"));\n return false;\n}\n\n//}}}
/***\n|Name:|ToggleTagPlugin|\n|Description:|Makes a checkbox which toggles a tag in a tiddler|\n|Version:|3.1.0 ($Rev: 4907 $)|\n|Date:|$Date: 2008-05-13 03:15:46 +1000 (Tue, 13 May 2008) $|\n|Source:|http://mptw.tiddlyspot.com/#ToggleTagPlugin|\n|Author:|Simon Baird <simon.baird@gmail.com>|\n|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|\n!!Usage\n{{{<<toggleTag }}}//{{{TagName TiddlerName LabelText}}}//{{{>>}}}\n* TagName - the tag to be toggled, default value "checked"\n* TiddlerName - the tiddler to toggle the tag in, default value the current tiddler\n* LabelText - the text (gets wikified) to put next to the check box, default value is '{{{[[TagName]]}}}' or '{{{[[TagName]] [[TiddlerName]]}}}'\n(If a parameter is '.' then the default will be used)\n* TouchMod flag - if non empty then touch the tiddlers mod date. Note, can set config.toggleTagAlwaysTouchModDate to always touch mod date\n!!Examples\n|Code|Description|Example|h\n|{{{<<toggleTag>>}}}|Toggles the default tag (checked) in this tiddler|<<toggleTag>>|\n|{{{<<toggleTag TagName>>}}}|Toggles the TagName tag in this tiddler|<<toggleTag TagName>>|\n|{{{<<toggleTag TagName TiddlerName>>}}}|Toggles the TagName tag in the TiddlerName tiddler|<<toggleTag TagName TiddlerName>>|\n|{{{<<toggleTag TagName TiddlerName 'click me'>>}}}|Same but with custom label|<<toggleTag TagName TiddlerName 'click me'>>|\n|{{{<<toggleTag . . 'click me'>>}}}|dot means use default value|<<toggleTag . . 'click me'>>|\n!!Notes\n* If TiddlerName doesn't exist it will be silently created\n* Set label to '-' to specify no label\n* See also http://mgtd-alpha.tiddlyspot.com/#ToggleTag2\n!!Known issues\n* Doesn't smoothly handle the case where you toggle a tag in a tiddler that is current open for editing\n* Should convert to use named params\n***/\n//{{{\n\nif (config.toggleTagAlwaysTouchModDate == undefined) config.toggleTagAlwaysTouchModDate = false;\n\nmerge(config.macros,{\n\n toggleTag: {\n\n createIfRequired: true,\n shortLabel: "[[%0]]",\n longLabel: "[[%0]] [[%1]]",\n\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n var tiddlerTitle = tiddler ? tiddler.title : '';\n var tag = (params[0] && params[0] != '.') ? params[0] : "checked";\n var title = (params[1] && params[1] != '.') ? params[1] : tiddlerTitle;\n var defaultLabel = (title == tiddlerTitle ? this.shortLabel : this.longLabel);\n var label = (params[2] && params[2] != '.') ? params[2] : defaultLabel;\n var touchMod = (params[3] && params[3] != '.') ? params[3] : "";\n label = (label == '-' ? '' : label); // dash means no label\n var theTiddler = (title == tiddlerTitle ? tiddler : store.getTiddler(title));\n var cb = createTiddlyCheckbox(place, label.format([tag,title]), theTiddler && theTiddler.isTagged(tag), function(e) {\n if (!store.tiddlerExists(title)) {\n if (config.macros.toggleTag.createIfRequired) {\n var content = store.getTiddlerText(title); // just in case it's a shadow\n store.saveTiddler(title,title,content?content:"",config.options.txtUserName,new Date(),null);\n }\n else \n return false;\n }\n if ((touchMod != "" || config.toggleTagAlwaysTouchModDate) && theTiddler)\n theTiddler.modified = new Date();\n store.setTiddlerTag(title,this.checked,tag);\n return true;\n });\n }\n }\n});\n\n//}}}
/***\n|Name:|SaveCloseTiddlerPlugin|\n|Description:|Provides two extra toolbar commands, saveCloseTiddler and cancelCloseTiddler|\n|Version:|3.0 ($Rev: 3861 $)|\n|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|\n|Source:|http://mptw.tiddlyspot.com/#SaveCloseTiddlerPlugin|\n|Author:|Simon Baird <simon.baird@gmail.com>|\n|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|\nTo use these you must add them to the tool bar in your EditTemplate\n***/\n//{{{\nmerge(config.commands,{\n\n saveCloseTiddler: {\n text: 'done/close',\n tooltip: 'Save changes to this tiddler and close it',\n handler: function(e,src,title) {\n config.commands.saveTiddler.handler(e,src,title);\n config.commands.closeTiddler.handler(e,src,title);\n return false;\n }\n },\n\n cancelCloseTiddler: {\n text: 'cancel/close',\n tooltip: 'Undo changes to this tiddler and close it',\n handler: function(e,src,title) {\n config.commands.cancelTiddler.handler(e,src,title);\n config.commands.closeTiddler.handler(e,src,title);\n return false;\n }\n }\n\n});\n\n//}}}
*@@color:red;Software Engineer@@ \n**Web Developer \n**Integration Engineer \n**Generalist Engineer \n**Technical Director \n**Software Engineering Intern \n**Server Online Engineer \n**Rendering Engineer \n**Porting Engineer \n**Pipeline Engineer \n**Physics Engineer \n**Mobile Phone Game Programmer \n**Lead Engineer/Programmer \n**Graphics/Special Effects and Interface Programmer \n**Gameplay Engineer \n**Game Online Engineer \n**Game Database Engineer \n**Front End Engineer \n**Build Engineer \n**Audio Engineer \n**Artificial Intelligence (AI) Engineer \n**Animation Engineer \n**Tools Engineer \n**Configuration Manager \n**OEM Coordinator \n**Online Architect\n**Platform Engineer \n
@@color:red;Wide character type@@\n\n8비트로 표현할 수 없는 문자 세트를 처리할 때 사용한다.\n이 데이터형은 기반데이터형( underlying type )이라고 불리는 다른 정수형 중 하나와 같은 크기와 부호 속성을 가지고 있다.\nwchar_t 스트림을 처리하기 위해 wcin 과 wcout 기능을 제공한다.\n광폭 문자상수나 광폭 문자 문자열은 그 앞에 L 을 붙여서 나타낼수 있다.\n{{{\nwchar_t babo = L'ah'; // 광폭 문자 상수 \nwchar_t jjindda[ 3 ] = L"jjindda"; // 광폭 문자 문자열\n}}}\n2바이트 wchar_t 를 사용하는 시스템에서는 이 코드가 각 문자를 2바이트 단위로 메모리에 저장한다.\n\n
네트웍 게임을 개발할때 부딪히는 물리적 한계가 두가지 있습니다. \n\nBandwidth 와 Latency \n\nBandwidth의 한계로 신호를 많이 보낼 수 없는 것 뿐만아니라, 자주 보낼 수도 없습니다. \n\n기본적으로 리얼타임게임에서는 매 프레임 마다 상태 정보를 갱신해야 합니다. \n만약 30FPS 정도의 갱신률을 가진 게임을 네트웍 플레이로 만든다면 1초에 30번 플레이어의 상태정보를 전송해야합니다.\n전송만 하는게 아니라.. 다른 플레이어들의 정보도 전송 받아야 하지요.\n이렇게 하면 아무리 넉넉한 Bandwidth를 가졌다 해도 플레이어의 숫자가 늘어남에 따라 금방 Bandwidth가 차 버립니다. \n\n네명정도를 최대 플레이어 수로 제한 한다면 모르지만 제한된 Bandwidth 내에서 많은 수의 동시 플레이어를 지원하려면 우선 매프레임 마다 정보를 보내는 걸 포기해야합니다. \n\n그런데 게임은 기본적으로 매프레임 마다 전체 상태를 갱신해야 하는데, 이걸 매프레임 마다 보내지 않는 다면 정보가 전달되지 않는 프레임 동안에는 어떻게 하지요?? \n\n이때 사용되는 기법이 바로 Dead Reckoning 입니다.\nDead라는 말은 신호를 받지 못하고 있는 상태를 말합니다.\n즉 신호가 전달 되지 않으니 신호가 죽은셈이죠. \nReckoning은 추산하다는 뜻으로 신호가 없는 동안에도 추측으로 계산한다는 겁니다. \n\n다시말해서 신호가 없는 동안에도 이전에 받았던 신호를 바탕으로 추산해서 상태정보를 갱신한다는 겁니다. \n\nDead Reckoning은 주로 플레이어의 위치정보를 갱신하는데 사용됩니다. \n물론 데드 레커닝 없이 매 프레임마다 플레이어의 위치값을 주고 받을 수 있으면 좋지만.. 제한된 Bandwidth 때문에 그렇게 할 수가 없지요. \n\n그렇다면 플레이어의 정보를 전달할때 현재의 위치 값 뿐만아니라 위치 값이 전달되지 않는 동안에도 위치 값을 추측하는데 데 필요한 부가적인 정보를 같이 보내야 합니다. \n\n이런 정보는 보통 속도나 가속도 값이 됩니다. \n물론 속도만 보낼 수도 있고, 가속도 까지 보낼 수도 있습니다. \n경우에 따라서는 위치값만 보내더라도 이전 위치 값을 기초로 속도를 구해서 처리 할 수 도 있습니다. \n\n고등학교때 배운 물리공식을 상기하면.. \n\nX = X0 + V * t + 1/2 * A * t * t\n(X :위치, V :속도, A :가속도, t :시간)\n\n최근에 받은 위치값과 속도, 가속도를 이용해서 쉽게 이후 시간의 위치를 추측할 수 있죠. \n\n물론 이 값은 어디까지나 추측일 뿐이고 신호가 없는 동안에 일반적으로 운동상태가 바뀌어졌겠죠. \n이럴 경우 다음 신호가 전달 되어 왔을때 추측한 값이랑 비교해보면 서로 다르겠지요. \n차이가 별로 없다면 추측한 값은 버리고 새로 받은 위치정보로 갱신해버리면 족하지만... 그렇지 않은 경우 새로받은 위치정보로 갱신해버리면 워프하듯이 갑자기 위치가 바뀌어 버리고 어색하게 보일 겁니다.\n우리가 네트웍 게임을 하다보면 흔히 목격하는 광경이죠. \n\n이런 경우 바로 갱신하지 말고 새로받은 위치 정보로 새로운 추측을 해서 현재의 추측값에서 새로운 추측값으로 부드럽게 연결할 수도 있습니다. \n이러면 겉보기 결과는 좀 더 나아지겠지만 공짜로 되는 건 아니지요. \n부가적인 계산이 더 추가되겠지요. \nCPU타임이 남아 돈다면 모르지만 그렇지 않다면 그냥 워프되는걸 감수 해야지요.\n이처럼 신호가 없는 동안에 간단한 물리공식을 이용해서 위치값을 추정 할 수는 있는데.. \n\n그러면 다음 문제는 신호를 얼만큼 덜 보낼 것인가이죠. \n예컨데 30FPS 의 게임의 경우 매 5프레임 마다 보낼 수도 있고 10프레임 마다 보낼 수도 있고, 15프레임 마다 보낼 수도 있고, 혹은 1초에 한번만 보낼 수도 있지요. \n이건 사실 정답이 없지요. \n게임이나 네트웍 등의 상태에 따라 다르겠죠. \n\n일률적으로 몇 프레임 마다 보내는 방법 외에.. 필요할때만 보내는 방법도 생각할 수 있습니다. \n이런 경우는 서버에서도 데드 레커닝을 해야하지만..\n각 클라이언트에서 날아오는 플레이어 위치정보를 그때 그때 다른 클라이언트로 전달하는 대신 서버도 나름대로 클라이언트와 똑 같은 방식으로 데드래커닝을 하고 있다가 받은 정보가 추측한 값이랑 적정한 문턱값 이상으로 차이가 발생했을때만 다른 클라이언트에 보내는 겁니다. \n\n실제적인 적용에 있어서는 여러가지 다양한 방법을 생각해 볼 수 있겠지요. \n\n다음의 문제는 latency가 되는데 여태까지의 논의는 어디까지나 latency 가 없다는 전제하에서 그런 것이고, latency까지 고려한다면 문제는 좀 더 복잡해 집니다. \n\n보통 실용적인 견지에서 동일한 LAN상에서라면 latency를 무시해도 무방하지만 인터넷을 통해서 접속을 하게 되면 이제는 latency를 무시 할 수 없게 됩니다.\n미국처럼 대양을 건너 다른 대륙까지 연결되는 경우가 아닌 국내에서 서로 접속한다고 해도 latency는 심각하게 고려해야 합니다. \n\n물론 바둑이나 장기처럼 Turn 방식으로 진행되는 게임들에는 전혀 상관 없는 얘기 것지만...; \n\n[[[출처]|http://www.g-matrix.pe.kr/]]
네트웍 게임을 개발하면서 많은 경우 간과 되고 있는 부분이 Latency를 어떻게 처리 할 것인가 입니다. \n\n대개 Bandwidth(대역폭)에 대해서는 인지하고 있는데...\nLantency의 경우는 근본적인 원인을 알지못하고, Modem 이라서 느리다는 식으로 이해하는게 보통이죠. \n\nLantency는 우리말로 번역한다면 신호지연 이라고 할 수 있습니다. \n네트웍의 한 노드에서 다른 노드로 신호가 전달되는데 시간지연이 생긴다고 이해하시면됩니다. \n\n구체적인 데이타의 형태가 어떠하던 결국 네트웍을 타고 전달되는 신호는 전자기신호입니다. \n단순히 전기신호일 수도 있고, 광케이블인 경우는 빛 신호가 될것이고, 인공위성이라면 전자기파 신호이겠죠. \n빛도 전자기파의 한종류이므로 결국은 모두 전자기 신호이죠. \n\n그런데 아인슈타인의 특수상대성이론에 의하면 물리적으로 가장 빠른 속도는 빛의 속도입니다.\n정보의 전달도 마찬가지로 빛의 속도가 최대치입니다.\n이보다 더 빨리 전달될 수는 없습니다.\n(적어도 아인슈타인의 상대성이론을 능가하는 이론이 나오기 까지는...) \n\n일반적인 네트웍 어플리케이션에서는 이러한 정보전달 속도의 한계가 전혀 문제 될 게 없습니다.\n주로 대역폭이 문제가 되지요.\n하지만 리얼타임으로 상호작용해야 하는 게임의 경우는 중요한 문제가 됩니다. \n혹자들은 네트웍상에서 정보는 결국 전자기신호로 전달되므로 빛의 속도로 전달될 것이고, 빛의 속도는 엄청빠르기 때문에 문제될게 없다고 생각할 수도 있습니다. \n\n하지만 바로 이 빛의 속도라는 한계가 문제가 됩니다.\n초속 3십만킬로미터 라는 어마어마한 빠르기의 빛의 속도라고 해도 리얼타임 게임을 하기에는 느립니다. \n\n같은 게임방내에서 랜으로 접속된 컴퓨터 들 사이라면 무시해도 되지만 인터넷을 통 해 미국에 있는 컴퓨터와 통신을 한다면 문제가 됩니다. \n\n간단하게 계산을 해보지요.\n흔히들 알고 있기로 빛이 1초에 지구를 7바퀴 반을 돌 정도의 속도라고 알고 있습니다.\n계산을 편하게 하기 위해서 이것보다는 조금 빠른 1초에 열바퀴도는 속도라고 합시다.\n그렇다면 지구를 한바퀴도는데는 약 1/10초가 걸립니다. \n그러니까 100밀리세컨드죠.\n미국이라면 우리나라를 기준으로 대충 지구 반대편에 있으므로 반바퀴 정도라고 보면 됩니다. \n그러면 미국까지 가는데는 대략 50밀리세컨드가 소요됩니다. \n1/20초이죠. \n\n게임 프로그램은 보통 프레임 단위로 모든 걸 처리하므로 FPS가 30인 게임이 있다면 1/30초 안에 모든 작업을 완료해야 합니다.\n그런데 미국까지 신호가 가는데만도 1/20초가 걸리니 게임프로그램이 한 프레임을 갱신하는데 주어진 시간보다 더 느립니다. \n\n흔히들 네트웍 게임을 하면 Ping 이니 lag이니 해서 Ping값이 높은 모뎀은 나가라고 들 하지요. \n\n하지만 제아무리 기가급의 초초고속 인터넷망에 물려있다해도 물리적인 제한을 넘을 수는 없습니다. \n미국까지 ping하면 패킷이 미국까지 갔다 와야하므로 최소한 1/10초는 걸립니다.\n흔히들 대역폭이 커다는 걸 네트웍의 속도가 빠른 걸로 표현하니까 신호가 전달되는데 걸리는 시간이 빠른 것과 혼돈을 하는데, 대역폭은 어디까지나 단위시간당 전달되는 데이타의 양이지 결코 신호가 전달되는 속도를 말하는게 아닙니다. \n\n물론 지금까지 따져본 것은 신호전달의 물리적 한계인 빛의 속도만 고려한 겁니다. \n하지만 인터넷 상에서 실제로 신호가 전달되려면 여러개의 라우터를 거쳐서 지정된 주소의 컴퓨터로 전달됩니다. \n라우터가 신호를 받으면 즉시 전달하는게 아니라.. 버퍼에 대기시켰다가 어디로 가는 신호인지 구분해서 보내게 되므로 라우터가 신호를 처리하는데 걸리는 시간까지 포함시켜야지요.\n세밀하게 따진다면 컴퓨터에 달린 네트웍카드에서 부터 벌써 하드웨어적인 지연이 생기죠.\n프로그램이 데이타전송을 네트웍카드에 요청하면 즉시 신호가 전달되는게 아니라 네트웍 카드내의 버퍼에 잠시라도 대기했다가 라인이 비면 보내집니다. \n\n이런식으로 따지면 신호가 미국까지 가는데 더 많은 시간이 걸립니다. \n\n실제로 미국에있는 서버를 선택해서 Ping을 때려보면 알 수 있습니다. \n절대로 100밀리세컨드 이하로는 나오지 않습니다.\n혹시라도 나오면 노벨물리학상을 탈 수 있을지도..\n신호가 빛보다 빨리 전달되는 걸 발견했으니.. 대단한 과학적 발견입니다. \n\n결론적으로 이러한 네트웍의 latency 는 결코 줄일 수 없는 물리적인 한계입니다. \n그래서 인터넷상에서 이루어지는 게임의 경우 이러한 latency를 어떻게 잘 처리하는 냐가 중요한 문제가 됩니다.\n더군다나 이러한 latency가 물리적인 신호전달속도에만 의해서 발생하는게 아니라 라우터를 거치면서도 발생하기 때문에.. 값이 고정되어 있지도 않습니다. \n\n그러니까 퀘이크나 언리얼 같은 게임은 3차원 엔진으로만 대단한게 아니라.. 대역폭은 제껴놓고라도 lantency를 극복하고 인터넷상에서 네트웍 플레이가 가능하게 한 것만으로도 대단한 겁니다. \n\n< ps >\nlatency 를 극복한다는 건 latency를 없앤다는 뜻이 아니라....\n(이건 결코 없앨수가 없지요. 빛보다 빠를 수는 없으니..) \nlatency가 존재함에도 불구하고 게임 플레이가 가능하게 한다는 뜻이죠... \n물론 ping값이 300ms 를 넘어가기 시작하면 백약이 무효이긴 하지만....\n실용적인 견지에서 300ms 이하에서는 latency를 잘 감추어서 플레이하는 플레이어들은 눈치 못채게 해야지요..\n이게 결코 쉬운게 아니라는 거지요.. \n사실 150ms가 넘어가면 플레이어가 눈치 못채게 하기는 정말 힘듭니다. \n\n[[[출처]|http://www.g-matrix.pe.kr/]]
http://knowfree.net/
!@@color:red;Mutex, Mutual Exclusion object@@\n\n스레드들 간에서 공유가 배제되는 객체. 파일과 같은 공유 자원이 수행 중 오직 한 프로그램이나 스레드에게만 소유되어야 할 필요가 있을 때 그 자원에 대한 뮤텍스 객체를 생성시킨다. 뮤텍스가 비신호 상태이면 프로그램은 자원을 점유하여 사용한 후 이를 반환하고, 다른 프로그램 또는 다른 스레드가 자원을 사용 중 즉, 뮤텍스가 신호 상태이면 대기 상태로 들어가 끝나기를 기다린다. 뮤텍스는 여러 면에서 크리티컬 섹션과 비슷하고, 대신 사용할 수도 있지만 이름을 가질 수 있다는 점에서 크리티컬 섹션보다 우월하다. \n
@@color:red;세마포어(Semaphore)@@는 에츠허르 데이크스트라가 고안한, 두 개의 원자적 함수로 조작되는 정수 변수로서, 멀티프로그래밍 환경에서 공유 자원에 대한 접근을 제한하는 방법으로 사용된다. 이는 철학자들의 만찬 문제의 고전적인 해법이지만 모든 교착 상태를 해결하지는 못 한다.\n\n*구성\n세마포어 S는 정수값을 가지는 변수이며, 다음과 같이 P와 V라는 명령에 의해서만 접근할 수 있다. (P와 V는 각각 test와 increment를 뜻하는 네덜란드어 Proberen과 Verhogen의 머릿글자를 딴 것이다.)\n\nP는 임계 구역에 들어가기 전에 수행되고, V는 임계 구역에서 나올 때 수행된다. 이 때 변수 값을 수정하는 연산은 모두 원자성을 만족해야 한다. 다시 말해, 한 프로세스(또는 스레드)에서 세마포어 값을 변경하는 동안 다른 프로세스가 동시에 이 값을 변경해서는 안된다.\n\n*적용\n@@color:blue;방법 1@@\n최초 제시된 방법은 바쁜 대기(busy waiting)을 이용한 방법이다.\n{{{\n P(S) {\n while S <=0\n ; // 아무 것도 하지 않음 (반복문)\n S--;\n }\n \n V(S) {\n S++;\n }\n}}}\n이 방법은 임계 구역에 들어갈 수 있을 때까지 빈 반복문을 수행하기 때문에, 단일처리기 다중프로세스 환경에서 처리기 효율이 떨어진다. 또한 대기 중인 프로세스들 중 어느 것을 먼저 임계 구역에 진입시킬지를 결정할 수 없다.\n\n@@color:blue;방법 2@@\n최초 방법의 단점을 보완한 방법으로서 재움 큐를 활용하여 프로세스를 재우는 방식이다.\n{{{\n P(S) {\n S--;\n if S < 0\n // 이 프로세스를 재움 큐에 추가 (잠 듬)\n }\n \n V(S) {\n S++;\n if S <= 0\n // 재움 큐로부터 프로세스를 제거 (깨어남)\n }\n}}}\n\n*종류\n**계수 세마포어 - 계수 세마포어(counting semaphore)에서는 초기값은 가능한 자원의 수로 정해지며, 세마포어 값의 범위는 정해져 있지 않다.\n**이진 세마포어 - 이진 세마포어(binary semaphore)에서는 세마포어 값으로 0 또는 1을 가진다. 계수 세마포어보다 간단히 구현할 수 있으며, Test and Set 등 하드웨어가 지원하는 기능을 이용하여 구현하기도 한다. 또한, 이진 세마포어를 이용하여 계수 세마포어를 구현할 수도 있다.\n\n*약점\nP함수와 V함수의 동작은 독립적이기 때문에 잘못 사용하는 경우, 문제가 발생한다. \nP - 임계 구역 - P : 현재 프로세스가 임계 구역에서 빠져나갈 수 없게 된다. 또한 다른 프로세스들은 임계 구역에 들어갈 수 없으므로 교착 상태가 발생한다. \nV - 임계 구역 - P : 2개 이상의 프로세스가 동시에 임계구역에 들어갈 수 있으므로 상호 배제를 보장할 수 없게 된다. \n고급 언어에서 동기화를 제공해야 한다. \n\n*참고\n세마포어(semaphore)의 원래 뜻은 기차 등에서 사용하는 '까치발 신호기'이다.\n\n
소프트웨어 개발도구들
[[SWIG|http://www.swig.org]] - Simplified Wrapper and Interface Generator\n\nSWIG 는 C, C++, Objective-C로 작성된 코드와 Perl, Python, Tcl/Tk 뿐만 아니라 Java, Eiffel, Guile등의 다양한 고급 언어로 작성된 코드 사이를 연결해 주는 소프트웨어 개발 도구다.
http://www.martinfowler.com\n\n*저서\n**''Analysis Patterns'' \n**''UML Distilled''\n**''Refactoring: Improving the Design of Existing Code''\n\n*Article\n**''지속적통합'' - http://martinfowler.com/articles/continuousIntegration.html
각종 게임엔진
http://www.mysticgd.com/
*[[폭포수모델|폭포수모델]]\n*[[프로토타이핑|프로토타이핑]]\n*[[RAD|RAD]]\n*[[RUP|RUP]]\n*[[익스트림프로그래밍|익스트림프로그래밍]]\n*[[애자일|애자일]]
''Waterfall Model''\n\n폭포수 모델은 설계에서 구현까지 이전 단계로 되돌아가지 않고개발을 진행해 나가는 것을 기본으로 하는 방법이다.
프로토타이핑 방법론은 사용자에게 시스템의 프로토타입을 제시하면서 개발을 진행하는 방법이다.
''RAD(Rapid Application Development)'' 는 빠른 시일 내에 애플리케이션(주로 프로그램)을 개발하는 방법론 전체를 지칭한다.\n\n
''RUP(Rational Unified Process)''는 미국 IBM 의 Rational 부서가 만든 반복형 개발 방법론으로, 설계에서 테스트까지 수 회 반복하며 개발을 진행한다.
익스트림프로그래밍^^XP^^(Extreme Programming)\n\n최근 개발 방법론 중에서 급부상하고 있는 애자일 소프트웨어 개발 방법론([[Agile Software Development|애자일]])의 하나로, 단순성, 상호소통, 피드백, 용기 등의 원칙에 기반해서 '고객에게 최고의 가치를 가장 빨리' 전달하도록 하는 경량 방법론이다. 요구사항 등의 변화가 자주, 많이 있거나 개발자가 소규모이고 같은 공간을 사용하는 경우가 높은 효과가 있다고 알려졌고, 규모가 큰 프로젝트나 원거리 XP 등 적용을 확대하려는 노력이 꾸준히 시도되고 있다.
''애자일 방법론(Agile Methodology)''은 2001년 2월경에 XP, FDD, Crystal, SCRUM, DSDM, ASD 등 방법론 대표자들이 모여서 애자일 얼라이언스라는 일종의 동맹을 만들고 공식적인 이름을 발표한 '애자일(agile)한' 방법론의 집합이다.
엔터프라이즈 자바빈즈(Enterprise JavaBeans; EJB)는 기업환경의 시스템을 구현하기 위한 서버측 컴포넌트 모델이다. 즉, EJB는 애플리케이션의 업무 로직을 가지고 있는 서버 애플리케이션이다. EJB 사양은 Java EE의 자바 API 중 하나로, 주로 웹 시스템에서 JSP는 화면 로직을 처리하고, EJB는 업무 로직을 처리하는 역할을 한다.\n\n!EJB의 종류\n* 세션 빈 (Session Bean) \n* 엔티티 빈 (Entity Bean) \n* 메시지 구동 빈 (Message-driven Bean) \n\n[[SUN사의 EJB 홈페이지|http://java.sun.com/products/ejb/]] \n
http://xprogramming.com/software.htm
* ''flat file ; 플랫파일''\n\n플랫파일은 아무런 구조적 상호관계가 없는 레코드들이 들어 있는 파일이다. 이 용어는 모든 문서 처리나, 다른 구조 문자들 또는 마크업 들이 제거된 상태의 텍스트 문서를 가리키기 위해 자주 사용된다. 그러나 실제 용례에서는, 플랫파일에 "줄 바꿈" 표시가 포함될 수 있는지 여부에 대한 모호함이 있다. 어쨌든, 많은 사용자들은 마이크로소프트 워드에서 문서를 "텍스트만"으로 저장한 것을 "플랫파일"이라고 부른다. 그 결과로 나온 파일은 레코드들을 포함하긴 하지만, 한 줄의 크기가 얼마인지, 제목 또는 그 문서를 포맷하기 위해 프로그램이 사용할 수 있는 목차 등에 관한 다른 정보는 없다. \n\n플랫파일의 또다른 형식은, 각 테이블 셀들이 콤마로 구분되어 있고 각 줄은 줄 바꿈으로 구분되어 ASCII 텍스트로 표시된 표 데이터가 그 중 하나이다. 이러한 형태의 플랫파일을 CSV 파일이라고 부른다. \n\nSQL과 관계형 데이터베이스 소개 책자인 SQL for Dummies에서, 앨런 G. 테일러는 "플랫파일의 장점은 구조화된 파일에 비해 저장공간을 적게 차지하는 데 있다"고 지적했다. 그러나, 플랫파일은 그 파일 내에 데이터들이 어떻게 조직되어 있는지를 알고 있는 프로그램을 필요로 한다. 파일시스템에서 여러 개의 파일들을 이용하는 것 대신 SQL과 데이터베이스를 사용하면, 사용자와 응용프로그램은 데이터의 위치나 배열을 이해하지 않아도 된다. \n\n관계형 데이터베이스에서 플랫파일은 때로 "관계(relation)"와 동의어로 사용되기도 한다. \n \n[출처][[텀즈|http://www.terms.co.kr/flatfile.htm]]
[[텀즈|http://www.terms.co.kr/]]
''Fit : Framework for Integrated Test'' - http://fit.c2.com/
\nhttp://www.fraps.com/download.php
!@@comma separated value@@\n\nCSV Parsing Class\nhttp://www.mayukhbose.com/freebies/c-code.php\n\n\nCSpreadSheet - A Class to Read and Write to Excel and Text Delimited Spreadsheet\nhttp://www.codeproject.com/database/cspreadsheet.asp\n\n
http://udk.com/